aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md6
-rw-r--r--bootstrap/bin/start.script2
-rw-r--r--bootstrap/bin/start_clean.script2
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bsm.beambin12196 -> 12172 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin11456 -> 11264 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app2
-rw-r--r--bootstrap/lib/compiler/egen/core_parse.erl6
-rw-r--r--bootstrap/lib/kernel/ebin/application.beambin2684 -> 2708 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin32824 -> 32824 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin29312 -> 29312 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_group.beambin16160 -> 16160 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin11428 -> 11460 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin18124 -> 18124 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14212 -> 13856 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app2
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin21032 -> 21036 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin4872 -> 4872 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/pg2.beambin6984 -> 6984 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/rpc.beambin8204 -> 8204 bytes
-rw-r--r--bootstrap/lib/kernel/include/inet.hrl15
-rw-r--r--bootstrap/lib/kernel/include/inet_sctp.hrl2
-rw-r--r--bootstrap/lib/orber/include/Makefile2
-rw-r--r--bootstrap/lib/orber/include/corba.hrl2
-rw-r--r--bootstrap/lib/orber/include/orber_pi.hrl2
-rw-r--r--bootstrap/lib/stdlib/ebin/array.beambin10720 -> 10720 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin16504 -> 16504 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin12752 -> 12752 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin48400 -> 48400 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dict.beambin8392 -> 8392 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin7664 -> 7664 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6252 -> 6252 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin22132 -> 22132 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin21588 -> 21544 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin19888 -> 19888 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin77224 -> 77224 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin66332 -> 66332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin21384 -> 21384 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin30368 -> 30424 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin18268 -> 18268 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin28196 -> 28196 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen.beambin3412 -> 3592 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin12056 -> 12064 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin9056 -> 8880 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin11948 -> 11776 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin8100 -> 8148 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin27432 -> 27432 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/log_mf_h.beambin2444 -> 2444 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin18684 -> 18684 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/orddict.beambin2620 -> 2620 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin7952 -> 8928 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pool.beambin3520 -> 3616 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin8472 -> 8472 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin64200 -> 64240 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin65960 -> 65960 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/re.beambin11268 -> 11268 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sets.beambin6456 -> 6456 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin28160 -> 28172 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/slave.beambin4088 -> 4100 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin37952 -> 37972 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app2
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin15580 -> 16400 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin6804 -> 6828 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin4840 -> 4924 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin10808 -> 10808 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin24552 -> 24552 bytes
-rw-r--r--bootstrap/lib/stdlib/egen/erl_parse.erl219
-rw-r--r--bootstrap/lib/stdlib/include/erl_bits.hrl2
-rw-r--r--bootstrap/lib/stdlib/include/erl_compile.hrl2
-rw-r--r--bootstrap/lib/stdlib/include/ms_transform.hrl2
-rw-r--r--bootstrap/lib/stdlib/include/qlc.hrl2
-rw-r--r--bootstrap/lib/stdlib/include/zip.hrl4
-rw-r--r--erts/aclocal.m42
-rw-r--r--erts/doc/specs/.gitignore1
-rw-r--r--erts/doc/src/Makefile38
-rw-r--r--erts/doc/src/driver.xml2
-rw-r--r--erts/doc/src/epmd.xml6
-rw-r--r--erts/doc/src/erl.xml2
-rw-r--r--erts/doc/src/erl_driver.xml2
-rw-r--r--erts/doc/src/erl_prim_loader.xml88
-rw-r--r--erts/doc/src/erlang.xml544
-rw-r--r--erts/doc/src/erts_alloc.xml66
-rw-r--r--erts/doc/src/init.xml69
-rw-r--r--erts/doc/src/notes.xml351
-rw-r--r--erts/doc/src/run_erl.xml2
-rw-r--r--erts/doc/src/specs.xml7
-rw-r--r--erts/doc/src/zlib.xml311
-rw-r--r--erts/emulator/Makefile.in4
-rw-r--r--erts/emulator/beam/atom.names2
-rw-r--r--erts/emulator/beam/beam_bif_load.c30
-rw-r--r--erts/emulator/beam/beam_emu.c2
-rw-r--r--erts/emulator/beam/beam_load.c181
-rw-r--r--erts/emulator/beam/bif.tab6
-rw-r--r--erts/emulator/beam/erl_afit_alloc.c15
-rw-r--r--erts/emulator/beam/erl_alloc.c184
-rw-r--r--erts/emulator/beam/erl_alloc.h8
-rw-r--r--erts/emulator/beam/erl_alloc.types15
-rw-r--r--erts/emulator/beam/erl_alloc_util.c698
-rw-r--r--erts/emulator/beam/erl_alloc_util.h43
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.c972
-rw-r--r--erts/emulator/beam/erl_ao_firstfit_alloc.h60
-rw-r--r--erts/emulator/beam/erl_async.c2
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.c168
-rw-r--r--erts/emulator/beam/erl_bestfit_alloc.h3
-rw-r--r--erts/emulator/beam/erl_bits.c2
-rw-r--r--erts/emulator/beam/erl_bits.h2
-rw-r--r--erts/emulator/beam/erl_db.c47
-rw-r--r--erts/emulator/beam/erl_db_util.c4
-rw-r--r--erts/emulator/beam/erl_driver.h2
-rw-r--r--erts/emulator/beam/erl_gc.c40
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.c22
-rw-r--r--erts/emulator/beam/erl_instrument.c6
-rw-r--r--erts/emulator/beam/erl_lock_check.c1
-rw-r--r--erts/emulator/beam/erl_nif.c10
-rw-r--r--erts/emulator/beam/erl_port_task.c2
-rw-r--r--erts/emulator/beam/erl_printf_term.h2
-rw-r--r--erts/emulator/beam/erl_unicode.c2
-rw-r--r--erts/emulator/beam/ops.tab4
-rw-r--r--erts/emulator/beam/safe_hash.c2
-rw-r--r--erts/emulator/drivers/common/inet_drv.c4
-rw-r--r--erts/emulator/hipe/hipe_bif64.c2
-rw-r--r--erts/emulator/hipe/hipe_bif64.h2
-rw-r--r--erts/emulator/hipe/hipe_bif64.tab2
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c7
-rw-r--r--erts/emulator/sys/common/erl_check_io.c2
-rw-r--r--erts/emulator/sys/common/erl_mseg.h2
-rw-r--r--erts/emulator/test/alloc_SUITE_data/allocator_test.h20
-rw-r--r--erts/emulator/test/alloc_SUITE_data/coalesce.c2
-rw-r--r--erts/emulator/test/alloc_SUITE_data/rbtree.c86
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl17
-rw-r--r--erts/emulator/test/code_SUITE.erl32
-rw-r--r--erts/emulator/test/driver_SUITE_data/otp_9302_drv.c175
-rw-r--r--erts/emulator/test/fun_SUITE.erl10
-rw-r--r--erts/emulator/test/hibernate_SUITE.erl31
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl61
-rw-r--r--erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c46
-rw-r--r--erts/emulator/test/nif_SUITE.erl45
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c86
-rw-r--r--erts/emulator/test/send_term_SUITE.erl4
-rwxr-xr-xerts/emulator/utils/beam_makeops71
-rw-r--r--erts/epmd/src/epmd.c2
-rw-r--r--erts/epmd/src/epmd_int.h9
-rw-r--r--erts/epmd/src/epmd_srv.c20
-rw-r--r--erts/etc/common/erlexec.c5
-rw-r--r--erts/etc/common/inet_gethost.c2
-rw-r--r--erts/etc/unix/to_erl.c2
-rw-r--r--erts/etc/win32/Install.c5
-rw-r--r--erts/etc/win32/erlsrv/erlsrv_service.c2
-rw-r--r--erts/example/matrix_nif.c85
-rw-r--r--erts/example/next_perm.cc2
-rw-r--r--erts/include/internal/erl_printf_format.h2
-rw-r--r--erts/include/internal/libatomic_ops/ethr_atomic.h2
-rw-r--r--erts/include/internal/sparc32/atomic.h2
-rw-r--r--erts/include/internal/tile/atomic.h2
-rw-r--r--erts/lib_src/common/erl_misc_utils.c4
-rw-r--r--erts/lib_src/common/erl_printf_format.c4
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50384 -> 50528 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin24144 -> 27148 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44876 -> 45296 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1432 -> 1436 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin31528 -> 31640 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin64888 -> 64892 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22432 -> 22444 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10616 -> 12148 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl49
-rw-r--r--erts/preloaded/src/erlang.erl142
-rw-r--r--erts/preloaded/src/init.erl31
-rw-r--r--erts/preloaded/src/prim_file.erl6
-rw-r--r--erts/preloaded/src/zlib.erl144
-rw-r--r--erts/vsn.mk4
-rw-r--r--lib/asn1/c_src/asn1_erl_driver.c47
-rw-r--r--lib/asn1/doc/src/notes.xml24
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl9
-rw-r--r--lib/asn1/src/asn1ct_value.erl4
-rw-r--r--lib/asn1/src/asn1rt_check.erl4
-rw-r--r--lib/asn1/test/asn1_SUITE.erl2489
-rw-r--r--lib/asn1/test/asn1_SUITE.erl.src61
-rw-r--r--lib/asn1/test/asn1_bin_SUITE.erl2382
-rw-r--r--lib/asn1/test/asn1_bin_v2_SUITE.erl2474
-rw-r--r--lib/asn1/test/asn1_common_SUITE.erl.src5
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl4
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--lib/common_test/doc/src/notes.xml69
-rw-r--r--lib/common_test/src/ct_logs.erl2
-rw-r--r--lib/common_test/src/vts.erl2
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/cfg_error_9_SUITE.erl2
-rw-r--r--lib/common_test/test/ct_error_SUITE_data/error/test/timetrap_2_SUITE.erl2
-rw-r--r--lib/common_test/test/ct_groups_test_2_SUITE_data/groups_2/groups_22_SUITE.erl2
-rw-r--r--lib/common_test/test/ct_test_support.erl2
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/notes.xml24
-rw-r--r--lib/compiler/src/beam_bsm.erl2
-rw-r--r--lib/compiler/src/beam_dead.erl2
-rw-r--r--lib/compiler/src/sys_core_fold.erl2
-rw-r--r--lib/compiler/src/v3_core.erl2
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml3
-rw-r--r--lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml3
-rw-r--r--lib/cosEvent/doc/src/notes.xml21
-rw-r--r--lib/cosEvent/vsn.mk2
-rw-r--r--lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml5
-rw-r--r--lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml3
-rw-r--r--lib/cosEventDomain/doc/src/notes.xml17
-rw-r--r--lib/cosEventDomain/vsn.mk2
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml3
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml5
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml5
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml5
-rw-r--r--lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml3
-rw-r--r--lib/cosFileTransfer/doc/src/notes.xml19
-rw-r--r--lib/cosFileTransfer/vsn.mk2
-rw-r--r--lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml7
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml5
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml5
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml7
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml9
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml7
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml11
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml11
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml11
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml11
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml11
-rw-r--r--lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml7
-rw-r--r--lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml9
-rw-r--r--lib/cosNotification/doc/src/ch_BNF.xml10
-rw-r--r--lib/cosNotification/doc/src/notes.xml15
-rw-r--r--lib/cosNotification/vsn.mk2
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml5
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml9
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml9
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml5
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml7
-rw-r--r--lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml9
-rw-r--r--lib/cosProperty/doc/src/notes.xml19
-rw-r--r--lib/cosProperty/vsn.mk2
-rw-r--r--lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml7
-rw-r--r--lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml3
-rw-r--r--lib/cosTime/doc/src/notes.xml17
-rw-r--r--lib/cosTime/vsn.mk2
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml11
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml5
-rw-r--r--lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml9
-rw-r--r--lib/cosTransactions/doc/src/notes.xml18
-rw-r--r--lib/cosTransactions/vsn.mk2
-rw-r--r--lib/crypto/c_src/Makefile.in2
-rw-r--r--lib/crypto/c_src/crypto.c132
-rw-r--r--lib/crypto/doc/src/crypto.xml100
-rw-r--r--lib/crypto/doc/src/licenses.xml2
-rw-r--r--lib/crypto/doc/src/notes.xml39
-rw-r--r--lib/crypto/src/crypto.erl35
-rw-r--r--lib/crypto/test/crypto_SUITE.erl178
-rw-r--r--lib/crypto/vsn.mk2
-rwxr-xr-xlib/dialyzer/doc/src/notes.xml39
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl13
-rw-r--r--lib/dialyzer/src/dialyzer_succ_typings.erl33
-rw-r--r--lib/dialyzer/src/dialyzer_typesig.erl9
-rw-r--r--lib/dialyzer/test/Makefile2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/asn12
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/inets23
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/results/mnesia5
-rw-r--r--lib/dialyzer/test/race_SUITE_data/results/extract_translations4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/flatten2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/binary_lc_bug.erl8
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/codec_can.erl35
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/list_to_bitstring.erl21
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl42
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/nowarnunused.erl7
-rw-r--r--lib/dialyzer/vsn.mk2
-rw-r--r--lib/diameter/aclocal.m42
-rwxr-xr-xlib/diameter/autoconf/configure.vxworks2
-rw-r--r--lib/diameter/autoconf/vxworks/sed.general2
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_cpu322
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_ppc322
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_ppc6032
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_ppc603_nolongcall2
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_ppc8602
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_simlinux2
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_simso2
-rw-r--r--lib/diameter/autoconf/vxworks/sed.vxworks_sparc2
-rwxr-xr-xlib/diameter/bin/diameterc2
-rw-r--r--lib/diameter/configure.in2
-rw-r--r--lib/diameter/doc/src/.gitignore2
-rw-r--r--lib/diameter/doc/src/Makefile31
-rw-r--r--lib/diameter/doc/src/depend.sed34
-rw-r--r--lib/diameter/doc/src/diameter.xml121
-rw-r--r--lib/diameter/doc/src/diameter_app.xml184
-rw-r--r--lib/diameter/doc/src/diameter_dict.xml78
-rw-r--r--lib/diameter/doc/src/diameter_examples.xml5
-rw-r--r--lib/diameter/doc/src/diameter_intro.xml58
-rw-r--r--lib/diameter/doc/src/diameter_transport.xml2
-rw-r--r--lib/diameter/doc/src/diameter_using.xml3
-rw-r--r--lib/diameter/doc/src/files.mk2
-rw-r--r--lib/diameter/doc/src/notes.xml59
-rw-r--r--lib/diameter/examples/server_cb.erl9
-rw-r--r--lib/diameter/include/diameter.hrl2
-rw-r--r--lib/diameter/make/release_targets.mk2
-rw-r--r--lib/diameter/make/rules.mk.in2
-rw-r--r--lib/diameter/make/subdir.mk2
-rw-r--r--lib/diameter/src/app/.gitignore1
-rw-r--r--lib/diameter/src/app/Makefile2
-rw-r--r--lib/diameter/src/app/diameter.erl24
-rw-r--r--lib/diameter/src/app/diameter_service.erl16
-rw-r--r--lib/diameter/src/compiler/Makefile2
-rw-r--r--lib/diameter/src/compiler/diameter_codegen.erl78
-rw-r--r--lib/diameter/src/compiler/diameter_forms.hrl2
-rw-r--r--lib/diameter/src/compiler/diameter_spec_util.erl50
-rw-r--r--lib/diameter/src/subdirs.mk2
-rw-r--r--lib/diameter/src/transport/Makefile2
-rw-r--r--lib/diameter/subdirs.mk2
-rw-r--r--lib/diameter/test/Makefile4
-rw-r--r--lib/diameter/test/diameter_reg_test.erl2
-rw-r--r--lib/diameter/test/diameter_tcp_test.erl2
-rw-r--r--lib/diameter/test/diameter_test_lib.erl2
-rw-r--r--lib/diameter/test/diameter_test_lib.hrl2
-rw-r--r--lib/diameter/test/modules.mk2
-rw-r--r--lib/diameter/test/slask/diameter_persistent_table_test.erl2
-rw-r--r--lib/docbuilder/doc/src/notes.xml22
-rw-r--r--lib/docbuilder/vsn.mk2
-rw-r--r--lib/edoc/Makefile2
-rw-r--r--lib/edoc/doc/Makefile2
-rw-r--r--lib/edoc/doc/overview.edoc7
-rw-r--r--lib/edoc/doc/src/Makefile2
-rw-r--r--lib/edoc/doc/src/notes.xml34
-rw-r--r--lib/edoc/include/Makefile2
-rw-r--r--lib/edoc/priv/edoc_generate.src3
-rw-r--r--lib/edoc/src/Makefile2
-rw-r--r--lib/edoc/src/edoc.erl19
-rw-r--r--lib/edoc/src/edoc_data.erl2
-rw-r--r--lib/edoc/src/edoc_doclet.erl4
-rw-r--r--lib/edoc/src/edoc_extract.erl10
-rw-r--r--lib/edoc/src/edoc_layout.erl20
-rw-r--r--lib/edoc/src/edoc_lib.erl6
-rw-r--r--lib/edoc/src/edoc_parser.yrl7
-rw-r--r--lib/edoc/src/edoc_report.erl2
-rw-r--r--lib/edoc/src/edoc_run.erl2
-rw-r--r--lib/edoc/src/edoc_scanner.erl2
-rw-r--r--lib/edoc/src/edoc_specs.erl7
-rw-r--r--lib/edoc/src/edoc_tags.erl2
-rw-r--r--lib/edoc/src/edoc_types.erl7
-rw-r--r--lib/edoc/src/edoc_wiki.erl13
-rw-r--r--lib/edoc/src/otpsgml_layout.erl4
-rw-r--r--lib/edoc/test/edoc_SUITE.erl2
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/erl_docgen/doc/src/notes.xml17
-rwxr-xr-xlib/erl_docgen/priv/bin/xref_mod_app.escript7
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl2
-rw-r--r--lib/erl_docgen/priv/xsl/db_man.xsl2
-rw-r--r--lib/erl_docgen/priv/xsl/db_pdf.xsl2
-rw-r--r--lib/erl_docgen/vsn.mk2
-rw-r--r--lib/erl_interface/doc/src/notes.xml36
-rw-r--r--lib/erl_interface/src/connect/ei_resolve.c7
-rw-r--r--lib/erl_interface/src/epmd/epmd_port.c2
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/et/doc/src/notes.xml16
-rw-r--r--lib/et/src/et_wx_viewer.erl4
-rw-r--r--lib/et/vsn.mk2
-rw-r--r--lib/eunit/doc/src/notes.xml40
-rw-r--r--lib/eunit/src/eunit_surefire.erl56
-rw-r--r--lib/eunit/vsn.mk2
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl83
-rw-r--r--lib/hipe/doc/src/notes.xml33
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/ic/doc/src/notes.xml18
-rw-r--r--lib/ic/src/ic_pp.erl472
-rw-r--r--lib/ic/src/ic_pragma.erl19
-rw-r--r--lib/ic/vsn.mk2
-rw-r--r--lib/inets/Makefile4
-rw-r--r--lib/inets/doc/src/http_server.xml2
-rw-r--r--lib/inets/doc/src/httpc.xml180
-rw-r--r--lib/inets/doc/src/inets.xml2
-rw-r--r--lib/inets/doc/src/notes.xml57
-rw-r--r--lib/inets/src/ftp/ftp.erl4
-rw-r--r--lib/inets/src/http_client/httpc.erl39
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl13
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl6
-rw-r--r--lib/inets/src/http_lib/http_transport.erl213
-rw-r--r--lib/inets/src/http_lib/http_util.erl2
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl2
-rw-r--r--lib/inets/src/http_server/httpd_util.erl2
-rw-r--r--lib/inets/src/inets_app/inets.appup.src18
-rw-r--r--lib/inets/test/ftp_suite_lib.erl35
-rw-r--r--lib/inets/test/httpc_SUITE.erl560
-rw-r--r--lib/inets/test/httpd_SUITE.erl304
-rw-r--r--lib/inets/test/httpd_test_lib.erl91
-rw-r--r--lib/inets/test/inets_app_test.erl2
-rw-r--r--lib/inets/test/inets_test_lib.erl153
-rw-r--r--lib/inets/test/inets_test_lib.hrl2
-rw-r--r--lib/inets/vsn.mk2
-rw-r--r--lib/kernel/doc/src/Makefile2
-rw-r--r--lib/kernel/doc/src/code.xml339
-rw-r--r--lib/kernel/doc/src/file.xml21
-rw-r--r--lib/kernel/doc/src/gen_sctp.xml146
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml25
-rw-r--r--lib/kernel/doc/src/gen_udp.xml21
-rw-r--r--lib/kernel/doc/src/inet.xml58
-rw-r--r--lib/kernel/doc/src/notes.xml65
-rw-r--r--lib/kernel/doc/src/os.xml3
-rw-r--r--lib/kernel/src/auth.erl2
-rw-r--r--lib/kernel/src/code.erl135
-rw-r--r--lib/kernel/src/code_server.erl17
-rw-r--r--lib/kernel/src/file.erl18
-rw-r--r--lib/kernel/src/gen_sctp.erl172
-rw-r--r--lib/kernel/src/gen_tcp.erl118
-rw-r--r--lib/kernel/src/gen_udp.erl85
-rw-r--r--lib/kernel/src/inet.erl147
-rw-r--r--lib/kernel/src/inet_config.erl52
-rw-r--r--lib/kernel/src/inet_dns_record_adts.pl12
-rw-r--r--lib/kernel/src/inet_res.erl6
-rw-r--r--lib/kernel/src/rpc.erl5
-rw-r--r--lib/kernel/src/seq_trace.erl2
-rw-r--r--lib/kernel/test/Makefile2
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl1
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/mnesia/doc/src/Mnesia_chap7.xmlsrc2
-rw-r--r--lib/mnesia/doc/src/mnesia.xml2
-rw-r--r--lib/mnesia/doc/src/notes.xml34
-rw-r--r--lib/mnesia/src/mnesia.hrl2
-rw-r--r--lib/observer/test/crashdump_helper.erl2
-rw-r--r--lib/odbc/c_src/odbcserver.c70
-rw-r--r--lib/odbc/c_src/odbcserver.h1
-rw-r--r--lib/odbc/doc/src/databases.xml4
-rw-r--r--lib/odbc/doc/src/odbc.xml2
-rw-r--r--lib/odbc/src/odbc.appup.src6
-rw-r--r--lib/odbc/src/odbc.erl7
-rw-r--r--lib/odbc/src/odbc_internal.hrl1
-rw-r--r--lib/odbc/test/Makefile3
-rw-r--r--lib/odbc/test/mysql.erl277
-rw-r--r--lib/odbc/test/odbc.dynspec31
-rw-r--r--lib/odbc/test/odbc.spec24
-rw-r--r--lib/odbc/test/odbc.spec.win5
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl237
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl516
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl64
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl27
-rw-r--r--lib/odbc/test/odbc_test.hrl13
-rw-r--r--lib/odbc/test/odbc_test_lib.erl57
-rw-r--r--lib/odbc/test/oracle.erl12
-rw-r--r--lib/odbc/test/postgres.erl23
-rw-r--r--lib/odbc/test/sqlserver.erl12
-rw-r--r--lib/odbc/vsn.mk2
-rw-r--r--lib/orber/doc/src/notes.xml16
-rw-r--r--lib/orber/src/orber.erl2
-rw-r--r--lib/orber/vsn.mk2
-rw-r--r--lib/os_mon/doc/src/notes.xml29
-rw-r--r--lib/os_mon/src/disksup.erl2
-rw-r--r--lib/os_mon/src/memsup.erl2
-rw-r--r--lib/os_mon/vsn.mk2
-rw-r--r--lib/parsetools/doc/src/leex.xml4
-rw-r--r--lib/parsetools/doc/src/yecc.xml12
-rw-r--r--lib/parsetools/src/leex.erl135
-rw-r--r--lib/parsetools/src/yecc.erl28
-rw-r--r--lib/parsetools/test/leex_SUITE.erl15
-rw-r--r--lib/parsetools/test/yecc_SUITE.erl8
-rw-r--r--lib/percept/src/percept_db.erl11
-rw-r--r--lib/public_key/asn1/README2
-rw-r--r--lib/public_key/doc/src/notes.xml16
-rw-r--r--lib/public_key/doc/src/public_key.xml16
-rw-r--r--lib/public_key/src/public_key.erl7
-rw-r--r--lib/reltool/doc/src/notes.xml28
-rw-r--r--lib/reltool/src/reltool_sys_win.erl133
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/sasl/doc/src/notes.xml96
-rw-r--r--lib/sasl/examples/src/Makefile2
-rw-r--r--lib/sasl/src/erlsrv.erl31
-rw-r--r--lib/sasl/src/release_handler.erl191
-rw-r--r--lib/sasl/src/release_handler_1.erl91
-rw-r--r--lib/sasl/src/sasl.erl2
-rw-r--r--lib/sasl/src/systools_lib.erl33
-rw-r--r--lib/sasl/test/Makefile5
-rw-r--r--lib/sasl/test/installer.erl80
-rw-r--r--lib/sasl/test/release_handler_SUITE.erl418
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/Makefile.src32
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/clients/start_cli138
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/erl.ini.src4
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/heart_restart.bat3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/README16
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.app (renamed from lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.app)4
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.appup3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/priv/file0
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl54
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl37
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/ebin/b.app7
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_lib.erl3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_server.erl37
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.app7
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_lib.erl3
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_server.erl37
-rw-r--r--lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app2
-rwxr-xr-xlib/sasl/test/release_handler_SUITE_data/start_client (renamed from lib/sasl/test/release_handler_SUITE_data/clients/start_cli2)2
-rw-r--r--lib/sasl/test/rh_test_lib.erl100
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/snmp/Makefile5
-rw-r--r--lib/snmp/doc/src/Makefile4
-rw-r--r--lib/snmp/doc/src/notes.xml130
-rw-r--r--lib/snmp/doc/src/snmp_agent_netif.xml2
-rw-r--r--lib/snmp/doc/src/snmpc.xml15
-rw-r--r--lib/snmp/doc/src/snmpc_cmd.xml28
-rw-r--r--lib/snmp/doc/src/snmpm.xml42
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl2
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl2
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl2
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl6
-rw-r--r--lib/snmp/src/agent/snmpa.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_acm.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl4
-rw-r--r--lib/snmp/src/agent/snmpa_authentication_service.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl11
-rw-r--r--lib/snmp/src/agent/snmpa_internal.hrl2
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl106
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl2
-rw-r--r--lib/snmp/src/app/snmp.appup.src226
-rw-r--r--lib/snmp/src/compile/Makefile11
-rw-r--r--lib/snmp/src/compile/snmpc.erl9
-rw-r--r--lib/snmp/src/compile/snmpc.src14
-rw-r--r--lib/snmp/src/compile/snmpc_lib.hrl15
-rw-r--r--lib/snmp/src/manager/snmpm.erl10
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl515
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl47
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl33
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl79
-rw-r--r--lib/snmp/src/manager/snmpm_usm.erl2
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl85
-rw-r--r--lib/snmp/src/misc/snmp_config.erl12
-rw-r--r--lib/snmp/src/misc/snmp_log.erl2
-rw-r--r--lib/snmp/src/misc/snmp_misc.erl2
-rw-r--r--lib/snmp/src/misc/snmp_pdus.erl2
-rw-r--r--lib/snmp/test/Makefile2
-rw-r--r--lib/snmp/test/snmp_agent_test.erl2
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl2
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl47
-rw-r--r--lib/snmp/test/snmp_manager_test.erl187
-rw-r--r--lib/snmp/test/snmp_manager_user.erl2
-rw-r--r--lib/snmp/test/snmp_pdus_test.erl2
-rw-r--r--lib/snmp/test/test_config/Makefile18
-rw-r--r--lib/snmp/vsn.mk2
-rw-r--r--lib/ssh/doc/src/notes.xml14
-rw-r--r--lib/ssh/src/ssh.appup.src10
-rwxr-xr-xlib/ssh/src/ssh_sftp.erl12
-rw-r--r--lib/ssh/test/Makefile2
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/c_src/Makefile.in2
-rw-r--r--lib/ssl/c_src/esock_openssl.c2
-rw-r--r--lib/ssl/doc/src/notes.xml6
-rw-r--r--lib/ssl/doc/src/ssl.xml35
-rw-r--r--lib/ssl/doc/src/ssl_protocol.xml4
-rw-r--r--lib/ssl/doc/src/using_ssl.xml8
-rw-r--r--lib/ssl/examples/src/Makefile2
-rw-r--r--lib/ssl/src/ssl.appup.src2
-rw-r--r--lib/ssl/src/ssl.erl66
-rw-r--r--lib/ssl/src/ssl_certificate.erl54
-rw-r--r--lib/ssl/src/ssl_certificate_db.erl49
-rw-r--r--lib/ssl/src/ssl_connection.erl148
-rw-r--r--lib/ssl/src/ssl_handshake.erl44
-rw-r--r--lib/ssl/src/ssl_internal.hrl4
-rw-r--r--lib/ssl/src/ssl_manager.erl69
-rw-r--r--lib/ssl/src/ssl_record.erl18
-rw-r--r--lib/ssl/src/ssl_session.erl6
-rw-r--r--lib/ssl/src/ssl_session_cache.erl16
-rw-r--r--lib/ssl/src/ssl_ssl2.erl2
-rw-r--r--lib/ssl/test/Makefile4
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl338
-rw-r--r--lib/ssl/test/ssl_session_cache_SUITE.erl108
-rw-r--r--lib/ssl/test/ssl_test_lib.erl3
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/doc/src/calendar.xml15
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml8
-rw-r--r--lib/stdlib/doc/src/io.xml2
-rw-r--r--lib/stdlib/doc/src/notes.xml181
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml2
-rw-r--r--lib/stdlib/src/calendar.erl78
-rw-r--r--lib/stdlib/src/erl_eval.erl2
-rw-r--r--lib/stdlib/src/erl_scan.erl7
-rw-r--r--lib/stdlib/src/erl_tar.erl30
-rw-r--r--lib/stdlib/src/io_lib.erl4
-rw-r--r--lib/stdlib/src/io_lib_fread.erl64
-rw-r--r--lib/stdlib/src/queue.erl127
-rw-r--r--lib/stdlib/src/slave.erl2
-rw-r--r--lib/stdlib/src/timer.erl6
-rw-r--r--lib/stdlib/src/zip.erl10
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl4
-rw-r--r--lib/stdlib/test/ets_SUITE.erl76
-rw-r--r--lib/stdlib/test/io_SUITE.erl30
-rw-r--r--lib/stdlib/test/supervisor_SUITE.erl18
-rw-r--r--lib/stdlib/test/zip_SUITE.erl3
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/syntax_tools/doc/src/notes.xml19
-rw-r--r--lib/syntax_tools/vsn.mk2
-rw-r--r--lib/test_server/doc/src/notes.xml59
-rw-r--r--lib/test_server/src/configure.in2
-rw-r--r--lib/test_server/src/ts_install.erl2
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/notes.xml67
-rw-r--r--lib/tools/doc/src/xref.xml8
-rw-r--r--lib/tools/src/make.erl2
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/tv/doc/src/notes.xml24
-rw-r--r--lib/tv/vsn.mk2
-rw-r--r--lib/typer/vsn.mk2
-rw-r--r--lib/webtool/doc/src/notes.xml16
-rw-r--r--lib/webtool/doc/src/webtool_chapter.xml2
-rw-r--r--lib/webtool/vsn.mk2
-rw-r--r--lib/wx/doc/src/notes.xml16
-rw-r--r--lib/wx/src/Makefile7
-rw-r--r--lib/wx/src/wx.appup.src3
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/notes.xml46
-rw-r--r--lib/xmerl/include/xmerl_xsd.hrl1
-rw-r--r--lib/xmerl/src/xmerl_sax_parser.erl2
-rw-r--r--lib/xmerl/src/xmerl_scan.erl4
-rw-r--r--lib/xmerl/src/xmerl_xpath.erl2
-rw-r--r--lib/xmerl/src/xmerl_xsd.erl45
-rw-r--r--lib/xmerl/src/xmerl_xsd_type.erl2
-rw-r--r--lib/xmerl/test/Makefile4
-rw-r--r--lib/xmerl/test/xmerl_SUITE.erl15
-rw-r--r--lib/xmerl/test/xmerl_SUITE_data/misc.tar.gzbin47121 -> 47340 bytes
-rw-r--r--lib/xmerl/test/xmerl_appup_test.erl2
-rw-r--r--lib/xmerl/test/xmerl_sax_std_SUITE.erl2
-rw-r--r--lib/xmerl/test/xmerl_test_lib.erl2
-rw-r--r--lib/xmerl/test/xmerl_xsd_SUITE.erl9
-rw-r--r--lib/xmerl/test/xmerl_xsd_lib.erl2
-rw-r--r--make/otp.mk.in2
-rwxr-xr-xotp_build2
-rw-r--r--system/doc/efficiency_guide/drivers.xml2
-rw-r--r--system/doc/efficiency_guide/functions.xml2
-rw-r--r--system/doc/efficiency_guide/processes.xml2
-rw-r--r--system/doc/efficiency_guide/profiling.xml2
-rw-r--r--system/doc/efficiency_guide/tablesDatabases.xml2
640 files changed, 13237 insertions, 13147 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 1061c5187a..24053b4793 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -27,7 +27,7 @@ on Unix. For detailed instructions on how to
Binary releases for Windows can be found at
<http://www.erlang.org/download.html>.
-Before reading the above mensioned documents you are in any case advised to
+Before reading the above mentioned documents you are in any case advised to
read this document first, since it covers building Erlang/OTP in general as
well as other important information.
@@ -424,7 +424,7 @@ as before, but the build process will take a much longer time.
### Building in Git ###
When building in a Git working directory you also have to have a GNU `autoconf`
-of at least version 2.59 on your system. This since you need to generate the
+of at least version 2.59 on your system, because you need to generate the
`configure` scripts before you can start building.
The `configure` scripts are generated by invoking `./otp_build autoconf` in
@@ -436,7 +436,7 @@ when checking out a branch. Regenerated `configure` scripts imply that you
have to run `configure` and build again.
> *NOTE*: Running `./otp_build autoconf` is **not** needed when building
-> an unmodified version the released source.
+> an unmodified version of the released source.
Other useful information can be found at our github wiki:
<http://wiki.github.com/erlang/otp>
diff --git a/bootstrap/bin/start.script b/bootstrap/bin/start.script
index ba1aed08e7..9b447c34a9 100644
--- a/bootstrap/bin/start.script
+++ b/bootstrap/bin/start.script
@@ -1,4 +1,4 @@
-%% script generated at {2011,3,30} {10,45,5}
+%% script generated at {2011,5,20} {15,43,53}
{script,
{"OTP APN 181 01","R14B03"},
[{preLoaded,
diff --git a/bootstrap/bin/start_clean.script b/bootstrap/bin/start_clean.script
index ba1aed08e7..9b447c34a9 100644
--- a/bootstrap/bin/start_clean.script
+++ b/bootstrap/bin/start_clean.script
@@ -1,4 +1,4 @@
-%% script generated at {2011,3,30} {10,45,5}
+%% script generated at {2011,5,20} {15,43,53}
{script,
{"OTP APN 181 01","R14B03"},
[{preLoaded,
diff --git a/bootstrap/lib/compiler/ebin/beam_bsm.beam b/bootstrap/lib/compiler/ebin/beam_bsm.beam
index fb331ee690..48302c39d2 100644
--- a/bootstrap/lib/compiler/ebin/beam_bsm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bsm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam
index 56288dc79e..652e2b44ea 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/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app
index b7518ff62f..fffb64c3a0 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -1,7 +1,7 @@
% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/compiler/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl
index b99bc0dbc3..399d61109f 100644
--- a/bootstrap/lib/compiler/egen/core_parse.erl
+++ b/bootstrap/lib/compiler/egen/core_parse.erl
@@ -13,11 +13,11 @@
tok_val(T) -> element(3, T).
tok_line(T) -> element(2, T).
--file("/usr/local/otp/releases/sles10_32_R14B02_patched/lib/parsetools-2.0.5/include/yeccpre.hrl", 0).
+-file("/opt/installs/lib/erlang/lib/parsetools-2.0.5/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -196,7 +196,7 @@ yecctoken2string(Other) ->
--file("/ldisk/bjorn/otp/bootstrap/lib/compiler/egen/core_parse.erl", 199).
+-file("/ldisk/egil/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 199).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
diff --git a/bootstrap/lib/kernel/ebin/application.beam b/bootstrap/lib/kernel/ebin/application.beam
index 3414e8bcc4..ca16b97197 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/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam
index f41ed33d9a..0b9ee6fb8d 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/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index 333dd35c7e..7cfbafb942 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 42be2aad4c..ec789e71ff 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/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
index 0bab2d23c7..a53e6f8800 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 52dc98319f..faac3fc921 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/inet_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam
index f1433006b7..61fe96d055 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/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index 296382abc2..9b5bff5033 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index 2e79781da8..b53dd9295a 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 cd112bb1cf..de55c53503 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 b14425b01c..a669e64bea 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/rpc.beam b/bootstrap/lib/kernel/ebin/rpc.beam
index 5fe7a7fffe..38ae0f4694 100644
--- a/bootstrap/lib/kernel/ebin/rpc.beam
+++ b/bootstrap/lib/kernel/ebin/rpc.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/include/inet.hrl b/bootstrap/lib/kernel/include/inet.hrl
index 929b2ee294..3e64d4bb79 100644
--- a/bootstrap/lib/kernel/include/inet.hrl
+++ b/bootstrap/lib/kernel/include/inet.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,18 +19,11 @@
%% This record is returned by inet:gethostbyaddr/2 and inet:gethostbyname/2.
--type hostname() :: atom() | string().
--type ip4_address() :: {0..255,0..255,0..255,0..255}.
--type ip6_address() :: {0..65535,0..65535,0..65535,0..65535,
- 0..65535,0..65535,0..65535,0..65535}.
--type ip_address() :: ip4_address() | ip6_address().
--type ip_port() :: 0..65535.
-
-record(hostent,
{
- h_name :: hostname(), %% offical name of host
- h_aliases = [] :: [hostname()], %% alias list
+ h_name :: inet:hostname(), %% offical name of host
+ h_aliases = [] :: [inet:hostname()], %% alias list
h_addrtype :: 'inet' | 'inet6', %% host address type
h_length :: non_neg_integer(), %% length of address
- h_addr_list = [] :: [ip_address()] %% list of addresses from name server
+ h_addr_list = [] :: [inet:ip_address()]%% list of addresses from name server
}).
diff --git a/bootstrap/lib/kernel/include/inet_sctp.hrl b/bootstrap/lib/kernel/include/inet_sctp.hrl
index 169ba013aa..3c072cc1db 100644
--- a/bootstrap/lib/kernel/include/inet_sctp.hrl
+++ b/bootstrap/lib/kernel/include/inet_sctp.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/orber/include/Makefile b/bootstrap/lib/orber/include/Makefile
index 219b7085e6..5aaeed1015 100644
--- a/bootstrap/lib/orber/include/Makefile
+++ b/bootstrap/lib/orber/include/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1998-2009. All Rights Reserved.
+# Copyright Ericsson AB 1998-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/orber/include/corba.hrl b/bootstrap/lib/orber/include/corba.hrl
index b9869855bf..526662d59d 100644
--- a/bootstrap/lib/orber/include/corba.hrl
+++ b/bootstrap/lib/orber/include/corba.hrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/orber/include/orber_pi.hrl b/bootstrap/lib/orber/include/orber_pi.hrl
index 84231758fe..69f14a5165 100644
--- a/bootstrap/lib/orber/include/orber_pi.hrl
+++ b/bootstrap/lib/orber/include/orber_pi.hrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/ebin/array.beam b/bootstrap/lib/stdlib/ebin/array.beam
index 1c26f19403..5e309a9842 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 8615d4872e..d29c13189a 100644
--- a/bootstrap/lib/stdlib/ebin/beam_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index e5acfa207d..7a31c9bfef 100644
--- a/bootstrap/lib/stdlib/ebin/c.beam
+++ b/bootstrap/lib/stdlib/ebin/c.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index 7b3b5719b6..002b3c9229 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/dict.beam b/bootstrap/lib/stdlib/ebin/dict.beam
index ee24ed8f47..9b65b345ff 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 d80b3a09c4..79c25f5a30 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 ce329ab2ab..18ebd2e30c 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/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 0483b561d4..528692fb81 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_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index cac3a46319..184918e97d 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 81936036ae..e292c379b0 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_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index 33d62a7a37..552c418ee8 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 753080584f..27e760de1f 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 8036376515..9dbed0af01 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 eb0ddd4397..51082779b8 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/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index ec0a566d14..1e0742e341 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 29eb281856..281c66b3ee 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/gen.beam b/bootstrap/lib/stdlib/ebin/gen.beam
index 3ad4d282f0..71733a69cf 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 79a037d8c8..321d3e7733 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 73df87a7ef..3467b05cd6 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 3b066ada0b..8354aabd1c 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/lib.beam b/bootstrap/lib/stdlib/ebin/lib.beam
index fb08310f36..07740547ed 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 153d6fb2ee..fe06dc3b4a 100644
--- a/bootstrap/lib/stdlib/ebin/lists.beam
+++ b/bootstrap/lib/stdlib/ebin/lists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/log_mf_h.beam b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
index 04c1bf5824..4afaff66d4 100644
--- a/bootstrap/lib/stdlib/ebin/log_mf_h.beam
+++ b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam
index 42335a6a00..898ee9861d 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 0f3850677f..d6bed77761 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 709d1379dd..2fbda80a5e 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/pool.beam b/bootstrap/lib/stdlib/ebin/pool.beam
index 74377d404b..29e5f83b5e 100644
--- a/bootstrap/lib/stdlib/ebin/pool.beam
+++ b/bootstrap/lib/stdlib/ebin/pool.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/proc_lib.beam b/bootstrap/lib/stdlib/ebin/proc_lib.beam
index 8a40aa650d..d2fb37b8ea 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 da0adc0c23..e250a375dd 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 141891308f..d405d8483f 100644
--- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/re.beam b/bootstrap/lib/stdlib/ebin/re.beam
index 8f763f66bf..da228c5542 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/sets.beam b/bootstrap/lib/stdlib/ebin/sets.beam
index e95a93e5cf..5ef47425a0 100644
--- a/bootstrap/lib/stdlib/ebin/sets.beam
+++ b/bootstrap/lib/stdlib/ebin/sets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index 737223aaf8..a8a03d5f3b 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/slave.beam b/bootstrap/lib/stdlib/ebin/slave.beam
index cf030178ef..ceb4f0e60f 100644
--- a/bootstrap/lib/stdlib/ebin/slave.beam
+++ b/bootstrap/lib/stdlib/ebin/slave.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index aa12f15cdc..8cbcfb55de 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 ac8b4ec113..bcce209e27 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index 124920f0a5..4e46676a20 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index e08ec9e70d..e972bcbd14 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 b4d979c577..0bfe233ad7 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 2a72ee9af6..62e348b3a5 100644
--- a/bootstrap/lib/stdlib/ebin/unicode.beam
+++ b/bootstrap/lib/stdlib/ebin/unicode.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index 6aa0cc32b2..74f7c6a208 100644
--- a/bootstrap/lib/stdlib/ebin/zip.beam
+++ b/bootstrap/lib/stdlib/ebin/zip.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/egen/erl_parse.erl b/bootstrap/lib/stdlib/egen/erl_parse.erl
index 9999fad385..97952dcb46 100644
--- a/bootstrap/lib/stdlib/egen/erl_parse.erl
+++ b/bootstrap/lib/stdlib/egen/erl_parse.erl
@@ -12,6 +12,15 @@
%% of the generated .erl file by the HiPE compiler. Please do not remove.
-compile([{hipe,[{regalloc,linear_scan}]}]).
+-export_type([abstract_clause/0, abstract_expr/0, abstract_form/0,
+ error_info/0]).
+
+-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 token() :: {Tag :: atom(), Line :: erl_scan:line()}.
%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
@@ -35,11 +44,19 @@
%% 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(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}]}} ->
@@ -47,6 +64,10 @@ parse_exprs(Tokens) ->
{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]}]}} ->
@@ -331,6 +352,7 @@ check_clauses(Cs, Name, Arity) ->
build_try(L,Es,Scs,{Ccs,As}) ->
{'try',L,Es,Scs,Ccs,As}.
+-spec ret_err(_, _) -> no_return().
ret_err(L, S) ->
{location,Location} = get_attribute(L, location),
return_error(Location, S).
@@ -347,10 +369,11 @@ mapl(F, [H|T]) ->
mapl(_, []) ->
[].
-%% normalise(AbsTerm)
-%% abstract(Term)
%% 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;
@@ -388,6 +411,9 @@ normalise_list([H|T]) ->
normalise_list([]) ->
[].
+-spec abstract(Data) -> AbsTerm when
+ Data :: term(),
+ AbsTerm :: abstract_expr().
abstract(T) when is_integer(T) -> {integer,0,T};
abstract(T) when is_float(T) -> {float,0,T};
abstract(T) when is_atom(T) -> {atom,0,T};
@@ -456,13 +482,18 @@ abstract_list([H|T], Line) ->
abstract_list([], _Line) ->
[].
-%% tokens(AbsTerm) -> [Token]
-%% tokens(AbsTerm, More) -> [Token]
%% 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];
@@ -562,11 +593,11 @@ get_attribute(L, Name) ->
get_attributes(L) ->
erl_scan:attributes_info(L).
--file("/usr/local/otp/releases/sles10_32_R14B02_patched/lib/parsetools-2.0.5/include/yeccpre.hrl", 0).
+-file("/opt/installs/lib/erlang/lib/parsetools-2.0.5/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -745,7 +776,7 @@ yecctoken2string(Other) ->
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 748).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 779).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
@@ -8201,7 +8232,7 @@ yeccpars2_39_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8204).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8235).
-compile({inline,yeccpars2_46_/1}).
-file("erl_parse.yrl", 434).
yeccpars2_46_(__Stack0) ->
@@ -8210,7 +8241,7 @@ yeccpars2_46_(__Stack0) ->
{ [ ] , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8213).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8244).
-compile({inline,yeccpars2_70_/1}).
-file("erl_parse.yrl", 325).
yeccpars2_70_(__Stack0) ->
@@ -8219,7 +8250,7 @@ yeccpars2_70_(__Stack0) ->
{ tuple , ? line ( __1 ) , [ ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8222).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8253).
-compile({inline,yeccpars2_71_/1}).
-file("erl_parse.yrl", 326).
yeccpars2_71_(__Stack0) ->
@@ -8228,7 +8259,7 @@ yeccpars2_71_(__Stack0) ->
{ tuple , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8231).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8262).
-compile({inline,yeccpars2_73_/1}).
-file("erl_parse.yrl", 408).
yeccpars2_73_(__Stack0) ->
@@ -8260,7 +8291,7 @@ yeccpars2_81_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8263).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8294).
-compile({inline,yeccpars2_82_/1}).
-file("erl_parse.yrl", 406).
yeccpars2_82_(__Stack0) ->
@@ -8293,7 +8324,7 @@ yeccpars2_88_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8296).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8327).
-compile({inline,yeccpars2_89_/1}).
-file("erl_parse.yrl", 381).
yeccpars2_89_(__Stack0) ->
@@ -8332,7 +8363,7 @@ yeccpars2_98_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8335).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8366).
-compile({inline,yeccpars2_100_/1}).
-file("erl_parse.yrl", 427).
yeccpars2_100_(__Stack0) ->
@@ -8349,7 +8380,7 @@ yeccpars2_102_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8352).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8383).
-compile({inline,yeccpars2_104_/1}).
-file("erl_parse.yrl", 424).
yeccpars2_104_(__Stack0) ->
@@ -8359,7 +8390,7 @@ yeccpars2_104_(__Stack0) ->
{ clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8362).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8393).
-compile({inline,yeccpars2_106_/1}).
-file("erl_parse.yrl", 421).
yeccpars2_106_(__Stack0) ->
@@ -8401,7 +8432,7 @@ yeccpars2_114_(__Stack0) ->
{ [ ] , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8404).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8435).
-compile({inline,yeccpars2_115_/1}).
-file("erl_parse.yrl", 452).
yeccpars2_115_(__Stack0) ->
@@ -8410,7 +8441,7 @@ yeccpars2_115_(__Stack0) ->
{ string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8413).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8444).
-compile({inline,yeccpars2_120_/1}).
-file("erl_parse.yrl", 386).
yeccpars2_120_(__Stack0) ->
@@ -8419,7 +8450,7 @@ yeccpars2_120_(__Stack0) ->
{ 'receive' , ? line ( __1 ) , [ ] , __3 , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8422).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8453).
-compile({inline,yeccpars2_122_/1}).
-file("erl_parse.yrl", 384).
yeccpars2_122_(__Stack0) ->
@@ -8428,7 +8459,7 @@ yeccpars2_122_(__Stack0) ->
{ 'receive' , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8431).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8462).
-compile({inline,yeccpars2_125_/1}).
-file("erl_parse.yrl", 388).
yeccpars2_125_(__Stack0) ->
@@ -8445,7 +8476,7 @@ yeccpars2_131_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8448).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8479).
-compile({inline,yeccpars2_135_/1}).
-file("erl_parse.yrl", 323).
yeccpars2_135_(__Stack0) ->
@@ -8454,7 +8485,7 @@ yeccpars2_135_(__Stack0) ->
{ b_generate , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8457).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8488).
-compile({inline,yeccpars2_137_/1}).
-file("erl_parse.yrl", 322).
yeccpars2_137_(__Stack0) ->
@@ -8471,7 +8502,7 @@ yeccpars2_139_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8474).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8505).
-compile({inline,yeccpars2_140_/1}).
-file("erl_parse.yrl", 315).
yeccpars2_140_(__Stack0) ->
@@ -8480,7 +8511,7 @@ yeccpars2_140_(__Stack0) ->
{ lc , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8483).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8514).
-compile({inline,yeccpars2_141_/1}).
-file("erl_parse.yrl", 431).
yeccpars2_141_(__Stack0) ->
@@ -8497,7 +8528,7 @@ yeccpars2_143_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8500).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8531).
-compile({inline,yeccpars2_145_/1}).
-file("erl_parse.yrl", 371).
yeccpars2_145_(__Stack0) ->
@@ -8514,7 +8545,7 @@ yeccpars2_147_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8517).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8548).
-compile({inline,yeccpars2_148_/1}).
-file("erl_parse.yrl", 365).
yeccpars2_148_(__Stack0) ->
@@ -8538,7 +8569,7 @@ yeccpars2_151_(__Stack0) ->
[ ]
end | __Stack0].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8541).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8572).
-compile({inline,yeccpars2_157_/1}).
-file("erl_parse.yrl", 394).
yeccpars2_157_(__Stack0) ->
@@ -8547,7 +8578,7 @@ yeccpars2_157_(__Stack0) ->
{ 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8550).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8581).
-compile({inline,yeccpars2_158_/1}).
-file("erl_parse.yrl", 392).
yeccpars2_158_(__Stack0) ->
@@ -8573,7 +8604,7 @@ yeccpars2_162_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8576).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8607).
-compile({inline,yeccpars2_163_/1}).
-file("erl_parse.yrl", 396).
yeccpars2_163_(__Stack0) ->
@@ -8582,7 +8613,7 @@ yeccpars2_163_(__Stack0) ->
build_fun ( ? line ( __1 ) , __2 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8585).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8616).
-compile({inline,yeccpars2_164_/1}).
-file("erl_parse.yrl", 214).
yeccpars2_164_(__Stack0) ->
@@ -8591,7 +8622,7 @@ yeccpars2_164_(__Stack0) ->
{ 'catch' , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8594).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8625).
-compile({inline,yeccpars2_168_/1}).
-file("erl_parse.yrl", 375).
yeccpars2_168_(__Stack0) ->
@@ -8600,7 +8631,7 @@ yeccpars2_168_(__Stack0) ->
{ 'case' , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8603).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8634).
-compile({inline,yeccpars2_170_/1}).
-file("erl_parse.yrl", 270).
yeccpars2_170_(__Stack0) ->
@@ -8609,7 +8640,7 @@ yeccpars2_170_(__Stack0) ->
{ block , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8612).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8643).
-compile({inline,yeccpars2_172_/1}).
-file("erl_parse.yrl", 279).
yeccpars2_172_(__Stack0) ->
@@ -8618,7 +8649,7 @@ yeccpars2_172_(__Stack0) ->
{ nil , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8621).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8652).
-compile({inline,yeccpars2_173_/1}).
-file("erl_parse.yrl", 280).
yeccpars2_173_(__Stack0) ->
@@ -8627,7 +8658,7 @@ yeccpars2_173_(__Stack0) ->
{ cons , ? line ( __1 ) , __2 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8630).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8661).
-compile({inline,yeccpars2_175_/1}).
-file("erl_parse.yrl", 282).
yeccpars2_175_(__Stack0) ->
@@ -8644,7 +8675,7 @@ yeccpars2_178_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8647).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8678).
-compile({inline,yeccpars2_180_/1}).
-file("erl_parse.yrl", 284).
yeccpars2_180_(__Stack0) ->
@@ -8668,7 +8699,7 @@ yeccpars2_186_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8671).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8702).
-compile({inline,yeccpars2_187_/1}).
-file("erl_parse.yrl", 287).
yeccpars2_187_(__Stack0) ->
@@ -8685,7 +8716,7 @@ yeccpars2_189_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8688).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8719).
-compile({inline,yeccpars2_190_/1}).
-file("erl_parse.yrl", 288).
yeccpars2_190_(__Stack0) ->
@@ -8694,7 +8725,7 @@ yeccpars2_190_(__Stack0) ->
{ bin , ? line ( __1 ) , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8697).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8728).
-compile({inline,yeccpars2_193_/1}).
-file("erl_parse.yrl", 317).
yeccpars2_193_(__Stack0) ->
@@ -8718,7 +8749,7 @@ yeccpars2_197_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8721).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8752).
-compile({inline,yeccpars2_198_/1}).
-file("erl_parse.yrl", 294).
yeccpars2_198_(__Stack0) ->
@@ -8767,7 +8798,7 @@ yeccpars2_206_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8770).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8801).
-compile({inline,yeccpars2_207_/1}).
-file("erl_parse.yrl", 296).
yeccpars2_207_(__Stack0) ->
@@ -8776,7 +8807,7 @@ yeccpars2_207_(__Stack0) ->
? mkop1 ( __1 , __2 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8779).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8810).
-compile({inline,yeccpars2_208_/1}).
-file("erl_parse.yrl", 256).
yeccpars2_208_(__Stack0) ->
@@ -8793,7 +8824,7 @@ yeccpars2_210_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8796).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8827).
-compile({inline,yeccpars2_212_/1}).
-file("erl_parse.yrl", 340).
yeccpars2_212_(__Stack0) ->
@@ -8818,7 +8849,7 @@ yeccpars2_219_(__Stack0) ->
[ ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8821).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8852).
-compile({inline,yeccpars2_221_/1}).
-file("erl_parse.yrl", 356).
yeccpars2_221_(__Stack0) ->
@@ -8827,7 +8858,7 @@ yeccpars2_221_(__Stack0) ->
{ record_field , ? line ( __1 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8830).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8861).
-compile({inline,yeccpars2_223_/1}).
-file("erl_parse.yrl", 357).
yeccpars2_223_(__Stack0) ->
@@ -8852,7 +8883,7 @@ yeccpars2_226_(__Stack0) ->
__2
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8855).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8886).
-compile({inline,yeccpars2_227_/1}).
-file("erl_parse.yrl", 338).
yeccpars2_227_(__Stack0) ->
@@ -8869,7 +8900,7 @@ yeccpars2_229_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8872).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8903).
-compile({inline,yeccpars2_232_/1}).
-file("erl_parse.yrl", 217).
yeccpars2_232_(__Stack0) ->
@@ -8878,7 +8909,7 @@ yeccpars2_232_(__Stack0) ->
{ match , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8881).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8912).
-compile({inline,yeccpars2_233_/1}).
-file("erl_parse.yrl", 218).
yeccpars2_233_(__Stack0) ->
@@ -8887,7 +8918,7 @@ yeccpars2_233_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8890).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8921).
-compile({inline,yeccpars2_235_/1}).
-file("erl_parse.yrl", 221).
yeccpars2_235_(__Stack0) ->
@@ -8896,7 +8927,7 @@ yeccpars2_235_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8899).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8930).
-compile({inline,yeccpars2_237_/1}).
-file("erl_parse.yrl", 224).
yeccpars2_237_(__Stack0) ->
@@ -8905,7 +8936,7 @@ yeccpars2_237_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8908).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8939).
-compile({inline,yeccpars2_247_/1}).
-file("erl_parse.yrl", 228).
yeccpars2_247_(__Stack0) ->
@@ -8914,7 +8945,7 @@ yeccpars2_247_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8917).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8948).
-compile({inline,yeccpars2_260_/1}).
-file("erl_parse.yrl", 236).
yeccpars2_260_(__Stack0) ->
@@ -8923,7 +8954,7 @@ yeccpars2_260_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8926).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8957).
-compile({inline,yeccpars2_268_/1}).
-file("erl_parse.yrl", 240).
yeccpars2_268_(__Stack0) ->
@@ -8932,7 +8963,7 @@ yeccpars2_268_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8935).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8966).
-compile({inline,yeccpars2_269_/1}).
-file("erl_parse.yrl", 232).
yeccpars2_269_(__Stack0) ->
@@ -8941,7 +8972,7 @@ yeccpars2_269_(__Stack0) ->
? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8944).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8975).
-compile({inline,yeccpars2_270_/1}).
-file("erl_parse.yrl", 362).
yeccpars2_270_(__Stack0) ->
@@ -8950,7 +8981,7 @@ yeccpars2_270_(__Stack0) ->
{ call , ? line ( __1 ) , __1 , element ( 1 , __2 ) }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8953).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8984).
-compile({inline,yeccpars2_273_/1}).
-file("erl_parse.yrl", 252).
yeccpars2_273_(__Stack0) ->
@@ -8959,7 +8990,7 @@ yeccpars2_273_(__Stack0) ->
{ remote , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8962).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8993).
-compile({inline,yeccpars2_274_/1}).
-file("erl_parse.yrl", 258).
yeccpars2_274_(__Stack0) ->
@@ -8968,7 +8999,7 @@ yeccpars2_274_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8971).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9002).
-compile({inline,yeccpars2_277_/1}).
-file("erl_parse.yrl", 344).
yeccpars2_277_(__Stack0) ->
@@ -8977,7 +9008,7 @@ yeccpars2_277_(__Stack0) ->
{ record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8980).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9011).
-compile({inline,yeccpars2_279_/1}).
-file("erl_parse.yrl", 342).
yeccpars2_279_(__Stack0) ->
@@ -8986,7 +9017,7 @@ yeccpars2_279_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8989).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9020).
-compile({inline,yeccpars2_280_/1}).
-file("erl_parse.yrl", 435).
yeccpars2_280_(__Stack0) ->
@@ -8995,7 +9026,7 @@ yeccpars2_280_(__Stack0) ->
{ __2 , ? line ( __1 ) }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8998).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9029).
-compile({inline,yeccpars2_281_/1}).
-file("erl_parse.yrl", 244).
yeccpars2_281_(__Stack0) ->
@@ -9004,7 +9035,7 @@ yeccpars2_281_(__Stack0) ->
? mkop1 ( __1 , __2 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9007).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9038).
-compile({inline,yeccpars2_284_/1}).
-file("erl_parse.yrl", 348).
yeccpars2_284_(__Stack0) ->
@@ -9013,7 +9044,7 @@ yeccpars2_284_(__Stack0) ->
{ record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9016).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9047).
-compile({inline,yeccpars2_286_/1}).
-file("erl_parse.yrl", 346).
yeccpars2_286_(__Stack0) ->
@@ -9022,7 +9053,7 @@ yeccpars2_286_(__Stack0) ->
{ record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9025).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9056).
-compile({inline,yeccpars2_288_/1}).
-file("erl_parse.yrl", 493).
yeccpars2_288_(__Stack0) ->
@@ -9031,7 +9062,7 @@ yeccpars2_288_(__Stack0) ->
{ clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9034).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9065).
-compile({inline,yeccpars2_289_/1}).
-file("erl_parse.yrl", 203).
yeccpars2_289_(__Stack0) ->
@@ -9096,7 +9127,7 @@ yeccpars2_318_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9099).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9130).
-compile({inline,yeccpars2_332_/1}).
-file("erl_parse.yrl", 152).
yeccpars2_332_(__Stack0) ->
@@ -9105,7 +9136,7 @@ yeccpars2_332_(__Stack0) ->
{ type , ? line ( __1 ) , tuple , [ ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9108).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9139).
-compile({inline,yeccpars2_333_/1}).
-file("erl_parse.yrl", 153).
yeccpars2_333_(__Stack0) ->
@@ -9114,7 +9145,7 @@ yeccpars2_333_(__Stack0) ->
{ type , ? line ( __1 ) , tuple , __2 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9117).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9148).
-compile({inline,yeccpars2_335_/1}).
-file("erl_parse.yrl", 116).
yeccpars2_335_(__Stack0) ->
@@ -9123,7 +9154,7 @@ yeccpars2_335_(__Stack0) ->
{ ann_type , ? line ( __1 ) , [ __1 , __3 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9126).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9157).
-compile({inline,yeccpars2_341_/1}).
-file("erl_parse.yrl", 159).
yeccpars2_341_(__Stack0) ->
@@ -9132,7 +9163,7 @@ yeccpars2_341_(__Stack0) ->
{ type , ? line ( __1 ) , 'fun' , [ ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9135).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9166).
-compile({inline,yeccpars2_345_/1}).
-file("erl_parse.yrl", 163).
yeccpars2_345_(__Stack0) ->
@@ -9150,7 +9181,7 @@ yeccpars2_346_(__Stack0) ->
__3
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9153).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9184).
-compile({inline,yeccpars2_352_/1}).
-file("erl_parse.yrl", 144).
yeccpars2_352_(__Stack0) ->
@@ -9160,7 +9191,7 @@ yeccpars2_352_(__Stack0) ->
[ __1 , __3 , [ ] ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9163).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9194).
-compile({inline,yeccpars2_353_/1}).
-file("erl_parse.yrl", 146).
yeccpars2_353_(__Stack0) ->
@@ -9178,7 +9209,7 @@ yeccpars2_355_(__Stack0) ->
build_gen_type ( __1 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9181).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9212).
-compile({inline,yeccpars2_356_/1}).
-file("erl_parse.yrl", 142).
yeccpars2_356_(__Stack0) ->
@@ -9188,7 +9219,7 @@ yeccpars2_356_(__Stack0) ->
normalise ( __1 ) , __3 }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9191).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9222).
-compile({inline,yeccpars2_358_/1}).
-file("erl_parse.yrl", 148).
yeccpars2_358_(__Stack0) ->
@@ -9197,7 +9228,7 @@ yeccpars2_358_(__Stack0) ->
{ type , ? line ( __1 ) , nil , [ ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9200).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9231).
-compile({inline,yeccpars2_360_/1}).
-file("erl_parse.yrl", 149).
yeccpars2_360_(__Stack0) ->
@@ -9206,7 +9237,7 @@ yeccpars2_360_(__Stack0) ->
{ type , ? line ( __1 ) , list , [ __2 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9209).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9240).
-compile({inline,yeccpars2_362_/1}).
-file("erl_parse.yrl", 150).
yeccpars2_362_(__Stack0) ->
@@ -9216,7 +9247,7 @@ yeccpars2_362_(__Stack0) ->
nonempty_list , [ __2 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9219).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9250).
-compile({inline,yeccpars2_365_/1}).
-file("erl_parse.yrl", 179).
yeccpars2_365_(__Stack0) ->
@@ -9243,7 +9274,7 @@ yeccpars2_371_(__Stack0) ->
build_bin_type ( [ __1 , __3 ] , __5 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9246).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9277).
-compile({inline,yeccpars2_373_/1}).
-file("erl_parse.yrl", 182).
yeccpars2_373_(__Stack0) ->
@@ -9253,7 +9284,7 @@ yeccpars2_373_(__Stack0) ->
[ __2 , abstract ( 0 , ? line ( __1 ) ) ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9256).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9287).
-compile({inline,yeccpars2_378_/1}).
-file("erl_parse.yrl", 187).
yeccpars2_378_(__Stack0) ->
@@ -9262,7 +9293,7 @@ yeccpars2_378_(__Stack0) ->
{ type , ? line ( __1 ) , binary , [ __2 , __4 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9265).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9296).
-compile({inline,yeccpars2_379_/1}).
-file("erl_parse.yrl", 184).
yeccpars2_379_(__Stack0) ->
@@ -9272,7 +9303,7 @@ yeccpars2_379_(__Stack0) ->
[ abstract ( 0 , ? line ( __1 ) ) , __2 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9275).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9306).
-compile({inline,yeccpars2_381_/1}).
-file("erl_parse.yrl", 167).
yeccpars2_381_(__Stack0) ->
@@ -9282,7 +9313,7 @@ yeccpars2_381_(__Stack0) ->
[ { type , ? line ( __1 ) , product , [ ] } , __4 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9285).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9316).
-compile({inline,yeccpars2_383_/1}).
-file("erl_parse.yrl", 138).
yeccpars2_383_(__Stack0) ->
@@ -9299,7 +9330,7 @@ yeccpars2_387_(__Stack0) ->
[ __1 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9302).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9333).
-compile({inline,yeccpars2_389_/1}).
-file("erl_parse.yrl", 154).
yeccpars2_389_(__Stack0) ->
@@ -9308,7 +9339,7 @@ yeccpars2_389_(__Stack0) ->
{ type , ? line ( __1 ) , record , [ __2 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9311).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9342).
-compile({inline,yeccpars2_391_/1}).
-file("erl_parse.yrl", 176).
yeccpars2_391_(__Stack0) ->
@@ -9326,7 +9357,7 @@ yeccpars2_393_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9329).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9360).
-compile({inline,yeccpars2_394_/1}).
-file("erl_parse.yrl", 155).
yeccpars2_394_(__Stack0) ->
@@ -9336,7 +9367,7 @@ yeccpars2_394_(__Stack0) ->
record , [ __2 | __4 ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9339).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9370).
-compile({inline,yeccpars2_395_/1}).
-file("erl_parse.yrl", 135).
yeccpars2_395_(__Stack0) ->
@@ -9353,7 +9384,7 @@ yeccpars2_397_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9356).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9387).
-compile({inline,yeccpars2_400_/1}).
-file("erl_parse.yrl", 170).
yeccpars2_400_(__Stack0) ->
@@ -9371,7 +9402,7 @@ yeccpars2_402_(__Stack0) ->
lift_unions ( __1 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9374).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9405).
-compile({inline,yeccpars2_405_/1}).
-file("erl_parse.yrl", 122).
yeccpars2_405_(__Stack0) ->
@@ -9382,7 +9413,7 @@ yeccpars2_405_(__Stack0) ->
skip_paren ( __3 ) ] }
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9385).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9416).
-compile({inline,yeccpars2_406_/1}).
-file("erl_parse.yrl", 127).
yeccpars2_406_(__Stack0) ->
@@ -9392,7 +9423,7 @@ yeccpars2_406_(__Stack0) ->
__2 , skip_paren ( __3 ) )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9395).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9426).
-compile({inline,yeccpars2_408_/1}).
-file("erl_parse.yrl", 131).
yeccpars2_408_(__Stack0) ->
@@ -9402,7 +9433,7 @@ yeccpars2_408_(__Stack0) ->
__2 , skip_paren ( __3 ) )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9405).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9436).
-compile({inline,yeccpars2_410_/1}).
-file("erl_parse.yrl", 103).
yeccpars2_410_(__Stack0) ->
@@ -9428,7 +9459,7 @@ yeccpars2_415_(__Stack0) ->
build_def ( __1 , __3 )
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9431).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9462).
-compile({inline,yeccpars2_418_/1}).
-file("erl_parse.yrl", 109).
yeccpars2_418_(__Stack0) ->
@@ -9558,7 +9589,7 @@ yeccpars2_446_(__Stack0) ->
[ __1 | __3 ]
end | __Stack].
--file("/ldisk/bjorn/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9561).
+-file("/ldisk/egil/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9592).
-compile({inline,yeccpars2_447_/1}).
-file("erl_parse.yrl", 90).
yeccpars2_447_(__Stack0) ->
@@ -9646,4 +9677,4 @@ yeccpars2_463_(__Stack0) ->
end | __Stack0].
--file("erl_parse.yrl", 1063).
+-file("erl_parse.yrl", 1094).
diff --git a/bootstrap/lib/stdlib/include/erl_bits.hrl b/bootstrap/lib/stdlib/include/erl_bits.hrl
index 54ebe58585..aca213c08c 100644
--- a/bootstrap/lib/stdlib/include/erl_bits.hrl
+++ b/bootstrap/lib/stdlib/include/erl_bits.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/include/erl_compile.hrl b/bootstrap/lib/stdlib/include/erl_compile.hrl
index f779c4382c..2e0d90dfad 100644
--- a/bootstrap/lib/stdlib/include/erl_compile.hrl
+++ b/bootstrap/lib/stdlib/include/erl_compile.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/include/ms_transform.hrl b/bootstrap/lib/stdlib/include/ms_transform.hrl
index 9937d48fef..2b89a4df2f 100644
--- a/bootstrap/lib/stdlib/include/ms_transform.hrl
+++ b/bootstrap/lib/stdlib/include/ms_transform.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/include/qlc.hrl b/bootstrap/lib/stdlib/include/qlc.hrl
index 067fb83060..cccedcbd2c 100644
--- a/bootstrap/lib/stdlib/include/qlc.hrl
+++ b/bootstrap/lib/stdlib/include/qlc.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/bootstrap/lib/stdlib/include/zip.hrl b/bootstrap/lib/stdlib/include/zip.hrl
index 2b5ddc1dfe..6e3ed9c78a 100644
--- a/bootstrap/lib/stdlib/include/zip.hrl
+++ b/bootstrap/lib/stdlib/include/zip.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -19,7 +19,7 @@
-record(zip_file, {
name :: string(), % file name
- info :: #file_info{},
+ info :: file:file_info(),
comment :: string(), % zip file comment
offset :: non_neg_integer(), % offset of file's local header in archive
comp_size :: non_neg_integer() % compressed size
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index f7e5c31910..b64380e817 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2010. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-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
diff --git a/erts/doc/specs/.gitignore b/erts/doc/specs/.gitignore
new file mode 100644
index 0000000000..322eebcb06
--- /dev/null
+++ b/erts/doc/specs/.gitignore
@@ -0,0 +1 @@
+specs_*.xml
diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile
index 6578923fe1..cfa5527474 100644
--- a/erts/doc/src/Makefile
+++ b/erts/doc/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -16,6 +16,9 @@
#
# %CopyrightEnd%
#
+
+SPECS_ESRC = ../../preloaded/src/
+
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
@@ -43,6 +46,12 @@ XML_REF1_FILES = epmd.xml \
run_erl.xml \
start.xml
+XML_REF3_EFILES = \
+ erl_prim_loader.xml \
+ erlang.xml \
+ init.xml \
+ zlib.xml
+
XML_REF3_FILES = \
driver_entry.xml \
erl_nif.xml \
@@ -98,18 +107,26 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+SPECS_FILES = $(XML_REF3_EFILES:%.xml=$(SPECDIR)/specs_%.xml)
+
+TOP_SPECS_FILE = specs.xml
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
XML_FLAGS +=
+KERNEL_SRC=$(ERL_TOP)/lib/kernel/src
+KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include
+SPECS_FLAGS = -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
-docs: pdf html man $(INFO_FILE)
+docs: man pdf html $(INFO_FILE)
$(TOP_PDF_FILE): $(XML_FILES)
@@ -132,8 +149,25 @@ clean:
rm -f $(MAN1DIR)/*
rm -f $(MAN3DIR)/*
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
rm -f errs core *~
+$(SPECDIR)/specs_driver_entry.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module driver_entry
+$(SPECDIR)/specs_erl_nif.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erl_nif
+$(SPECDIR)/specs_erl_set_memory_block.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erl_set_memory_block
+$(SPECDIR)/specs_erl_driver.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erl_driver
+$(SPECDIR)/specs_erts_alloc.xml:
+ escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
+ -o$(dir $@) -module erts_alloc
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
index 2b1ed398ee..9f246c4a6c 100644
--- a/erts/doc/src/driver.xml
+++ b/erts/doc/src/driver.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml
index 8c3c1e5237..3e7005410f 100644
--- a/erts/doc/src/epmd.xml
+++ b/erts/doc/src/epmd.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -120,7 +120,7 @@
<item>
<p>Let this instance of <c>epmd</c> listen only on the
comma-separated list of IP addresses and on the loopback address
- (which is implicitely added to the list if it has not been
+ (which is implicitly added to the list if it has not been
specified). This can also be set using the
<c><![CDATA[ERL_EPMD_ADDRESS]]></c> environment variable, see the
section <seealso marker="#environment_variables">Environment
@@ -243,7 +243,7 @@
<p>This environment variable may be set to a comma-separated
list of IP addresses, in which case the <c>epmd</c> daemon
will listen only on the specified address(es) and on the
- loopback address (which is implicitely added to the list if it
+ loopback address (which is implicitly added to the list if it
has not been specified). The default behaviour is to listen on
all available IP addresses.</p>
</item>
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 514ee5ffaf..02082e57c6 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -1010,7 +1010,7 @@
list of IP addresses, in which case the
<seealso marker="epmd">epmd</seealso> daemon
will listen only on the specified address(es) and on the
- loopback address (which is implicitely added to the list if it
+ loopback address (which is implicitly added to the list if it
has not been specified).</p>
</item>
<tag><c><![CDATA[ERL_EPMD_PORT]]></c></tag>
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 066a2a4b92..2fb03954b6 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml
index ccaa9b725f..fa3daaeecc 100644
--- a/erts/doc/src/erl_prim_loader.xml
+++ b/erts/doc/src/erl_prim_loader.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -55,33 +55,31 @@
<c>-loader_debug</c> are also experimental</p></warning>
</description>
+ <datatypes>
+ <datatype>
+ <name name="host"/>
+ </datatype>
+ </datatypes>
+
<funcs>
<func>
- <name>start(Id, Loader, Hosts) -> {ok, Pid} | {error, What}</name>
+ <name name="start" arity="3"/>
<fsummary>Start the Erlang low level loader</fsummary>
- <type>
- <v>Id = term()</v>
- <v>Loader = atom() | string()</v>
- <v>Hosts = [Host]</v>
- <v>Host = atom()</v>
- <v>Pid = pid()</v>
- <v>What = term()</v>
- </type>
<desc>
<p>Starts the Erlang low level loader. This function is called
by the <c>init</c> process (and module). The <c>init</c>
- process reads the command line flags <c>-id Id</c>,
- <c>-loader Loader</c>, and <c>-hosts Hosts</c>. These are
+ process reads the command line flags <c>-id <anno>Id</anno></c>,
+ <c>-loader <anno>Loader</anno></c>, and <c>-hosts <anno>Hosts</anno></c>. These are
the arguments supplied to the <c>start/3</c> function.</p>
<p>If <c>-loader</c> is not given, the default loader is
<c>efile</c> which tells the system to read from the file
system.</p>
- <p>If <c>-loader</c> is <c>inet</c>, the <c>-id Id</c>,
- <c>-hosts Hosts</c>, and <c>-setcookie Cookie</c> flags must
- also be supplied. <c>Hosts</c> identifies hosts which this
+ <p>If <c>-loader</c> is <c>inet</c>, the <c>-id <anno>Id</anno></c>,
+ <c>-hosts <anno>Hosts</anno></c>, and <c>-setcookie Cookie</c> flags must
+ also be supplied. <c><anno>Hosts</anno></c> identifies hosts which this
node can contact in order to load modules. One Erlang
runtime system with a <c>erl_boot_server</c> process must be
- started on each of hosts given in <c>Hosts</c> in order to
+ 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
@@ -90,35 +88,26 @@
</desc>
</func>
<func>
- <name>get_file(Filename) -> {ok, Bin, FullName} | error</name>
+ <name name="get_file" arity="1"/>
<fsummary>Get a file</fsummary>
- <type>
- <v>Filename = string()</v>
- <v>Bin = binary()</v>
- <v>FullName = string()</v>
- </type>
<desc>
<p>This function fetches a file using the low level loader.
- <c>Filename</c> is either an absolute file name or just the name
+ <c><anno>Filename</anno></c> is either an absolute file name or just the name
of the file, for example <c>"lists.beam"</c>. If an internal
path is set to the loader, this path is used to find the file.
If a user supplied loader is used, the path can be stripped
off if it is obsolete, and the loader does not use a path.
- <c>FullName</c> is the complete name of the fetched file.
- <c>Bin</c> is the contents of the file as a binary.</p>
+ <c><anno>FullName</anno></c> is the complete name of the fetched file.
+ <c><anno>Bin</anno></c> is the contents of the file as a binary.</p>
- <p>The <c>Filename</c> can also be a file in an archive. For example
- <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>
+ <p>The <c><anno>Filename</anno></c> can also be a file in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>.
See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
</desc>
</func>
<func>
- <name>get_path() -> {ok, Path}</name>
+ <name name="get_path" arity="0"/>
<fsummary>Get the path set in the loader</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>Dir = string()</v>
- </type>
<desc>
<p>This function gets the path set in the loader. The path is
set by the <c>init</c> process according to information found
@@ -126,35 +115,26 @@
</desc>
</func>
<func>
- <name>list_dir(Dir) -> {ok, Filenames} | error</name>
+ <name name="list_dir" arity="1"/>
<fsummary>List files in a directory</fsummary>
- <type>
- <v>Dir = name()</v>
- <v>Filenames = [Filename]</v>
- <v>Filename = string()</v>
- </type>
<desc>
<p>Lists all the files in a directory. Returns
- <c>{ok, Filenames}</c> if successful. Otherwise, it returns
- <c>error</c>. <c>Filenames</c> is a list of
+ <c>{ok, <anno>Filenames</anno>}</c> if successful. Otherwise, it returns
+ <c>error</c>. <c><anno>Filenames</anno></c> is a list of
the names of all the files in the directory. The names are
not sorted.</p>
- <p>The <c>Dir</c> can also be a directory in an archive. For example
- <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>
+ <p>The <c><anno>Dir</anno></c> can also be a directory in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>.
See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
</desc>
</func>
<func>
- <name>read_file_info(Filename) -> {ok, FileInfo} | error</name>
+ <name name="read_file_info" arity="1"/>
<fsummary>Get information about a file</fsummary>
- <type>
- <v>Filename = name()</v>
- <v>FileInfo = #file_info{}</v>
- </type>
<desc>
<p>Retrieves information about a file. Returns
- <c>{ok, FileInfo}</c> if successful, otherwise
- <c>error</c>. <c>FileInfo</c> is a record
+ <c>{ok, <anno>FileInfo</anno>}</c> if successful, otherwise
+ <c>error</c>. <c><anno>FileInfo</anno></c> is a record
<c>file_info</c>, defined in the Kernel include file
<c>file.hrl</c>. Include the following directive in the module
from which the function is called:</p>
@@ -162,18 +142,14 @@
-include_lib("kernel/include/file.hrl").</code>
<p>See <seealso marker="kernel:file">file(3)</seealso> for more info about
the record <c>file_info</c>.</p>
- <p>The <c>Filename</c> can also be a file in an archive. For example
- <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>
+ <p>The <c><anno>Filename</anno></c> can also be a file in an archive. For example
+ <c>/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin/mnesia_backup.beam</c>.
See <seealso marker="kernel:code">code(3)</seealso> about archive files.</p>
</desc>
</func>
<func>
- <name>set_path(Path) -> ok</name>
+ <name name="set_path" arity="1"/>
<fsummary>Set the path of the loader</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>Dir = string()</v>
- </type>
<desc>
<p>This function sets the path of the loader if <c>init</c>
interprets a <c>path</c> command in the start script.</p>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index f98e15cb52..ad7a57bd73 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -48,22 +48,24 @@
"Allowed in guard tests".</p>
</description>
- <section>
- <title>DATA TYPES</title>
- <marker id="iolist_definition"></marker>
- <code type="none">
-ext_binary()
- a binary data object,
- structured according to the Erlang external term format
-
-iodata() = iolist() | binary()
+ <datatypes>
+ <datatype>
+ <name><marker id="type-ext_binary">ext_binary()</marker></name>
+ <desc>
+ <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>
+ </datatype>
+ </datatypes>
-iolist() = [char() | binary() | iolist()]
- a binary is allowed as the tail of the list</code>
- </section>
<funcs>
<func>
- <name>abs(Number) -> int() | float()</name>
+ <name>abs(Number) -> integer() | float()</name>
<fsummary>Arithmetical absolute value</fsummary>
<type>
<v>Number = number()</v>
@@ -80,7 +82,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>erlang:adler32(Data) -> int()</name>
+ <name>erlang:adler32(Data) -> integer()</name>
<fsummary>Compute adler32 checksum</fsummary>
<type>
<v>Data = iodata()</v>
@@ -90,10 +92,10 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>erlang:adler32(OldAdler, Data) -> int()</name>
+ <name>erlang:adler32(OldAdler, Data) -> integer()</name>
<fsummary>Compute adler32 checksum</fsummary>
<type>
- <v>OldAdler = int()</v>
+ <v>OldAdler = integer()</v>
<v>Data = iodata()</v>
</type>
<desc>
@@ -112,11 +114,11 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>erlang:adler32_combine(FirstAdler, SecondAdler, SecondSize) -> int()</name>
+ <name>erlang:adler32_combine(FirstAdler, SecondAdler, SecondSize) -> integer()</name>
<fsummary>Combine two adler32 checksums</fsummary>
<type>
- <v>FirstAdler = SecondAdler = int()</v>
- <v>SecondSize = int()</v>
+ <v>FirstAdler = SecondAdler = integer()</v>
+ <v>SecondSize = integer()</v>
</type>
<desc>
<p>Combines two previously computed adler32 checksums.
@@ -155,20 +157,16 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>apply(Fun, Args) -> term() | empty()</name>
+ <name name="apply" arity="2"/>
<fsummary>Apply a function to an argument list</fsummary>
- <type>
- <v>Fun = fun()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
- <p>Call a fun, passing the elements in <c>Args</c> as
+ <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
- <c>Fun(Arg1, Arg2, ... ArgN)</c>.</p>
+ <c><anno>Fun</anno>(Arg1, Arg2, ... ArgN)</c>.</p>
<warning>
- <p>Earlier, <c>Fun</c> could also be given as
+ <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
@@ -177,15 +175,11 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>apply(Module, Function, Args) -> term() | empty()</name>
+ <name name="apply" arity="3"/>
<fsummary>Apply a function to an argument list</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
<p>Returns the result of applying <c>Function</c> in
- <c>Module</c> to <c>Args</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>
<pre>
@@ -198,7 +192,7 @@ iolist() = [char() | binary() | iolist()]
"Erlang"</pre>
<p>Note: If the number of arguments are known at compile-time,
the call is better written as
- <c>Module:Function(Arg1, Arg2, ..., ArgN)</c>.</p>
+ <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
@@ -258,8 +252,8 @@ iolist() = [char() | binary() | iolist()]
<type>
<v>Subject = binary()</v>
<v>PosLen = {Start,Length}</v>
- <v>Start = int()</v>
- <v>Length = int()</v>
+ <v>Start = integer() >= 0</v>
+ <v>Length = integer() >= 0</v>
</type>
<desc>
<p>Extracts the part of the binary described by <c>PosLen</c>.</p>
@@ -291,8 +285,8 @@ iolist() = [char() | binary() | iolist()]
<fsummary>Extracts a part of a binary</fsummary>
<type>
<v>Subject = binary()</v>
- <v>Start = int()</v>
- <v>Length = int()</v>
+ <v>Start = integer() >= 0</v>
+ <v>Length = integer() >= 0</v>
</type>
<desc>
<p>The same as <c>binary_part(Subject, {Pos, Len})</c>.</p>
@@ -390,7 +384,7 @@ iolist() = [char() | binary() | iolist()]
<name>binary_to_term(Binary) -> term()</name>
<fsummary>Decode an Erlang external term format binary</fsummary>
<type>
- <v>Binary = ext_binary()</v>
+ <v>Binary = <seealso marker="#type-ext_binary">ext_binary()</seealso></v>
</type>
<desc>
<p>Returns an Erlang term which is the result of decoding
@@ -411,7 +405,7 @@ iolist() = [char() | binary() | iolist()]
<fsummary>Decode an Erlang external term format binary</fsummary>
<type>
<v>Opts = [safe]</v>
- <v>Binary = ext_binary()</v>
+ <v>Binary = <seealso marker="#type-ext_binary">ext_binary()</seealso></v>
</type>
<desc>
<p>As <c>binary_to_term/1</c>, but takes options that affect decoding
@@ -442,7 +436,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>bit_size(Bitstring) -> int()</name>
+ <name>bit_size(Bitstring) -> integer() >= 0</name>
<fsummary>Return the size of a bitstring</fsummary>
<type>
<v>Bitstring = bitstring()</v>
@@ -461,7 +455,7 @@ iolist() = [char() | binary() | iolist()]
<name>erlang:bump_reductions(Reductions) -> void()</name>
<fsummary>Increment the reduction counter</fsummary>
<type>
- <v>Reductions = int()</v>
+ <v>Reductions = integer() >= 0</v>
</type>
<desc>
<p>This implementation-dependent function increments
@@ -478,7 +472,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>byte_size(Bitstring) -> int()</name>
+ <name>byte_size(Bitstring) -> integer() >= 0</name>
<fsummary>Return the size of a bitstring (or binary)</fsummary>
<type>
<v>Bitstring = bitstring()</v>
@@ -500,7 +494,7 @@ iolist() = [char() | binary() | iolist()]
<fsummary>Cancel a timer</fsummary>
<type>
<v>TimerRef = reference()</v>
- <v>Time = int()</v>
+ <v>Time = integer() >= 0</v>
</type>
<desc>
<p>Cancels a timer, where <c>TimerRef</c> was returned by
@@ -524,7 +518,19 @@ iolist() = [char() | binary() | iolist()]
</func>
<func>
- <name>check_process_code(Pid, Module) -> bool()</name>
+ <name>check_old_code(Module) -> boolean()</name>
+ <fsummary>Check if a module has old code</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns <c>true</c> if the <c>Module</c> has old code,
+ and <c>false</c> otherwise.</p>
+ <p>See also <seealso marker="kernel:code">code(3)</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>check_process_code(Pid, Module) -> boolean()</name>
<fsummary>Check if a process is executing old code for a module</fsummary>
<type>
<v>Pid = pid()</v>
@@ -544,7 +550,7 @@ false</pre>
</desc>
</func>
<func>
- <name>concat_binary(ListOfBinaries)</name>
+ <name name="concat_binary" arity="1"/>
<fsummary>Concatenate a list of binaries (deprecated)</fsummary>
<desc>
<p>Do not use; use
@@ -553,7 +559,7 @@ false</pre>
</desc>
</func>
<func>
- <name>erlang:crc32(Data) -> int()</name>
+ <name>erlang:crc32(Data) -> integer() >= 0</name>
<fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
<type>
<v>Data = iodata()</v>
@@ -563,10 +569,10 @@ false</pre>
</desc>
</func>
<func>
- <name>erlang:crc32(OldCrc, Data) -> int()</name>
+ <name>erlang:crc32(OldCrc, Data) -> integer() >= 0</name>
<fsummary>Compute crc32 (IEEE 802.3) checksum</fsummary>
<type>
- <v>OldCrc = int()</v>
+ <v>OldCrc = integer() >= 0</v>
<v>Data = iodata()</v>
</type>
<desc>
@@ -585,11 +591,11 @@ false</pre>
</desc>
</func>
<func>
- <name>erlang:crc32_combine(FirstCrc, SecondCrc, SecondSize) -> int()</name>
+ <name>erlang:crc32_combine(FirstCrc, SecondCrc, SecondSize) -> integer() >= 0</name>
<fsummary>Combine two crc32 (IEEE 802.3) checksums</fsummary>
<type>
- <v>FirstCrc = SecondCrc = int()</v>
- <v>SecondSize = int()</v>
+ <v>FirstCrc = SecondCrc = integer() >= 0</v>
+ <v>SecondSize = integer() >= 0</v>
</type>
<desc>
<p>Combines two previously computed crc32 checksums.
@@ -609,10 +615,10 @@ false</pre>
</desc>
</func>
<func>
- <name>date() -> {Year, Month, Day}</name>
+ <name>date() -> Date</name>
<fsummary>Current date</fsummary>
<type>
- <v>Year = Month = Day = int()</v>
+ <v>Date = <seealso marker="calendar#type-date">calendar:date()</seealso></v>
</type>
<desc>
<p>Returns the current date as <c>{Year, Month, Day}</c>.</p>
@@ -631,20 +637,20 @@ false</pre>
<v>Options = [Opt]</v>
<v>Packet = binary() | HttpPacket</v>
<v>Rest = binary()</v>
- <v>Length = int() | undefined</v>
+ <v>Length = integer() > 0 | undefined</v>
<v>Reason = term()</v>
<v>&nbsp;Type, Opt -- see below</v>
<v></v>
<v>HttpPacket = HttpRequest | HttpResponse | HttpHeader | http_eoh | HttpError</v>
<v>HttpRequest = {http_request, HttpMethod, HttpUri, HttpVersion}</v>
<v>HttpResponse = {http_response, HttpVersion, integer(), HttpString}</v>
- <v>HttpHeader = {http_header, int(), HttpField, Reserved=term(), Value=HttpString}</v>
+ <v>HttpHeader = {http_header, integer(), HttpField, Reserved=term(), Value=HttpString}</v>
<v>HttpError = {http_error, HttpString}</v>
<v>HttpMethod = HttpMethodAtom | HttpString</v>
<v>HttpMethodAtom = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE'</v>
- <v>HttpUri = '*' | {absoluteURI, http|https, Host=HttpString, Port=int()|undefined, Path=HttpString} |
+ <v>HttpUri = '*' | {absoluteURI, http|https, Host=HttpString, Port=integer()|undefined, Path=HttpString} |
{scheme, Scheme=HttpString, HttpString} | {abs_path, HttpString} | HttpString</v>
- <v>HttpVersion = {Major=int(), Minor=int()}</v>
+ <v>HttpVersion = {Major=integer(), Minor=integer()}</v>
<v>HttpString = string() | binary()</v>
<v>HttpField = HttpFieldAtom | HttpString</v>
<v>HttpFieldAtom = 'Cache-Control' | 'Connection' | 'Date' | 'Pragma' | 'Transfer-Encoding' | 'Upgrade' | 'Via' | 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Authorization' | 'From' | 'Host' | 'If-Modified-Since' | 'If-Match' | 'If-None-Match' | 'If-Range' | 'If-Unmodified-Since' | 'Max-Forwards' | 'Proxy-Authorization' | 'Range' | 'Referer' | 'User-Agent' | 'Age' | 'Location' | 'Proxy-Authenticate' | 'Public' | 'Retry-After' | 'Server' | 'Vary' | 'Warning' | 'Www-Authenticate' | 'Allow' | 'Content-Base' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Md5' | 'Content-Range' | 'Content-Type' | 'Etag' | 'Expires' | 'Last-Modified' | 'Accept-Ranges' | 'Set-Cookie' | 'Set-Cookie2' | 'X-Forwarded-For' | 'Cookie' | 'Keep-Alive' | 'Proxy-Connection'</v>
@@ -719,14 +725,14 @@ false</pre>
</taglist>
<p>The following options are available:</p>
<taglist>
- <tag><c>{packet_size, int()}</c></tag>
+ <tag><c>{packet_size, integer()}</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>
- <tag><c>{line_length, int()}</c></tag>
+ <tag><c>{line_length, integer()}</c></tag>
<item><p>Applies only to line oriented protocols
(<c>line</c>, <c>http</c>). Lines longer than this
will be truncated.</p>
@@ -800,7 +806,7 @@ false</pre>
</desc>
</func>
<func>
- <name>demonitor(MonitorRef, OptionList) -> true|false</name>
+ <name>demonitor(MonitorRef, OptionList) -> boolean()</name>
<fsummary>Stop monitoring</fsummary>
<type>
<v>MonitorRef = reference()</v>
@@ -867,14 +873,11 @@ false</pre>
</desc>
</func>
<func>
- <name>disconnect_node(Node) -> bool() | ignored</name>
+ <name name="disconnect_node" arity="1"/>
<fsummary>Force the disconnection of a node</fsummary>
- <type>
- <v>Node = atom()</v>
- </type>
<desc>
<p>Forces the disconnection of a node. This will appear to
- the node <c>Node</c> as if the local node has crashed. This
+ 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,
otherwise <c>false</c>. If the local node is not alive,
@@ -1069,15 +1072,11 @@ b</pre>
</desc>
</func>
<func>
- <name>erlang:fun_info(Fun) -> [{Item, Info}]</name>
+ <name name="fun_info" arity="1"/>
<fsummary>Information about a fun</fsummary>
- <type>
- <v>Fun = fun()</v>
- <v>Item, Info -- see below</v>
- </type>
<desc>
<p>Returns a list containing information about the fun
- <c>Fun</c>. Each element of the list is a tuple. The order of
+ <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
future release.</p>
<warning>
@@ -1176,7 +1175,7 @@ b</pre>
<p>Returns information about <c>Fun</c> as specified by
<c>Item</c>, in the form <c>{Item,Info}</c>.</p>
<p>For any fun, <c>Item</c> can be any of the atoms
- <c>module</c>, <c>name</c>, <c>arity</c>, or <c>env</c>.</p>
+ <c>module</c>, <c>name</c>, <c>arity</c>, <c>env</c>, or <c>type</c>.</p>
<p>For a local fun, <c>Item</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
@@ -1197,11 +1196,11 @@ b</pre>
</desc>
</func>
<func>
- <name>erlang:function_exported(Module, Function, Arity) -> bool()</name>
+ <name>erlang:function_exported(Module, Function, Arity) -> boolean()</name>
<fsummary>Check if a function is exported and loaded</fsummary>
<type>
<v>Module = Function = atom()</v>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
</type>
<desc>
<p>Returns <c>true</c> if the module <c>Module</c> is loaded
@@ -1229,7 +1228,7 @@ b</pre>
</desc>
</func>
<func>
- <name>garbage_collect(Pid) -> bool()</name>
+ <name>garbage_collect(Pid) -> boolean()</name>
<fsummary>Force an immediate garbage collection of a process</fsummary>
<type>
<v>Pid = pid()</v>
@@ -1276,11 +1275,8 @@ b</pre>
</desc>
</func>
<func>
- <name>erlang:get_cookie() -> Cookie | nocookie</name>
+ <name name="get_cookie" arity="0"/>
<fsummary>Get the magic cookie of the local node</fsummary>
- <type>
- <v>Cookie = atom()</v>
- </type>
<desc>
<p>Returns the magic cookie of the local node, if the node is
alive; otherwise the atom <c>nocookie</c>.</p>
@@ -1311,7 +1307,7 @@ b</pre>
<fsummary>Get the call stack back-trace of the last exception</fsummary>
<type>
<v>Module = Function = atom()</v>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
<v>Args = [term()]</v>
</type>
<desc>
@@ -1379,7 +1375,7 @@ os_prompt%</pre>
<name>halt(Status)</name>
<fsummary>Halt the Erlang runtime system</fsummary>
<type>
- <v>Status = int()>=0 | string()</v>
+ <v>Status = integer() >= 0 | string()</v>
</type>
<desc>
<p><c>Status</c> must be a non-negative integer, or a string.
@@ -1472,7 +1468,7 @@ os_prompt%</pre>
<name>integer_to_list(Integer) -> string()</name>
<fsummary>Text representation of an integer</fsummary>
<type>
- <v>Integer = int()</v>
+ <v>Integer = integer()</v>
</type>
<desc>
<p>Returns a string which corresponds to the text
@@ -1483,15 +1479,11 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>integer_to_list(Integer, Base) -> string()</name>
+ <name name="integer_to_list" arity="2"/>
<fsummary>Text representation of an integer</fsummary>
- <type>
- <v>Integer = int()</v>
- <v>Base = 2..36</v>
- </type>
<desc>
<p>Returns a string which corresponds to the text
- representation of <c>Integer</c> in base <c>Base</c>.</p>
+ representation of <c><anno>Integer</anno></c> in base <c><anno>Base</anno></c>.</p>
<pre>
> <input>integer_to_list(1023, 16).</input>
"3FF"</pre>
@@ -1518,7 +1510,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>iolist_size(Item) -> int()</name>
+ <name>iolist_size(Item) -> integer() >= 0</name>
<fsummary>Size of an iolist</fsummary>
<type>
<v>Item = iolist() | binary()</v>
@@ -1533,7 +1525,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_alive() -> bool()</name>
+ <name>is_alive() -> boolean()</name>
<fsummary>Check whether the local node is alive</fsummary>
<desc>
<p>Returns <c>true</c> if the local node is alive; that is, if
@@ -1542,7 +1534,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_atom(Term) -> bool()</name>
+ <name>is_atom(Term) -> boolean()</name>
<fsummary>Check whether a term is an atom</fsummary>
<type>
<v>Term = term()</v>
@@ -1554,7 +1546,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_binary(Term) -> bool()</name>
+ <name>is_binary(Term) -> boolean()</name>
<fsummary>Check whether a term is a binary</fsummary>
<type>
<v>Term = term()</v>
@@ -1569,7 +1561,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_bitstring(Term) -> bool()</name>
+ <name>is_bitstring(Term) -> boolean()</name>
<fsummary>Check whether a term is a bitstring</fsummary>
<type>
<v>Term = term()</v>
@@ -1582,7 +1574,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_boolean(Term) -> bool()</name>
+ <name>is_boolean(Term) -> boolean()</name>
<fsummary>Check whether a term is a boolean</fsummary>
<type>
<v>Term = term()</v>
@@ -1595,11 +1587,11 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:is_builtin(Module, Function, Arity) -> bool()</name>
+ <name>erlang:is_builtin(Module, Function, Arity) -> boolean()</name>
<fsummary>Check if a function is a BIF implemented in C</fsummary>
<type>
<v>Module = Function = atom()</v>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
</type>
<desc>
<p>Returns <c>true</c> if <c>Module:Function/Arity</c> is
@@ -1608,7 +1600,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_float(Term) -> bool()</name>
+ <name>is_float(Term) -> boolean()</name>
<fsummary>Check whether a term is a float</fsummary>
<type>
<v>Term = term()</v>
@@ -1620,7 +1612,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_function(Term) -> bool()</name>
+ <name>is_function(Term) -> boolean()</name>
<fsummary>Check whether a term is a fun</fsummary>
<type>
<v>Term = term()</v>
@@ -1632,11 +1624,11 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_function(Term, Arity) -> bool()</name>
+ <name>is_function(Term, Arity) -> boolean()</name>
<fsummary>Check whether a term is a fun with a given arity</fsummary>
<type>
<v>Term = term()</v>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
</type>
<desc>
<p>Returns <c>true</c> if <c>Term</c> is a fun that can be
@@ -1653,7 +1645,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_integer(Term) -> bool()</name>
+ <name>is_integer(Term) -> boolean()</name>
<fsummary>Check whether a term is an integer</fsummary>
<type>
<v>Term = term()</v>
@@ -1665,7 +1657,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_list(Term) -> bool()</name>
+ <name>is_list(Term) -> boolean()</name>
<fsummary>Check whether a term is a list</fsummary>
<type>
<v>Term = term()</v>
@@ -1677,7 +1669,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_number(Term) -> bool()</name>
+ <name>is_number(Term) -> boolean()</name>
<fsummary>Check whether a term is a number</fsummary>
<type>
<v>Term = term()</v>
@@ -1689,7 +1681,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_pid(Term) -> bool()</name>
+ <name>is_pid(Term) -> boolean()</name>
<fsummary>Check whether a term is a pid</fsummary>
<type>
<v>Term = term()</v>
@@ -1701,7 +1693,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_port(Term) -> bool()</name>
+ <name>is_port(Term) -> boolean()</name>
<fsummary>Check whether a term is a port</fsummary>
<type>
<v>Term = term()</v>
@@ -1713,7 +1705,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_process_alive(Pid) -> bool()</name>
+ <name>is_process_alive(Pid) -> boolean()</name>
<fsummary>Check whether a process is alive</fsummary>
<type>
<v>Pid = pid()</v>
@@ -1728,7 +1720,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_record(Term, RecordTag) -> bool()</name>
+ <name>is_record(Term, RecordTag) -> boolean()</name>
<fsummary>Check whether a term appears to be a record</fsummary>
<type>
<v>Term = term()</v>
@@ -1751,12 +1743,12 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_record(Term, RecordTag, Size) -> bool()</name>
+ <name>is_record(Term, RecordTag, Size) -> boolean()</name>
<fsummary>Check whether a term appears to be a record</fsummary>
<type>
<v>Term = term()</v>
<v>RecordTag = atom()</v>
- <v>Size = int()</v>
+ <v>Size = integer()</v>
</type>
<desc>
<p><c>RecordTag</c> must be an atom. Returns <c>true</c> if
@@ -1771,7 +1763,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_reference(Term) -> bool()</name>
+ <name>is_reference(Term) -> boolean()</name>
<fsummary>Check whether a term is a reference</fsummary>
<type>
<v>Term = term()</v>
@@ -1783,7 +1775,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>is_tuple(Term) -> bool()</name>
+ <name>is_tuple(Term) -> boolean()</name>
<fsummary>Check whether a term is a tuple</fsummary>
<type>
<v>Term = term()</v>
@@ -1795,7 +1787,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>length(List) -> int()</name>
+ <name>length(List) -> integer() >= 0</name>
<fsummary>Length of a list</fsummary>
<type>
<v>List = [term()]</v>
@@ -1916,7 +1908,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>list_to_integer(String) -> int()</name>
+ <name>list_to_integer(String) -> integer()</name>
<fsummary>Convert from text representation to an integer</fsummary>
<type>
<v>String = string()</v>
@@ -1932,19 +1924,15 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>list_to_integer(String, Base) -> int()</name>
+ <name name="list_to_integer" arity="2"/>
<fsummary>Convert from text representation to an integer</fsummary>
- <type>
- <v>String = string()</v>
- <v>Base = 2..36</v>
- </type>
<desc>
<p>Returns an integer whose text representation in base
- <c>Base</c> is <c>String</c>.</p>
+ <c><anno>Base</anno></c> is <c><anno>String</anno></c>.</p>
<pre>
> <input>list_to_integer("3FF", 16).</input>
1023</pre>
- <p>Failure: <c>badarg</c> if <c>String</c> contains a bad
+ <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
representation of an integer.</p>
</desc>
</func>
@@ -2095,12 +2083,10 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:localtime() -> {Date, Time}</name>
+ <name>erlang:localtime() -> DateTime</name>
<fsummary>Current local date and time</fsummary>
<type>
- <v>Date = {Year, Month, Day}</v>
- <v>Time = {Hour, Minute, Second}</v>
- <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ <v>DateTime = <seealso marker="calendar#type-datetime">calendar:datetime()</seealso></v>
</type>
<desc>
<p>Returns the current local date and time
@@ -2113,17 +2099,12 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:localtime_to_universaltime({Date1, Time1}) -> {Date2, Time2}</name>
+ <name name="localtime_to_universaltime" arity="1"/>
<fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
- <type>
- <v>Date1 = Date2 = {Year, Month, Day}</v>
- <v>Time1 = Time2 = {Hour, Minute, Second}</v>
- <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
- </type>
<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>{Date1, Time1}</c> is returned.</p>
+ no conversion is done and <c>{<anno>Date1</anno>, <anno>Time1</anno>}</c> is returned.</p>
<pre>
> <input>erlang:localtime_to_universaltime({{1996,11,6},{14,45,17}}).</input>
{{1996,11,6},{13,45,17}}</pre>
@@ -2135,9 +2116,8 @@ os_prompt%</pre>
<name>erlang:localtime_to_universaltime({Date1, Time1}, IsDst) -> {Date2, Time2}</name>
<fsummary>Convert from local to Universal Time Coordinated (UTC) date and time</fsummary>
<type>
- <v>Date1 = Date2 = {Year, Month, Day}</v>
- <v>Time1 = Time2 = {Hour, Minute, Second}</v>
- <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ <v>Date1 = Date2 = <seealso marker="calendar#type-date">calendar:date()</seealso></v>
+ <v>Time1 = Time2 = <seealso marker="calendar#type-time">calendar:time()</seealso></v>
<v>IsDst = true | false | undefined</v>
</type>
<desc>
@@ -2177,7 +2157,7 @@ os_prompt%</pre>
<name>erlang:make_tuple(Arity, InitialValue) -> tuple()</name>
<fsummary>Create a new tuple of a given arity</fsummary>
<type>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
<v>InitialValue = term()</v>
</type>
<desc>
@@ -2192,7 +2172,7 @@ os_prompt%</pre>
<name>erlang:make_tuple(Arity, Default, InitList) -> tuple()</name>
<fsummary>Create a new tuple with given arity and contents</fsummary>
<type>
- <v>Arity = int()</v>
+ <v>Arity = arity()</v>
<v>Default = term()</v>
<v>InitList = [{Position,term()}]</v>
<v>Position = integer()</v>
@@ -2211,14 +2191,11 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>max(Term1, Term2) -> Maximum</name>
+ <name name="max" arity="2"/>
<fsummary>Return the largest of two term</fsummary>
- <type>
- <v>Term1 = Term2 = Maximum = term()</v>
- </type>
<desc>
- <p>Return the largest of <c>Term1</c> and <c>Term2</c>;
- if the terms compares equal, <c>Term1</c> will be returned.</p>
+ <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>
</desc>
</func>
<func>
@@ -2468,18 +2445,15 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>min(Term1, Term2) -> Minimum</name>
+ <name name="min" arity="2"/>
<fsummary>Return the smallest of two term</fsummary>
- <type>
- <v>Term1 = Term2 = Minimum = term()</v>
- </type>
<desc>
- <p>Return the smallest of <c>Term1</c> and <c>Term2</c>;
- if the terms compare equal, <c>Term1</c> will be returned.</p>
+ <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>
</desc>
</func>
<func>
- <name>module_loaded(Module) -> bool()</name>
+ <name>module_loaded(Module) -> boolean()</name>
<fsummary>Check if a module is loaded</fsummary>
<type>
<v>Module = atom()</v>
@@ -2602,7 +2576,7 @@ os_prompt%</pre>
<fsummary>Monitor the status of a node</fsummary>
<type>
<v>Node = node()</v>
- <v>Flag = bool()</v>
+ <v>Flag = boolean()</v>
</type>
<desc>
<p>Monitors the status of the node <c>Node</c>. If <c>Flag</c>
@@ -2628,7 +2602,7 @@ os_prompt%</pre>
<fsummary>Monitor the status of a node</fsummary>
<type>
<v>Node = node()</v>
- <v>Flag = bool()</v>
+ <v>Flag = boolean()</v>
<v>Options = [Option]</v>
<v>Option = allow_passive_connect</v>
</type>
@@ -2711,11 +2685,8 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>nodes() -> Nodes</name>
+ <name name="nodes" arity="0"/>
<fsummary>All visible nodes in the system</fsummary>
- <type>
- <v>Nodes = [node()]</v>
- </type>
<desc>
<p>Returns a list of all visible nodes in the system, excluding
the local node. Same as <c>nodes(visible)</c>.</p>
@@ -2765,11 +2736,12 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>now() -> {MegaSecs, Secs, MicroSecs}</name>
- <fsummary>Elapsed time since 00:00 GMT</fsummary>
+ <name>now() -> timestamp()</name>
<type>
- <v>MegaSecs = Secs = MicroSecs = int()</v>
+ <v>timestamp() = {MegaSecs, Secs, MicroSecs}</v>
+ <v>MegaSecs = Secs = MicroSecs = integer() >= 0</v>
</type>
+ <fsummary>Elapsed time since 00:00 GMT</fsummary>
<desc>
<p>Returns the tuple <c>{MegaSecs, Secs, MicroSecs}</c> which is
the elapsed time since 00:00 GMT, January 1, 1970 (zero hour)
@@ -2792,12 +2764,12 @@ os_prompt%</pre>
<v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, FileName} | {fd, In, Out}</v>
<v>&nbsp;Command = string()</v>
<v>&nbsp;FileName = [ FileNameChar ] | binary()</v>
- <v>&nbsp;FileNameChar = int() (1..255 or any Unicode codepoint, see description)</v>
- <v>&nbsp;In = Out = int()</v>
+ <v>&nbsp;FileNameChar = integer() (1..255 or any Unicode codepoint, see description)</v>
+ <v>&nbsp;In = Out = integer()</v>
<v>PortSettings = [Opt]</v>
<v>&nbsp;Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v>
<v>&nbsp;&nbsp;N = 1 | 2 | 4</v>
- <v>&nbsp;&nbsp;L = int()</v>
+ <v>&nbsp;&nbsp;L = integer()</v>
<v>&nbsp;&nbsp;Dir = string()</v>
<v>&nbsp;&nbsp;ArgString = [ FileNameChar ] | binary()</v>
<v>&nbsp;&nbsp;Env = [{Name, Val}]</v>
@@ -3283,7 +3255,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>port_command(Port, Data, OptionList) -> true|false</name>
+ <name>port_command(Port, Data, OptionList) -> boolean()</name>
<fsummary>Send data to a port</fsummary>
<type>
<v>Port = port() | atom()</v>
@@ -3399,7 +3371,7 @@ os_prompt%</pre>
<fsummary>Perform a synchronous control operation on a port</fsummary>
<type>
<v>Port = port() | atom()</v>
- <v>Operation = int()</v>
+ <v>Operation = integer()</v>
<v>Data = Res = iodata()</v>
</type>
<desc>
@@ -3423,7 +3395,7 @@ os_prompt%</pre>
<fsummary>Synchronous call to a port with term data</fsummary>
<type>
<v>Port = port() | atom()</v>
- <v>Operation = int()</v>
+ <v>Operation = integer()</v>
<v>Data = term()</v>
</type>
<desc>
@@ -4109,7 +4081,7 @@ os_prompt%</pre>
<v>Reason = term()</v>
<v>Stacktrace = [{Module, Function, Arity | Args} | {Fun, Args}]</v>
<v>&nbsp;Module = Function = atom()</v>
- <v>&nbsp;Arity = int()</v>
+ <v>&nbsp;Arity = arity()</v>
<v>&nbsp;Args = [term()]</v>
<v>&nbsp;Fun = [fun()]</v>
</type>
@@ -4146,7 +4118,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:read_timer(TimerRef) -> int() | false</name>
+ <name>erlang:read_timer(TimerRef) -> integer() >= 0 | false</name>
<fsummary>Number of milliseconds remaining for a timer</fsummary>
<type>
<v>TimerRef = reference()</v>
@@ -4262,7 +4234,7 @@ true</pre>
</desc>
</func>
<func>
- <name>round(Number) -> int()</name>
+ <name>round(Number) -> integer()</name>
<fsummary>Return an integer by rounding a number</fsummary>
<type>
<v>Number = number()</v>
@@ -4346,7 +4318,7 @@ true</pre>
<name>erlang:send_after(Time, Dest, Msg) -> TimerRef</name>
<fsummary>Start a timer</fsummary>
<type>
- <v>Time = int()</v>
+ <v>Time = integer() >= 0</v>
<v>&nbsp;0 &lt;= Time &lt;= 4294967295</v>
<v>Dest = pid() | RegName </v>
<v>&nbsp;LocalPid = pid() (of a process, alive or dead, on the local node)</v>
@@ -4375,17 +4347,12 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:send_nosuspend(Dest, Msg) -> bool()</name>
+ <name name="send_nosuspend" arity="2"/>
<fsummary>Try to send a message without ever blocking</fsummary>
- <type>
- <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
- <v>&nbsp;RegName = atom()</v>
- <v>&nbsp;Node = node()</v>
- <v>Msg = term()</v>
- </type>
+ <type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(Dest, Msg, [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
@@ -4393,7 +4360,7 @@ true</pre>
(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>Dest</c> refers to a local port that
+ <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
returns <c>true</c>.</p>
@@ -4426,18 +4393,12 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:send_nosuspend(Dest, Msg, Options) -> bool()</name>
+ <name name="send_nosuspend" arity="3"/>
<fsummary>Try to send a message without ever blocking</fsummary>
- <type>
- <v>Dest = pid() | port() | RegName | {RegName, Node}</v>
- <v>&nbsp;RegName = atom()</v>
- <v>&nbsp;Node = node()</v>
- <v>Msg = term()</v>
- <v>Option = noconnect</v>
- </type>
+ <type name="dst"/>
<desc>
<p>The same as
- <seealso marker="#send/3">erlang:send(Dest, Msg, [nosuspend | Options])</seealso>,
+ <seealso marker="#send/3">erlang:send(<anno>Dest</anno>, <anno>Msg</anno>, [nosuspend | <anno>Options</anno>])</seealso>,
but with boolean return value.</p>
<p>This function behaves like
<seealso marker="#send_nosuspend/2">erlang:send_nosuspend/2)</seealso>,
@@ -4462,17 +4423,13 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:set_cookie(Node, Cookie) -> true</name>
+ <name name="set_cookie" arity="2"/>
<fsummary>Set the magic cookie of a node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Cookie = atom()</v>
- </type>
<desc>
- <p>Sets the magic cookie of <c>Node</c> to the atom
- <c>Cookie</c>. If <c>Node</c> is the local node, the function
+ <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
also sets the cookie of all other unknown nodes to
- <c>Cookie</c> (see
+ <c><anno>Cookie</anno></c> (see
<seealso marker="doc/reference_manual:distributed">Distributed Erlang</seealso> in the Erlang Reference Manual).</p>
<p>Failure: <c>function_clause</c> if the local node is not
alive.</p>
@@ -4497,7 +4454,7 @@ true</pre>
</desc>
</func>
<func>
- <name>size(Item) -> int()</name>
+ <name>size(Item) -> integer() >= 0</name>
<fsummary>Size of a tuple or binary</fsummary>
<type>
<v>Item = tuple() | binary()</v>
@@ -4512,28 +4469,21 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn(Fun) -> pid()</name>
+ <name name="spawn" arity="1"/>
<fsummary>Create a new process with a fun as entry point</fsummary>
- <type>
- <v>Fun = fun()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list <c>[]</c>. Otherwise works
+ 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>spawn(Node, Fun) -> pid()</name>
+ <name name="spawn" arity="2"/>
<fsummary>Create a new process with a fun as entry point on a given node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Fun = fun()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list <c>[]</c> on <c>Node</c>. If
- <c>Node</c> does not exist, a useless pid is returned.
+ 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>
@@ -4564,47 +4514,35 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn(Node, Module, Function, Args) -> pid()</name>
+ <name name="spawn" arity="4"/>
<fsummary>Create a new process with a function as entry point on a given node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. If
- <c>Node</c> does not exists, a useless pid is returned.
+ 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.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
<func>
- <name>spawn_link(Fun) -> pid()</name>
+ <name name="spawn_link" arity="1"/>
<fsummary>Create and link to a new process with a fun as entry point</fsummary>
- <type>
- <v>Fun = fun()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list []. A link is created between
+ of <c><anno>Fun</anno></c> to the empty list []. 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>spawn_link(Node, Fun) -> pid()</name>
+ <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>
- <type>
- <v>Node = node()</v>
- <v>Fun = fun()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list [] on <c>Node</c>. A link is
+ of <c><anno>Fun</anno></c> to the empty list [] on <c><anno>Node</anno></c>. A link is
created between the calling process and the new process,
- atomically. If <c>Node</c> does not exist, a useless pid is
+ 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>
@@ -4626,47 +4564,35 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn_link(Node, Module, Function, Args) -> pid()</name>
+ <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>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. A
+ of <c><anno>Module</anno>:<anno>Function</anno></c> to <c><anno>Args</anno></c> on <c>Node</c>. A
link is created between the calling process and the new
- process, atomically. If <c>Node</c> does not exist, a useless
+ 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>
</desc>
</func>
<func>
- <name>spawn_monitor(Fun) -> {pid(),reference()}</name>
+ <name name="spawn_monitor" arity="1"/>
<fsummary>Create and monitor a new process with a fun as entry point</fsummary>
- <type>
- <v>Fun = fun()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list [] and reference for a monitor
+ of <c><anno>Fun</anno></c> to the empty list [] and reference for a monitor
created to the new process.
Otherwise works like
<seealso marker="#spawn/3">spawn/3</seealso>.</p>
</desc>
</func>
<func>
- <name>spawn_monitor(Module, Function, Args) -> {pid(),reference()}</name>
+ <name name="spawn_monitor" arity="3"/>
<fsummary>Create and monitor a new process with a function as entry point</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- </type>
<desc>
<p>A new process is started by the application
- of <c>Module:Function</c> to <c>Args</c>, and the process is
+ 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
@@ -4674,19 +4600,11 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn_opt(Fun, [Option]) -> pid() | {pid(),reference()}</name>
+ <name name="spawn_opt" arity="2"/>
<fsummary>Create a new process with a fun as entry point</fsummary>
- <type>
- <v>Fun = fun()</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
- <v>&nbsp;Level = low | normal | high</v>
- <v>&nbsp;Number = int()</v>
- <v>&nbsp;Size = int()</v>
- <v>&nbsp;VSize = int()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list <c>[]</c>. Otherwise
+ 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
@@ -4695,37 +4613,19 @@ true</pre>
</desc>
</func>
<func>
- <name>spawn_opt(Node, Fun, [Option]) -> pid()</name>
+ <name name="spawn_opt" arity="3"/>
<fsummary>Create a new process with a fun as entry point on a given node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Fun = fun()</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
- <v>&nbsp;Level = low | normal | high</v>
- <v>&nbsp;Number = int()</v>
- <v>&nbsp;Size = int()</v>
- <v>&nbsp;VSize = int()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Fun</c> to the empty list <c>[]</c> on <c>Node</c>. If
- <c>Node</c> does not exist, a useless pid is returned.
+ 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>spawn_opt(Module, Function, Args, [Option]) -> pid() | {pid(),reference()}</name>
+ <name name="spawn_opt" arity="4"/>
<fsummary>Create a new process with a function as entry point</fsummary>
- <type>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
- <v>&nbsp;Level = low | normal | high</v>
- <v>&nbsp;Number = int()</v>
- <v>&nbsp;Size = int()</v>
- <v>&nbsp;VSize = int()</v>
- </type>
<desc>
<p>Works exactly like
<seealso marker="#spawn/3">spawn/3</seealso>, except that an
@@ -4744,17 +4644,17 @@ true</pre>
<p>Monitor the new process (just like
<seealso marker="#monitor/2">monitor/2</seealso> does).</p>
</item>
- <tag><c>{priority, Level}</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, Level)</seealso> in the start function of the new process,
+ <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>
</item>
- <tag><c>{fullsweep_after, Number}</c></tag>
+ <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
@@ -4776,18 +4676,18 @@ true</pre>
<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>Number</c> to zero.) Secondly, a process that
+ (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>Number</c> to a suitable value such as 10 or 20.
+ <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>Number</c> to zero. (The value may be set
+ 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>
</item>
- <tag><c>{min_heap_size, Size}</c></tag>
+ <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
@@ -4802,9 +4702,9 @@ true</pre>
slow down the system due to worse data locality.
Therefore, it is recommended to use this option only for
fine-tuning an application and to measure the execution
- time with various <c>Size</c> values.</p>
+ time with various <c><anno>Size</anno></c> values.</p>
</item>
- <tag><c>{min_bin_vheap_size, VSize}</c></tag>
+ <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
@@ -4818,29 +4718,19 @@ true</pre>
Setting too high value, however, might waste memory.
Therefore, it is recommended to use this option only for
fine-tuning an application and to measure the execution
- time with various <c>VSize</c> values.</p>
+ time with various <c><anno>VSize</anno></c> values.</p>
</item>
</taglist>
</desc>
</func>
<func>
- <name>spawn_opt(Node, Module, Function, Args, [Option]) -> pid()</name>
+ <name name="spawn_opt" arity="5"/>
<fsummary>Create a new process with a function as entry point on a given node</fsummary>
- <type>
- <v>Node = node()</v>
- <v>Module = Function = atom()</v>
- <v>Args = [term()]</v>
- <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v>
- <v>&nbsp;Level = low | normal | high</v>
- <v>&nbsp;Number = int()</v>
- <v>&nbsp;Size = int()</v>
- <v>&nbsp;VSize = int()</v>
- </type>
<desc>
<p>Returns the pid of a new process started by the application
- of <c>Module:Function</c> to <c>Args</c> on <c>Node</c>. If
- <c>Node</c> does not exist, a useless pid is returned.
+ 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 exist, a useless pid is returned.
Otherwise works like
<seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p>
</desc>
@@ -4874,7 +4764,7 @@ true</pre>
<name>erlang:start_timer(Time, Dest, Msg) -> TimerRef</name>
<fsummary>Start a timer</fsummary>
<type>
- <v>Time = int()</v>
+ <v>Time = integer() >= 0</v>
<v>&nbsp;0 &lt;= Time &lt;= 4294967295</v>
<v>Dest = LocalPid | RegName </v>
<v>&nbsp;LocalPid = pid() (of a process, alive or dead, on the local node)</v>
@@ -4983,7 +4873,7 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:suspend_process(Suspendee, OptList) -> true | false</name>
+ <name>erlang:suspend_process(Suspendee, OptList) -> boolean()</name>
<fsummary>Suspend a process</fsummary>
<type>
<v>Suspendee = pid()</v>
@@ -5083,15 +4973,12 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:suspend_process(Suspendee) -> true</name>
+ <name name="suspend_process" arity="1"/>
<fsummary>Suspend a process</fsummary>
- <type>
- <v>Suspendee = pid()</v>
- </type>
<desc>
- <p>Suspends the process identified by <c>Suspendee</c>. The
+ <p>Suspends the process identified by <c><anno>Suspendee</anno></c>. The
same as calling
- <seealso marker="#suspend_process/2">erlang:suspend_process(Suspendee, [])</seealso>. For more information see the documentation of <seealso marker="#suspend_process/2">erlang:suspend_process/2</seealso>.
+ <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>
<warning>
<p>This BIF is intended for debugging only.</p>
@@ -5416,7 +5303,7 @@ true</pre>
<p>Types:</p>
<list type="bulleted">
<item><c>Allocator = undefined | glibc</c></item>
- <item><c>Version = [int()]</c></item>
+ <item><c>Version = [integer()]</c></item>
<item><c>Features = [atom()]</c></item>
<item><c>Settings = [{Subsystem, [{Parameter, Value}]}]</c></item>
<item><c>Subsystem = atom()</c></item>
@@ -5682,7 +5569,7 @@ true</pre>
</item>
<tag><c>fullsweep_after</c></tag>
<item>
- <p>Returns <c>{fullsweep_after, int()}</c> which is the
+ <p>Returns <c>{fullsweep_after, integer()}</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>
@@ -6050,7 +5937,7 @@ true</pre>
<v>&nbsp;MonitorPid = pid()</v>
<v>&nbsp;Options = [Option]</v>
<v>&nbsp;&nbsp;Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v>
- <v>&nbsp;&nbsp;&nbsp;Time = Size = int()</v>
+ <v>&nbsp;&nbsp;&nbsp;Time = Size = integer()</v>
</type>
<desc>
<p>Returns the current system monitoring settings set by
@@ -6084,7 +5971,7 @@ true</pre>
<type>
<v>MonitorPid = pid()</v>
<v>Option = {long_gc, Time} | {large_heap, Size} | busy_port | busy_dist_port</v>
- <v>&nbsp;Time = Size = int()</v>
+ <v>&nbsp;Time = Size = integer()</v>
<v>MonSettings = {OldMonitorPid, [Option]}</v>
<v>&nbsp;OldMonitorPid = pid()</v>
</type>
@@ -6314,7 +6201,7 @@ true</pre>
<name>time() -> {Hour, Minute, Second}</name>
<fsummary>Current time</fsummary>
<type>
- <v>Hour = Minute = Second = int()</v>
+ <v>Hour = Minute = Second = integer() >= 0</v>
</type>
<desc>
<p>Returns the current time as <c>{Hour, Minute, Second}</c>.</p>
@@ -6342,11 +6229,11 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:trace(PidSpec, How, FlagList) -> int()</name>
+ <name>erlang:trace(PidSpec, How, FlagList) -> integer() >= 0</name>
<fsummary>Set trace flags for a process or processes</fsummary>
<type>
<v>PidSpec = pid() | existing | new | all</v>
- <v>How = bool()</v>
+ <v>How = boolean()</v>
<v>FlagList = [Flag]</v>
<v>&nbsp;Flag -- see below</v>
</type>
@@ -6747,7 +6634,7 @@ true</pre>
<type>
<v>PidOrFunc = pid() | new | {Module, Function, Arity} | on_load</v>
<v>&nbsp;Module = Function = atom()</v>
- <v>&nbsp;Arity = int()</v>
+ <v>&nbsp;Arity = arity()</v>
<v>Item, Res -- see below</v>
</type>
<desc>
@@ -6850,7 +6737,7 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:trace_pattern(MFA, MatchSpec) -> int()</name>
+ <name>erlang:trace_pattern(MFA, MatchSpec) -> integer() >= 0</name>
<fsummary>Set trace patterns for global call tracing</fsummary>
<desc>
<p>The same as
@@ -6859,7 +6746,7 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:trace_pattern(MFA, MatchSpec, FlagList) -> int()</name>
+ <name>erlang:trace_pattern(MFA, MatchSpec, FlagList) -> integer() >= 0</name>
<fsummary>Set trace patterns for tracing of function calls</fsummary>
<type>
<v>MFA, MatchSpec, FlagList -- see below</v>
@@ -7039,7 +6926,7 @@ true</pre>
</desc>
</func>
<func>
- <name>trunc(Number) -> int()</name>
+ <name>trunc(Number) -> integer()</name>
<fsummary>Return an integer by the truncating a number</fsummary>
<type>
<v>Number = number()</v>
@@ -7053,7 +6940,7 @@ true</pre>
</desc>
</func>
<func>
- <name>tuple_size(Tuple) -> int()</name>
+ <name>tuple_size(Tuple) -> integer() >= 0</name>
<fsummary>Return the size of a tuple</fsummary>
<type>
<v>Tuple = tuple()</v>
@@ -7081,12 +6968,10 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:universaltime() -> {Date, Time}</name>
+ <name>erlang:universaltime() -> DateTime</name>
<fsummary>Current date and time according to Universal Time Coordinated (UTC)</fsummary>
<type>
- <v>Date = {Year, Month, Day}</v>
- <v>Time = {Hour, Minute, Second}</v>
- <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ <v>DateTime = <seealso marker="calendar#type-datetime">calendar:datetime()</seealso></v>
</type>
<desc>
<p>Returns the current date and time according to Universal
@@ -7104,9 +6989,8 @@ true</pre>
<name>erlang:universaltime_to_localtime({Date1, Time1}) -> {Date2, Time2}</name>
<fsummary>Convert from Universal Time Coordinated (UTC) to local date and time</fsummary>
<type>
- <v>Date1 = Date2 = {Year, Month, Day}</v>
- <v>Time1 = Time2 = {Hour, Minute, Second}</v>
- <v>&nbsp;Year = Month = Day = Hour = Minute = Second = int()</v>
+ <v>Date1 = Date2 = <seealso marker="calendar#type-date">calendar:date()</seealso></v>
+ <v>Time1 = Time2 = <seealso marker="calendar#type-time">calendar:time()</seealso></v>
</type>
<desc>
<p>Converts Universal Time Coordinated (UTC) date and time to
@@ -7193,7 +7077,7 @@ true</pre>
</desc>
</func>
<func>
- <name>erlang:yield() -> true</name>
+ <name name="yield" arity="0"/>
<fsummary>Let other processes get a chance to execute</fsummary>
<desc>
<p>Voluntarily let other processes (if any) get a chance to
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 51a4a2bca0..90347824d5 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -78,14 +78,20 @@
segments are allocated, cached segments are used if possible
instead of creating new segments. This in order to reduce
the number of system calls made.</item>
+ <tag><c>sbmbc_alloc</c></tag>
+ <item>Allocator used by other allocators for allocation of carriers
+ where only small blocks are placed. Currently this allocator is
+ disabled by default.</item>
</taglist>
<p><c>sys_alloc</c> and <c>fix_alloc</c> are always enabled and
cannot be disabled. <c>mseg_alloc</c> is always enabled if it is
available and an allocator that uses it is enabled. All other
allocators can be <seealso marker="#M_e">enabled or disabled</seealso>.
By default all allocators are enabled.
- When an allocator is disabled, <c>sys_alloc</c>
- is used instead of the disabled allocator.</p>
+ When an allocator is disabled, <c>sys_alloc</c> is used instead of
+ the disabled allocator. <c>sbmbc_alloc</c> is an exception. If
+ <c>sbmbc_alloc</c> is disabled, other allocators will not handle
+ small blocks in separate carriers.</p>
<p>The main idea with the <c>erts_alloc</c> library is to separate
memory blocks that are used differently into different memory
areas, and by this achieving less memory fragmentation. By
@@ -103,15 +109,20 @@
following does <em>not</em> apply to them.</p>
<p>An allocator manages multiple areas, called carriers, in which
memory blocks are placed. A carrier is either placed in a
- separate memory segment (allocated via <c>mseg_alloc</c>) or in
- the heap segment (allocated via <c>sys_alloc</c>). Multiblock
+ separate memory segment (allocated via <c>mseg_alloc</c>), in
+ the heap segment (allocated via <c>sys_alloc</c>), or inside
+ another carrier (in case it is a carrier created by
+ <c>sbmbc_alloc</c>). Multiblock
carriers are used for storage of several blocks. Singleblock
carriers are used for storage of one block. Blocks that are
larger than the value of the singleblock carrier threshold
(<seealso marker="#M_sbct">sbct</seealso>) parameter are placed
- in singleblock carriers. Blocks smaller than the value of the
- <c>sbct</c> parameter are placed in multiblock
- carriers. Normally an allocator creates a "main multiblock
+ in singleblock carriers. Blocks that are smaller than the value
+ of the <c>sbct</c> parameter are placed in multiblock
+ carriers. Blocks that are smaller than the small block multiblock
+ carrier threshold (<seealso marker="#M_sbmbct">sbmbct</seealso>)
+ will be placed in multiblock carriers only used for small blocks.
+ Normally an allocator creates a "main multiblock
carrier". Main multiblock carriers are never deallocated. The
size of the main multiblock carrier is determined by the value
of the <seealso marker="#M_mmbcs">mmbcs</seealso> parameter.</p>
@@ -133,8 +144,11 @@
<c>sbct</c> parameter should be larger than the value of the
<c>lmbcs</c> parameter, the allocator may have to create
multiblock carriers that are larger than the value of the
- <c>lmbcs</c> parameter, though. Singleblock carriers allocated
- via <c>mseg_alloc</c> are sized to whole pages.</p>
+ <c>lmbcs</c> parameter, though. The size of multiblock carriers
+ for small blocks is determined by the small block multiblock
+ carrier size (<seealso marker="#M_sbmbcs">sbmbcs</seealso>).
+ Singleblock carriers allocated via <c>mseg_alloc</c> are sized
+ to whole pages.</p>
<p>Sizes of carriers allocated via <c>sys_alloc</c> are
decided based on the value of the <c>sys_alloc</c> carrier size
(<seealso marker="#Muycs">ycs</seealso>) parameter. The size of
@@ -166,6 +180,14 @@
used. The time complexity is proportional to log N, where
N is the number of free blocks.</p>
</item>
+ <tag>Address order first fit</tag>
+ <item>
+ <p>Strategy: Find the block with the lowest address that satisfies the
+ requested block size.</p>
+ <p>Implementation: A balanced binary search tree is
+ used. The time complexity is proportional to log N, where
+ N is the number of free blocks.</p>
+ </item>
<tag>Good fit</tag>
<item>
<p>Strategy: Try to find the best fit, but settle for the best fit
@@ -194,6 +216,11 @@
</taglist>
</section>
+ <note><p>
+ Currently only allocators using the best fit and the address order
+ best fit strategies are able to use "small block multi block carriers".
+ </p></note>
+
<section>
<marker id="flags"></marker>
<title>System Flags Effecting erts_alloc</title>
@@ -215,6 +242,7 @@
the currently present allocators:</p>
<list type="bulleted">
<item><c>B: binary_alloc</c></item>
+ <item><c>C: sbmbc_alloc</c></item>
<item><c>D: std_alloc</c></item>
<item><c>E: ets_alloc</c></item>
<item><c>F: fix_alloc</c></item>
@@ -300,11 +328,11 @@
subsystem identifier, only the specific allocator identified will be
effected:</p>
<taglist>
- <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|gf|af]]></c></marker></tag>
+ <tag><marker id="M_as"><c><![CDATA[+M<S>as bf|aobf|aoff|gf|af]]></c></marker></tag>
<item>
Allocation strategy. Valid strategies are <c>bf</c> (best fit),
- <c>aobf</c> (address order best fit), <c>gf</c> (good fit),
- and <c>af</c> (a fit). See
+ <c>aobf</c> (address order best fit), <c>aoff</c> (address order first 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>
<item>
@@ -395,6 +423,20 @@
threshold will be placed in singleblock carriers. Blocks
smaller than this threshold will be placed in multiblock
carriers.</item>
+ <tag><marker id="M_sbmbcs"><c><![CDATA[+M<S>sbmbcs <size>]]></c></marker></tag>
+ <item>
+ Small block multiblock carrier size (in bytes). Memory blocks smaller
+ than the small block multiblock carrier threshold
+ (<seealso marker="#M_sbmbct">sbmbct</seealso>) will be placed in
+ multiblock carriers used for small blocks only. This parameter
+ determines the size of such carriers.
+ </item>
+ <tag><marker id="M_sbmbct"><c><![CDATA[+M<S>sbmbct <size>]]></c></marker></tag>
+ <item>
+ Small block multiblock carrier threshold (in bytes). Memory blocks
+ smaller than this threshold will be placed in multiblock carriers
+ used for small blocks only.
+ </item>
<tag><marker id="M_smbcs"><c><![CDATA[+M<S>smbcs <size>]]></c></marker></tag>
<item>
Smallest (<c>mseg_alloc</c>) multiblock carrier size (in
diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml
index 0e828389f6..d5c43f6e57 100644
--- a/erts/doc/src/init.xml
+++ b/erts/doc/src/init.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -47,15 +47,12 @@
</description>
<funcs>
<func>
- <name>boot(BootArgs) -> void()</name>
+ <name name="boot" arity="1"/>
<fsummary>Start the Erlang runtime system</fsummary>
- <type>
- <v>BootArgs = [binary()]</v>
- </type>
<desc>
<p>Starts the Erlang runtime system. This function is called
when the emulator is started and coordinates system start-up.</p>
- <p><c>BootArgs</c> are all command line arguments except
+ <p><c><anno>BootArgs</anno></c> are all command line arguments except
the emulator flags, that is, flags and plain arguments. See
<seealso marker="erts:erl">erl(1)</seealso>.</p>
<p><c>init</c> itself interprets some of the flags, see
@@ -67,17 +64,12 @@
</desc>
</func>
<func>
- <name>get_argument(Flag) -> {ok, Arg} | error</name>
+ <name name="get_argument" arity="1"/>
<fsummary>Get the values associated with a command line user flag</fsummary>
- <type>
- <v>Flag = atom()</v>
- <v>Arg = [Values]</v>
- <v>&nbsp;Values = [string()]</v>
- </type>
<desc>
<p>Returns all values associated with the command line user flag
- <c>Flag</c>. If <c>Flag</c> is provided several times, each
- <c>Values</c> is returned in preserved order.</p>
+ <c><anno>Flag</anno></c>. If <c><anno>Flag</anno></c> is provided several times, each
+ <c><anno>Values</anno></c> is returned in preserved order.</p>
<pre>
% <input>erl -a b c -a d</input>
...
@@ -113,48 +105,37 @@
</desc>
</func>
<func>
- <name>get_arguments() -> Flags</name>
+ <name name="get_arguments" arity="0"/>
<fsummary>Get all command line user flags</fsummary>
- <type>
- <v>Flags = [{Flag, Values}]</v>
- <v>&nbsp;Flag = atom()</v>
- <v>&nbsp;Values = [string()]</v>
- </type>
<desc>
<p>Returns all command line flags, as well as the system
defined flags, see <c>get_argument/1</c>.</p>
</desc>
</func>
<func>
- <name>get_plain_arguments() -> [Arg]</name>
+ <name name="get_plain_arguments" arity="0"/>
<fsummary>Get all non-flag command line arguments</fsummary>
- <type>
- <v>Arg = string()</v>
- </type>
<desc>
<p>Returns any plain command line arguments as a list of strings
(possibly empty).</p>
</desc>
</func>
<func>
- <name>get_status() -> {InternalStatus, ProvidedStatus}</name>
+ <name name="get_status" arity="0"/>
<fsummary>Get system status information</fsummary>
- <type>
- <v>InternalStatus = starting | started | stopping</v>
- <v>ProvidedStatus = term()</v>
- </type>
+ <type name="internal_status"/>
<desc>
<p>The current status of the <c>init</c> process can be
inspected. During system startup (initialization),
- <c>InternalStatus</c> is <c>starting</c>, and
- <c>ProvidedStatus</c> indicates how far the boot script has
+ <c><anno>InternalStatus</anno></c> is <c>starting</c>, and
+ <c><anno>ProvidedStatus</anno></c> indicates how far the boot script has
been interpreted. Each <c>{progress, Info}</c> term
- interpreted in the boot script affects <c>ProvidedStatus</c>,
- that is, <c>ProvidedStatus</c> gets the value of <c>Info</c>.</p>
+ interpreted in the boot script affects <c><anno>ProvidedStatus</anno></c>,
+ that is, <c><anno>ProvidedStatus</anno></c> gets the value of <c>Info</c>.</p>
</desc>
</func>
<func>
- <name>reboot() -> void()</name>
+ <name name="reboot" arity="0"/>
<fsummary>Take down and restart an Erlang node smoothly</fsummary>
<desc>
<p>All applications are taken down smoothly, all code is
@@ -168,7 +149,7 @@
</desc>
</func>
<func>
- <name>restart() -> void()</name>
+ <name name="restart" arity="0"/>
<fsummary>Restart the running Erlang node</fsummary>
<desc>
<p>The system is restarted <em>inside</em> the running Erlang
@@ -183,20 +164,17 @@
</desc>
</func>
<func>
- <name>script_id() -> Id</name>
+ <name name="script_id" arity="0"/>
<fsummary>Get the identity of the used boot script</fsummary>
- <type>
- <v>Id = term()</v>
- </type>
<desc>
<p>Get the identity of the boot script used to boot the system.
- <c>Id</c> can be any Erlang term. In the delivered boot
- scripts, <c>Id</c> is <c>{Name, Vsn}</c>. <c>Name</c> and
+ <c><anno>Id</anno></c> can be any Erlang term. In the delivered boot
+ scripts, <c><anno>Id</anno></c> is <c>{Name, Vsn}</c>. <c>Name</c> and
<c>Vsn</c> are strings.</p>
</desc>
</func>
<func>
- <name>stop() -> void()</name>
+ <name name="stop" arity="0"/>
<fsummary>Take down an Erlang node smoothly</fsummary>
<desc>
<p>All applications are taken down smoothly, all code is
@@ -210,15 +188,12 @@
</desc>
</func>
<func>
- <name>stop(Status) -> void()</name>
+ <name name="stop" arity="1"/>
<fsummary>Take down an Erlang node smoothly</fsummary>
- <type>
- <v>Status = int()>=0 | string()</v>
- </type>
<desc>
<p>All applications are taken down smoothly, all code is
unloaded, and all ports are closed before the system
- terminates by calling <c>halt(Status)</c>. If the
+ terminates by calling <c>halt(<anno>Status</anno>)</c>. If the
<c>-heart</c> command line flag was given, the <c>heart</c>
program is terminated before the Erlang node
terminates. Refer to <c>heart(3)</c> for more
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 7383ea381d..3733fb2db9 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -30,6 +30,357 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 5.8.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fix binary and iolist overflow problems. Typically
+ problems arose in length calculation where the result
+ would exceed (1 bsl 32 - 1).</p>
+ <p>
+ Own Id: OTP-9118</p>
+ </item>
+ <item>
+ <p>
+ Using the old erlang shell (i.e. erl instead on werl) on
+ windows and doing several init:restart's would eventually
+ hang the VM. That is no longer the case.</p>
+ <p>
+ Own Id: OTP-9139</p>
+ </item>
+ <item>
+ <p>
+ Removed recursive C code when printing Erlang terms to
+ buffers, avoiding stack overflows that could cause VM to
+ crash.</p>
+ <p>
+ Own Id: OTP-9140</p>
+ </item>
+ <item>
+ <p>
+ The send_timeout option in gen_tcp did not work properly
+ in active mode or with {active,once} options. This is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-9145</p>
+ </item>
+ <item>
+ <p>
+ Fixed various typos across the documentation (Thanks to
+ Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9154</p>
+ </item>
+ <item>
+ <p>Remove duplicate stack entries which could occur after
+ calling certain BIFs.</p>
+ <p>
+ Own Id: OTP-9163</p>
+ </item>
+ <item>
+ <p>
+ A race when starting two nodes simultaneously using
+ run_erl has been removed.</p>
+ <p>
+ Own Id: OTP-9164</p>
+ </item>
+ <item>
+ <p>
+ Add documentation on .erlang processing back again
+ (Thanks to Gabor Liptak)</p>
+ <p>
+ Own Id: OTP-9189</p>
+ </item>
+ <item>
+ <p>
+ Remove gratuitous paren in driver_entry(Thanks to Tuncer
+ Ayaz)</p>
+ <p>
+ Own Id: OTP-9192</p>
+ </item>
+ <item>
+ <p>
+ Fix some wrong pointer dereferences (Thanks to Cristian
+ Greco)</p>
+ <p>
+ Own Id: OTP-9194</p>
+ </item>
+ <item>
+ <p>
+ erts: Remove unused variables (Thanks to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9205</p>
+ </item>
+ <item>
+ <p>
+ The documentation for <c>init:get_args/0</c> has been
+ removed. <c>init:get_args/0</c> itself was deprecated in
+ R9C and removed in R12B. (Thanks to Eric Pailleau.)</p>
+ <p>
+ Own Id: OTP-9209</p>
+ </item>
+ <item>
+ <p>
+ Allow user to specify the IP address epmd binds to</p>
+ <p>
+ The IP address(es) epmd binds to can now be specified by
+ the user, either via epmd's new "-address" option or (if
+ that's not used) by setting the environment variable
+ ERL_EPMD_ADDRESS. Multiple addresses may be specified
+ using a comma-separated list. If the loopback address is
+ not in this list, it will be added implicitly, so that
+ the daemon can be queried by an interactive epmd
+ process.(Thanks to Holger Wei�)</p>
+ <p>
+ Own Id: OTP-9213</p>
+ </item>
+ <item>
+ <p>
+ epmd: include host address in local access check</p>
+ <p>
+ In FreeBSD jails, the source and destination address of
+ connections to localhost are changed to be the IP address
+ of the jail. Consider connections from the host's IP
+ address to itself (e.g., the source and destination
+ address match) to be local for the access control checks.
+ (Thanks to Michal Santos and Tom at diogunix.com)</p>
+ <p>
+ Own Id: OTP-9214</p>
+ </item>
+ <item>
+ <p>
+ Fix list returned by net_kernel:epmd_module</p>
+ <p>
+ Function epmd_module of net_kernel returns a list instead
+ of an atom, when the epmd_module-flag is used. (Thanks to
+ Markus Knofe)</p>
+ <p>
+ Own Id: OTP-9215</p>
+ </item>
+ <item>
+ <p>
+ Fix epmd's dbg_perror() output</p>
+ <p>
+ The dbg_perror() function now hands the current errno
+ value over to dbg_gen_printf(). This fixes the problem
+ that errno had been reset to zero by the time it was used
+ (to print the corresponding error message) in the
+ dbg_gen_printf() function. (Thanks to Holger Wei�)</p>
+ <p>
+ Own Id: OTP-9223</p>
+ </item>
+ <item>
+ <p>
+ heart: remove garbage appended to heart command</p>
+ <p>
+ heart:get_cmd/0 is documented to return an empty string
+ if the command is cleared. get_cmd/0 returns 2 extra
+ bytes: 1 byte for the trailing null, 1 byte from the op
+ (the op is an unsigned char and 2 bytes are allocated for
+ it in the returned buffer). (Thanks to Michael Santos)</p>
+ <p>
+ Own Id: OTP-9224</p>
+ </item>
+ <item>
+ <p>
+ file: fix hang reading compressed files</p>
+ <p>
+ The gzio driver goes into an infinite loop when reading
+ past the end of a compressed file. Reported-By: Alex
+ Morarash (Thanks to Michael Santos)</p>
+ <p>
+ Own Id: OTP-9245</p>
+ </item>
+ <item>
+ <p>Eliminate alias warnings from gcc 4.5.2</p>
+ <p>
+ Own Id: OTP-9250</p>
+ </item>
+ <item>
+ <p>
+ Unsigned integer may overflow in error message (Thanks to
+ Michael Santos)</p>
+ <p>
+ Own Id: OTP-9251</p>
+ </item>
+ <item>
+ <p>
+ Driver names should be strings, not atoms</p>
+ <p>
+ Own Id: OTP-9253</p>
+ </item>
+ <item>
+ <p>
+ driver_entry: Remove gratuitous paren and fix typo
+ (Thanks to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9254</p>
+ </item>
+ <item>
+ <p>
+ Fix format specifiers in erl_exit messages</p>
+ <p>
+ Fix an error message by using an unsigned integer
+ specifier as seen in a tweet by @metabrew: #erlang VM
+ crashed with "no next heap size found: -2090496108,
+ offset 0", suddenly allocated all available RAM</p>
+ <p>
+ Also correct mis-typed string formats in bif.c.(Thanks to
+ Michael Santos)</p>
+ <p>
+ Own Id: OTP-9262</p>
+ </item>
+ <item>
+ <p>
+ net_drv: remove unused tcp request id inet_drv: remove
+ gratuitous assignment (Thanks to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9263</p>
+ </item>
+ <item>
+ <p>
+ Teach run_erl RUN_ERL_DISABLE_FLOWCNTRL for disabling
+ flow control</p>
+ <p>
+ Flow control can cause unwanted behaviour of the beam
+ process, if accidentally hit Ctrl-S (instead of Ctrl-D to
+ detach) the entire beam may be blocked.</p>
+ <p>
+ Fix this problem by making it possible to turn off flow
+ control by setting the environment variable
+ RUN_ERL_DISABLE_FLOWCNTRL. (Thanks to Jonas Faklkevik)</p>
+ <p>
+ Own Id: OTP-9270</p>
+ </item>
+ <item>
+ <p>The following bugs due to missing memory barriers have
+ been fixed:</p> <list> <item><p> ETS tables using the
+ <c>write_concurrency</c> option could potentially get
+ into an internally inconsistent state. </p></item>
+ <item><p> ETS tables using the <c>ordered_set</c> option
+ could potentially get into an internally inconsistent
+ state. </p></item> <item><p> A number of memory barriers
+ have been added when building with the
+ <c>libatomic_ops</c> API (i.e. when passing
+ <c>--with-libatomic_ops=PATH</c> to <c>configure</c>) and
+ the tilera atomics API (i.e. when building for the tilera
+ chip). Note that these bugs were due to erroneous usage
+ of the APIs, and not in the implementations of the APIs.
+ When using these APIs the following bugs where
+ present:</p> <list> <item><p> The BIF
+ <c>erlang:ports/0</c> could return an erroneous result.
+ </p></item> <item><p> A thread blocking other threads
+ during code loading, or setup of tracing could
+ potentially read invalid data. </p></item> <item><p>
+ Fixation of ETS tables could potentially get into an
+ internally inconsistent state. </p></item> </list>
+ </item> </list>
+ <p>
+ Own Id: OTP-9281</p>
+ </item>
+ <item>
+ <p>
+ Fix halfword bug for ETS ordered_set when doing
+ <c>select/match</c> with partly bound key.</p>
+ <p>
+ Own Id: OTP-9292</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in <c>code:is_module_native</c> that caused crash
+ for deleted modules.</p>
+ <p>
+ Own Id: OTP-9298</p>
+ </item>
+ <item>
+ <p>
+ Calling <c>driver_async_cancel()</c> could cause a
+ scheduler thread to enter an eternal loop doing no useful
+ work. (Thanks to Anders Ramsell)</p>
+ <p>
+ Own Id: OTP-9302</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New <c>enif_is_exception function</c> to allow NIFs to
+ determine whether an <c>ERL_NIF_TERM</c> represents an
+ exception. (Thanks to Steve Vinoski)</p>
+ <p>
+ Own Id: OTP-9150</p>
+ </item>
+ <item>
+ <p>
+ A process being garbage collected by another process
+ could be scheduled on another scheduler. This prevented
+ this scheduler from doing any useful work until the
+ garbage collection was done. This either occurred due to
+ a explicit call to the <c>garbage_collect/1</c> BIF, or
+ due to a garbage collection part of code loading. A
+ process being garbage collected like this will now not be
+ scheduled until the garbage collection has completed.</p>
+ <p>
+ Own Id: OTP-9211</p>
+ </item>
+ <item>
+ <p>
+ Remove unnecessary validation copy in
+ prim_file:drv_command/3 (Thanks to Tony Rogvall)</p>
+ <p>
+ Own Id: OTP-9276</p>
+ </item>
+ <item>
+ <p>
+ Symbolic link handling on windows have been slightly
+ updated to map error conditions more consequently and
+ correctly read directory links created outside of the
+ Erlang environment.</p>
+ <p>
+ Own Id: OTP-9279</p>
+ </item>
+ <item>
+ <p>
+ Due to standard library DLL mismatches between versions
+ of OpenSSL and Erlang/OTP, OpenSSL is now linked
+ statically to the crypto driver on Windows. This fixes
+ problems starting crypto when running Erlang as a service
+ on all Windows versions.</p>
+ <p>
+ Own Id: OTP-9280</p>
+ </item>
+ <item>
+ <p>Halfword emulator memory handling improvements:</p>
+ <list> <item><p>Much more of internal memory structures
+ have been made able to use "high" memory and are no
+ longer restricted to the 4Gb limit that still applies for
+ all process heap data.</p> </item> <item><p>Fixed faulty
+ values from <c>erlang:memory()</c> caused by 32-bit
+ counter overflow.</p> </item> <item><p>New counter
+ <c>low</c> in <c>erlang:memory()</c> that sums up all
+ memory restricted by 4Gb limit.</p> </item> </list>
+ <p>
+ Own Id: OTP-9291 Aux Id: seq11841 </p>
+ </item>
+ <item>
+ <p>
+ The value set in the undocumented and unsupported
+ ERL_version_FLAGS (e.g. ERL_R14B03_FLAGS) environment
+ variable can now be overridden by the command line
+ (similar to ERL_AFLAGS).</p>
+ <p>
+ Own Id: OTP-9297</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 5.8.3.2</title>
<section><title>Known Bugs and Problems</title>
diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml
index da08859c7b..c9784299b3 100644
--- a/erts/doc/src/run_erl.xml
+++ b/erts/doc/src/run_erl.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml
new file mode 100644
index 0000000000..e5c2f4783f
--- /dev/null
+++ b/erts/doc/src/specs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="latin1" ?>
+<specs xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="../specs/specs_erl_prim_loader.xml"/>
+ <xi:include href="../specs/specs_erlang.xml"/>
+ <xi:include href="../specs/specs_init.xml"/>
+ <xi:include href="../specs/specs_zlib.xml"/>
+</specs>
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
index b1e768bce9..47a649af02 100644
--- a/erts/doc/src/zlib.xml
+++ b/erts/doc/src/zlib.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2005</year><year>2010</year>
+ <year>2005</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -76,96 +76,92 @@ list_to_binary([Compressed|Last])</pre>
</taglist>
</description>
- <section>
- <title>DATA TYPES</title>
- <code type="none">
-iodata = iolist() | binary()
-
-iolist = [char() | binary() | iolist()]
- a binary is allowed as the tail of the list
-
-zstream = a zlib stream, see open/0</code>
- </section>
+ <datatypes>
+ <datatype>
+ <name name="zstream"/>
+ <desc>
+ <p>A zlib stream, see <seealso marker="#open/0">open/0</seealso>.
+ </p>
+ </desc>
+ </datatype>
+ <datatype>
+ <name name="zlevel"/>
+ </datatype>
+ <datatype>
+ <name name="zmemlevel"/>
+ </datatype>
+ <datatype>
+ <name name="zmethod"/>
+ </datatype>
+ <datatype>
+ <name name="zstrategy"/>
+ </datatype>
+ <datatype>
+ <name name="zwindowbits"/>
+ <desc>
+ <p>Normally in the range <c>-15..-9 | 9..15</c>.</p>
+ </desc>
+ </datatype>
+ </datatypes>
<funcs>
<func>
- <name>open() -> Z </name>
+ <name name="open" arity="0"/>
<fsummary>Open a stream and return a stream reference</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>Open a zlib stream.</p>
</desc>
</func>
<func>
- <name>close(Z) -> ok</name>
+ <name name="close" arity="1"/>
<fsummary>Close a stream</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
- <p>Closes the stream referenced by <c>Z</c>.</p>
+ <p>Closes the stream referenced by <c><anno>Z</anno></c>.</p>
</desc>
</func>
<func>
- <name>deflateInit(Z) -> ok</name>
+ <name name="deflateInit" arity="1"/>
<fsummary>Initialize a session for compression</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
- <p>Same as <c>zlib:deflateInit(Z, default)</c>.</p>
+ <p>Same as <c>zlib:deflateInit(<anno>Z</anno>, default)</c>.</p>
</desc>
</func>
<func>
- <name>deflateInit(Z, Level) -> ok</name>
+ <name name="deflateInit" arity="2"/>
<fsummary>Initialize a session for compression</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Level = none | default | best_speed | best_compression | 0..9</v>
- </type>
<desc>
<p>Initialize a zlib stream for compression.</p>
- <p><c>Level</c> decides the compression level to be used, 0
+ <p><c><anno>Level</anno></c> decides the compression level to be used, 0
(<c>none</c>), gives no compression at all, 1
(<c>best_speed</c>) gives best speed and 9
(<c>best_compression</c>) gives best compression.</p>
</desc>
</func>
<func>
- <name>deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> ok</name>
+ <name name="deflateInit" arity="6"/>
<fsummary>Initialize a session for compression</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Level = none | default | best_speed | best_compression | 0..9</v>
- <v>Method = deflated</v>
- <v>WindowBits = 9..15|-9..-15</v>
- <v>MemLevel = 1..9</v>
- <v>Strategy = default|filtered|huffman_only</v>
- </type>
<desc>
<p>Initiates a zlib stream for compression.</p>
- <p>The <c>Level</c> parameter decides the compression level to be
+ <p>The <c><anno>Level</anno></c> parameter decides the compression level to be
used, 0 (<c>none</c>), gives no compression at all, 1
(<c>best_speed</c>) gives best speed and 9
(<c>best_compression</c>) gives best compression.</p>
- <p>The <c>Method</c> parameter decides which compression method to use,
+ <p>The <c><anno>Method</anno></c> parameter decides which compression method to use,
currently the only supported method is <c>deflated</c>.</p>
- <p>The <c>WindowBits</c> parameter is the base two logarithm
+ <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
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>WindowBits</c>
+ <c>deflateInit/2</c>. A negative <c><anno>WindowBits</anno></c>
value suppresses the zlib header (and checksum) from the
stream. Note that the zlib source mentions this only as a
undocumented feature.</p>
- <p>The <c>MemLevel</c> parameter specifies how much memory
+ <p>The <c><anno>MemLevel</anno></c> parameter specifies how much memory
should be allocated for the internal compression
- state. <c>MemLevel</c>=1 uses minimum memory but is slow and
- reduces compression ratio; <c>MemLevel</c>=9 uses maximum
+ state. <c><anno>MemLevel</anno></c>=1 uses minimum memory but is slow and
+ reduces compression ratio; <c><anno>MemLevel</anno></c>=9 uses maximum
memory for optimal speed. The default value is 8.</p>
- <p>The <c>Strategy</c> parameter is used to tune the
+ <p>The <c><anno>Strategy</anno></c> parameter is used to tune the
compression algorithm. Use the value <c>default</c> for
normal data, <c>filtered</c> for data produced by a filter
(or predictor), or <c>huffman_only</c> to force Huffman
@@ -175,54 +171,43 @@ zstream = a zlib stream, see open/0</code>
tuned to compress them better. The effect of
<c>filtered</c>is to force more Huffman coding and less
string matching; it is somewhat intermediate between
- <c>default</c> and <c>huffman_only</c>. The <c>Strategy</c>
+ <c>default</c> and <c>huffman_only</c>. The <c><anno>Strategy</anno></c>
parameter only affects the compression ratio but not the
correctness of the compressed output even if it is not set
appropriately.</p>
</desc>
</func>
<func>
- <name>deflate(Z, Data) -> Compressed</name>
+ <name name="deflate" arity="2"/>
<fsummary>Compress data</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Data = iodata()</v>
- <v>Compressed = iolist()</v>
- </type>
<desc>
- <p>Same as <c>deflate(Z, Data, none)</c>.</p>
+ <p>Same as <c>deflate(<anno>Z</anno>, <anno>Data</anno>, none)</c>.</p>
</desc>
</func>
<func>
- <name>deflate(Z, Data, Flush) -> </name>
+ <name name="deflate" arity="3"/>
<fsummary>Compress data</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Data = iodata()</v>
- <v>Flush = none | sync | full | finish</v>
- <v>Compressed = iolist()</v>
- </type>
<desc>
<p><c>deflate/3</c> compresses as much data as possible, and
stops when the input buffer becomes empty. It may introduce
some output latency (reading input without producing any
output) except when forced to flush.</p>
- <p>If the parameter <c>Flush</c> is set to <c>sync</c>, all
+ <p>If the parameter <c><anno>Flush</anno></c> is set to <c>sync</c>, all
pending output is flushed to the output buffer and the
output is aligned on a byte boundary, so that the
decompressor can get all input data available so far.
Flushing may degrade compression for some compression algorithms and so
it should be used only when necessary.</p>
- <p>If <c>Flush</c> is set to <c>full</c>, all output is flushed as with
+ <p>If <c><anno>Flush</anno></c> is set to <c>full</c>, all output is flushed as with
<c>sync</c>, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
random access is desired. Using <c>full</c> too often can seriously degrade
the compression.</p>
- <p>If the parameter <c>Flush</c> is set to <c>finish</c>,
+ <p>If the parameter <c><anno>Flush</anno></c> is set to <c>finish</c>,
pending input is processed, pending output is flushed and
<c>deflate/3</c> returns. Afterwards the only possible
operations on the stream are <c>deflateReset/1</c> or <c>deflateEnd/1</c>.</p>
- <p><c>Flush</c> can be set to <c>finish</c> immediately after
+ <p><c><anno>Flush</anno></c> can be set to <c>finish</c> immediately after
<c>deflateInit</c> if all compression is to be done in one step.</p>
<pre>
@@ -234,13 +219,8 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
- <name>deflateSetDictionary(Z, Dictionary) -> Adler32</name>
+ <name name="deflateSetDictionary" arity="2"/>
<fsummary>Initialize the compression dictionary</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Dictionary = binary()</v>
- <v>Adler32 = integer()</v>
- </type>
<desc>
<p>Initializes the compression dictionary from the given byte
sequence without producing any compressed output. This
@@ -253,11 +233,8 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
- <name>deflateReset(Z) -> ok</name>
+ <name name="deflateReset" arity="1"/>
<fsummary>Reset the deflate session</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>This function is equivalent to <c>deflateEnd/1</c>
followed by <c>deflateInit/[1|2|6]</c>, but does not free
@@ -267,34 +244,26 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
- <name>deflateParams(Z, Level, Strategy) -> ok </name>
+ <name name="deflateParams" arity="3"/>
<fsummary>Dynamicly update deflate parameters</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Level = none | default | best_speed | best_compression | 0..9</v>
- <v>Strategy = default|filtered|huffman_only</v>
- </type>
<desc>
<p>Dynamically update the compression level and compression
- strategy. The interpretation of <c>Level</c> and
- <c>Strategy</c> is as in <c>deflateInit/6</c>. This can be
+ strategy. The interpretation of <c><anno>Level</anno></c> and
+ <c><anno>Strategy</anno></c> is as in <c>deflateInit/6</c>. This can be
used to switch between compression and straight copy of the
input data, or to switch to a different kind of input data
requiring a different strategy. If the compression level is
changed, the input available so far is compressed with the
old level (and may be flushed); the new level will take
effect only at the next call of <c>deflate/3</c>.</p>
- <p>Before the call of deflateParams, the stream state must be set as for
+ <p>Before the call of <c>deflateParams</c>, the stream state must be set as for
a call of <c>deflate/3</c>, since the currently available input may have to
be compressed and flushed.</p>
</desc>
</func>
<func>
- <name>deflateEnd(Z) -> ok</name>
+ <name name="deflateEnd" arity="1"/>
<fsummary>End deflate session</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>End the deflate session and cleans all data used.
Note that this function will throw an <c>data_error</c>
@@ -304,43 +273,31 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
- <name>inflateInit(Z) -> ok </name>
+ <name name="inflateInit" arity="1"/>
<fsummary>Initialize a session for decompression</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>Initialize a zlib stream for decompression.</p>
</desc>
</func>
<func>
- <name>inflateInit(Z, WindowBits) -> ok </name>
+ <name name="inflateInit" arity="2"/>
<fsummary>Initialize a session for decompression</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>WindowBits = 9..15|-9..-15</v>
- </type>
<desc>
<p>Initialize decompression session on zlib stream.</p>
- <p>The <c>WindowBits</c> parameter is the base two logarithm
+ <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.
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>
- exception. A negative <c>WindowBits</c> value makes zlib ignore the
+ exception. A negative <c><anno>WindowBits</anno></c> value makes zlib ignore the
zlib header (and checksum) from the stream. Note that the zlib
source mentions this only as a undocumented feature.</p>
</desc>
</func>
<func>
- <name>inflate(Z, Data) -> DeCompressed </name>
+ <name name="inflate" arity="2"/>
<fsummary>Decompress data</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Data = iodata()</v>
- <v>DeCompressed = iolist()</v>
- </type>
<desc>
<p><c>inflate/2</c> decompresses as much data as possible.
It may some introduce some output latency (reading
@@ -353,12 +310,8 @@ list_to_binary([B1,B2])</pre>
</desc>
</func>
<func>
- <name>inflateSetDictionary(Z, Dictionary) -> ok</name>
+ <name name="inflateSetDictionary" arity="2"/>
<fsummary>Initialize the decompression dictionary</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Dictionary = binary()</v>
- </type>
<desc>
<p>Initializes the decompression dictionary from the given
uncompressed byte sequence. This function must be called
@@ -381,11 +334,8 @@ unpack(Z, Compressed, Dict) ->
</desc>
</func>
<func>
- <name>inflateReset(Z) -> ok</name>
+ <name name="inflateReset" arity="1"/>
<fsummary>>Reset the inflate session</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>This function is equivalent to <c>inflateEnd/1</c> followed
by <c>inflateInit/1</c>, but does not free and reallocate all
@@ -394,11 +344,8 @@ unpack(Z, Compressed, Dict) ->
</desc>
</func>
<func>
- <name>inflateEnd(Z) -> ok</name>
+ <name name="inflateEnd" arity="1"/>
<fsummary>End inflate session</fsummary>
- <type>
- <v>Z = zstream()</v>
- </type>
<desc>
<p>End the inflate session and cleans all data used. Note
that this function will throw a <c>data_error</c> exception
@@ -407,62 +354,39 @@ unpack(Z, Compressed, Dict) ->
</desc>
</func>
<func>
- <name>setBufSize(Z, Size) -> ok</name>
+ <name name="setBufSize" arity="2"/>
<fsummary>Set buffer size</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Size = integer()</v>
- </type>
<desc>
<p>Sets the intermediate buffer size.</p>
</desc>
</func>
<func>
- <name>getBufSize(Z) -> Size</name>
+ <name name="getBufSize" arity="1"/>
<fsummary>Get buffer size</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Size = integer()</v>
- </type>
<desc>
<p>Get the size of intermediate buffer.</p>
</desc>
</func>
<func>
- <name>crc32(Z) -> CRC</name>
+ <name name="crc32" arity="1"/>
<fsummary>Get current CRC</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>CRC = integer()</v>
- </type>
<desc>
<p>Get the current calculated CRC checksum.</p>
</desc>
</func>
<func>
- <name>crc32(Z, Binary) -> CRC</name>
+ <name name="crc32" arity="2"/>
<fsummary>Calculate CRC</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Binary = binary()</v>
- <v>CRC = integer()</v>
- </type>
<desc>
- <p>Calculate the CRC checksum for <c>Binary</c>.</p>
+ <p>Calculate the CRC checksum for <c><anno>Binary</anno></c>.</p>
</desc>
</func>
<func>
- <name>crc32(Z, PrevCRC, Binary) -> CRC </name>
+ <name name="crc32" arity="3"/>
<fsummary>Calculate CRC</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>PrevCRC = integer()</v>
- <v>Binary = binary()</v>
- <v>CRC = integer()</v>
- </type>
- <desc>
- <p>Update a running CRC checksum for <c>Binary</c>.
- If <c>Binary</c> is the empty binary, this function returns
+ <desc>
+ <p>Update a running CRC checksum for <c><anno>Binary</anno></c>.
+ If <c><anno>Binary</anno></c> is the empty binary, this function returns
the required initial value for the crc.</p>
<pre>
Crc = lists:foldl(fun(Bin,Crc0) ->
@@ -471,49 +395,31 @@ Crc = lists:foldl(fun(Bin,Crc0) ->
</desc>
</func>
<func>
- <name>crc32_combine(Z, CRC1, CRC2, Size2) -> CRC </name>
+ <name name="crc32_combine" arity="4"/>
<fsummary>Combine two CRC's</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>CRC = integer()</v>
- <v>CRC1 = integer()</v>
- <v>CRC2 = integer()</v>
- <v>Size2 = integer()</v>
- </type>
<desc>
<p>Combine two CRC checksums into one. For two binaries,
<c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
- <c>Size2</c>, with CRC checksums <c>CRC1</c> and
- <c>CRC2</c>. <c>crc32_combine/4</c> returns the <c>CRC</c>
+ <c><anno>Size2</anno></c>, with CRC checksums <c><anno>CRC1</anno></c> and
+ <c><anno>CRC2</anno></c>. <c>crc32_combine/4</c> returns the <c><anno>CRC</anno></c>
checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
- only <c>CRC1</c>, <c>CRC2</c>, and <c>Size2</c>.
+ only <c><anno>CRC1</anno></c>, <c><anno>CRC2</anno></c>, and <c><anno>Size2</anno></c>.
</p>
</desc>
</func>
<func>
- <name>adler32(Z, Binary) -> Checksum</name>
+ <name name="adler32" arity="2"/>
<fsummary>Calculate the adler checksum</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Binary = binary()</v>
- <v>Checksum = integer()</v>
- </type>
<desc>
- <p>Calculate the Adler-32 checksum for <c>Binary</c>.</p>
+ <p>Calculate the Adler-32 checksum for <c><anno>Binary</anno></c>.</p>
</desc>
</func>
<func>
- <name>adler32(Z, PrevAdler, Binary) -> Checksum</name>
+ <name name="adler32" arity="3"/>
<fsummary>Calculate the adler checksum</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>PrevAdler = integer()</v>
- <v>Binary = binary()</v>
- <v>Checksum = integer()</v>
- </type>
- <desc>
- <p>Update a running Adler-32 checksum for <c>Binary</c>.
- If <c>Binary</c> is the empty binary, this function returns
+ <desc>
+ <p>Update a running Adler-32 checksum for <c><anno>Binary</anno></c>.
+ If <c><anno>Binary</anno></c> is the empty binary, this function returns
the required initial value for the checksum.</p>
<pre>
Crc = lists:foldl(fun(Bin,Crc0) ->
@@ -522,81 +428,56 @@ Crc = lists:foldl(fun(Bin,Crc0) ->
</desc>
</func>
<func>
- <name>adler32_combine(Z, Adler1, Adler2, Size2) -> Adler </name>
+ <name name="adler32_combine" arity="4"/>
<fsummary>Combine two Adler-32 checksums</fsummary>
- <type>
- <v>Z = zstream()</v>
- <v>Adler = integer()</v>
- <v>Adler1 = integer()</v>
- <v>Adler2 = integer()</v>
- <v>Size2 = integer()</v>
- </type>
<desc>
<p>Combine two Adler-32 checksums into one. For two binaries,
<c>Bin1</c> and <c>Bin2</c> with sizes of <c>Size1</c> and
- <c>Size2</c>, with Adler-32 checksums <c>Adler1</c> and
- <c>Adler2</c>. <c>adler32_combine/4</c> returns the <c>Adler</c>
+ <c><anno>Size2</anno></c>, with Adler-32 checksums <c><anno>Adler1</anno></c> and
+ <c><anno>Adler2</anno></c>. <c>adler32_combine/4</c> returns the <c><anno>Adler</anno></c>
checksum of <c>&lt;&lt;Bin1/binary,Bin2/binary&gt;&gt;</c>, requiring
- only <c>Adler1</c>, <c>Adler2</c>, and <c>Size2</c>.
+ only <c><anno>Adler1</anno></c>, <c><anno>Adler2</anno></c>, and <c><anno>Size2</anno></c>.
</p>
</desc>
</func>
<func>
- <name>compress(Binary) -> Compressed </name>
+ <name name="compress" arity="1"/>
<fsummary>Compress a binary with standard zlib functionality</fsummary>
- <type>
- <v>Binary = Compressed = binary()</v>
- </type>
<desc>
<p>Compress a binary (with zlib headers and checksum).</p>
</desc>
</func>
<func>
- <name>uncompress(Binary) -> Decompressed</name>
+ <name name="uncompress" arity="1"/>
<fsummary>Uncompress a binary with standard zlib functionality</fsummary>
- <type>
- <v>Binary = Decompressed = binary()</v>
- </type>
<desc>
<p>Uncompress a binary (with zlib headers and checksum).</p>
</desc>
</func>
<func>
- <name>zip(Binary) -> Compressed</name>
+ <name name="zip" arity="1"/>
<fsummary>Compress a binary without the zlib headers</fsummary>
- <type>
- <v>Binary = Compressed = binary()</v>
- </type>
<desc>
<p>Compress a binary (without zlib headers and checksum).</p>
</desc>
</func>
<func>
- <name>unzip(Binary) -> Decompressed</name>
+ <name name="unzip" arity="1"/>
<fsummary>Uncompress a binary without the zlib headers</fsummary>
- <type>
- <v>Binary = Decompressed = binary()</v>
- </type>
<desc>
<p>Uncompress a binary (without zlib headers and checksum).</p>
</desc>
</func>
<func>
- <name>gzip(Data) -> Compressed</name>
+ <name name="gzip" arity="1"/>
<fsummary>Compress a binary with gz header</fsummary>
- <type>
- <v>Binary = Compressed = binary()</v>
- </type>
<desc>
<p>Compress a binary (with gz headers and checksum).</p>
</desc>
</func>
<func>
- <name>gunzip(Bin) -> Decompressed</name>
+ <name name="gunzip" arity="1"/>
<fsummary>Uncompress a binary with gz header</fsummary>
- <type>
- <v>Binary = Decompressed = binary()</v>
- </type>
<desc>
<p>Uncompress a binary (with gz headers and checksum).</p>
</desc>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index c9076a9d64..b658e79378 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -742,7 +742,7 @@ RUN_OBJS = \
$(OBJDIR)/erl_bif_re.o $(OBJDIR)/erl_unicode.o \
$(OBJDIR)/packet_parser.o $(OBJDIR)/safe_hash.o \
$(OBJDIR)/erl_zlib.o $(OBJDIR)/erl_nif.o \
- $(OBJDIR)/erl_bif_binary.o
+ $(OBJDIR)/erl_bif_binary.o $(OBJDIR)/erl_ao_firstfit_alloc.o
ifeq ($(TARGET),win32)
DRV_OBJS = \
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index de76cb9680..68d64fb7b0 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1996-2010. All Rights Reserved.
+# Copyright Ericsson AB 1996-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index d76a7d8e9f..2561d7a630 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -162,6 +162,23 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3)
return res;
}
+BIF_RETTYPE
+check_old_code_1(BIF_ALIST_1)
+{
+ Module* modp;
+
+ if (is_not_atom(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ modp = erts_get_module(BIF_ARG_1);
+ if (modp == NULL) { /* Doesn't exist. */
+ BIF_RET(am_false);
+ } else if (modp->old_code == NULL) { /* No old code. */
+ BIF_RET(am_false);
+ }
+ BIF_RET(am_true);
+}
+
Eterm
check_process_code_2(BIF_ALIST_2)
{
@@ -175,6 +192,13 @@ check_process_code_2(BIF_ALIST_2)
Eterm res;
if (internal_pid_index(BIF_ARG_1) >= erts_max_processes)
goto error;
+ modp = erts_get_module(BIF_ARG_2);
+ if (modp == NULL) { /* Doesn't exist. */
+ return am_false;
+ } else if (modp->old_code == NULL) { /* No old code. */
+ return am_false;
+ }
+
#ifdef ERTS_SMP
rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN,
BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
@@ -188,7 +212,6 @@ check_process_code_2(BIF_ALIST_2)
ERTS_BIF_YIELD2(bif_export[BIF_check_process_code_2], BIF_P,
BIF_ARG_1, BIF_ARG_2);
}
- modp = erts_get_module(BIF_ARG_2);
res = check_process_code(rp, modp);
#ifdef ERTS_SMP
if (BIF_P != rp) {
@@ -412,11 +435,6 @@ check_process_code(Process* rp, Module* modp)
#endif
#define INSIDE(a) (start <= (a) && (a) < end)
- if (modp == NULL) { /* Doesn't exist. */
- return am_false;
- } else if (modp->old_code == NULL) { /* No old code. */
- return am_false;
- }
/*
* Pick up limits for the module.
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index fb90a7d4f7..937b3d9e53 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3561,7 +3561,7 @@ void process_main(void)
* Operands: NotUsed Live Dst
*/
do_bs_init_bits_known:
- num_bytes = (num_bits+7) >> 3;
+ num_bytes = ((Uint64)num_bits+(Uint64)7) >> 3;
if (num_bits & 7) {
alloc += ERL_SUB_BIN_SIZE;
}
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 57fe25453d..eb10ae59a8 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -332,20 +332,22 @@ typedef struct {
Eterm* func_tab[1]; /* Pointers to each function. */
} LoadedCode;
-#define GetTagAndValue(Stp, Tag, Val) \
- do { \
- BeamInstr __w; \
- GetByte(Stp, __w); \
- Tag = __w & 0x07; \
- if ((__w & 0x08) == 0) { \
- Val = __w >> 4; \
- } else if ((__w & 0x10) == 0) { \
- Val = ((__w >> 5) << 8); \
- GetByte(Stp, __w); \
- Val |= __w; \
- } else { \
- if (!get_int_val(Stp, __w, &(Val))) goto load_error; \
- } \
+#define GetTagAndValue(Stp, Tag, Val) \
+ do { \
+ BeamInstr __w; \
+ GetByte(Stp, __w); \
+ Tag = __w & 0x07; \
+ if ((__w & 0x08) == 0) { \
+ Val = __w >> 4; \
+ } else if ((__w & 0x10) == 0) { \
+ Val = ((__w >> 5) << 8); \
+ GetByte(Stp, __w); \
+ Val |= __w; \
+ } else { \
+ int __res = get_tag_and_value(Stp, __w, (Tag), &(Val)); \
+ if (__res < 0) goto load_error; \
+ Tag = (unsigned) __res; \
+ } \
} while (0)
@@ -489,8 +491,8 @@ static void load_printf(int line, LoaderState* context, char *fmt, ...);
static int transform_engine(LoaderState* st);
static void id_to_string(Uint id, char* s);
static void new_genop(LoaderState* stp);
-static int get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result);
-static int get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result);
+static int get_tag_and_value(LoaderState* stp, Uint len_code,
+ unsigned tag, BeamInstr* result);
static int new_label(LoaderState* stp);
static void new_literal_patch(LoaderState* stp, int pos);
static void new_string_patch(LoaderState* stp, int pos);
@@ -1470,46 +1472,15 @@ load_code(LoaderState* stp)
last_op->arity = 0;
ASSERT(arity <= MAX_OPARGS);
-#define GetValue(Stp, First, Val) \
- do { \
- if (((First) & 0x08) == 0) { \
- Val = (First) >> 4; \
- } else if (((First) & 0x10) == 0) { \
- BeamInstr __w; \
- GetByte(Stp, __w); \
- Val = (((First) >> 5) << 8) | __w; \
- } else { \
- if (!get_int_val(Stp, (First), &(Val))) goto load_error; \
- } \
- } while (0)
-
for (arg = 0; arg < arity; arg++) {
- BeamInstr first;
-
- GetByte(stp, first);
- last_op->a[arg].type = first & 0x07;
+ GetTagAndValue(stp, last_op->a[arg].type, last_op->a[arg].val);
switch (last_op->a[arg].type) {
case TAG_i:
- if ((first & 0x08) == 0) {
- last_op->a[arg].val = first >> 4;
- } else if ((first & 0x10) == 0) {
- BeamInstr w;
- GetByte(stp, w);
- ASSERT(first < 0x800);
- last_op->a[arg].val = ((first >> 5) << 8) | w;
- } else {
- int i = get_erlang_integer(stp, first, &(last_op->a[arg].val));
- if (i < 0) {
- goto load_error;
- }
- last_op->a[arg].type = i;
- }
- break;
case TAG_u:
- GetValue(stp, first, last_op->a[arg].val);
+ case TAG_q:
+ case TAG_o:
break;
case TAG_x:
- GetValue(stp, first, last_op->a[arg].val);
if (last_op->a[arg].val == 0) {
last_op->a[arg].type = TAG_r;
} else if (last_op->a[arg].val >= MAX_REG) {
@@ -1518,7 +1489,6 @@ load_code(LoaderState* stp)
}
break;
case TAG_y:
- GetValue(stp, first, last_op->a[arg].val);
if (last_op->a[arg].val >= MAX_REG) {
LoadError1(stp, "invalid y register number: %u",
last_op->a[arg].val);
@@ -1526,7 +1496,6 @@ load_code(LoaderState* stp)
last_op->a[arg].val += CP_SIZE;
break;
case TAG_a:
- GetValue(stp, first, last_op->a[arg].val);
if (last_op->a[arg].val == 0) {
last_op->a[arg].type = TAG_n;
} else if (last_op->a[arg].val >= stp->num_atoms) {
@@ -1536,7 +1505,6 @@ load_code(LoaderState* stp)
}
break;
case TAG_f:
- GetValue(stp, first, last_op->a[arg].val);
if (last_op->a[arg].val == 0) {
last_op->a[arg].type = TAG_p;
} else if (last_op->a[arg].val >= stp->num_labels) {
@@ -1544,7 +1512,6 @@ load_code(LoaderState* stp)
}
break;
case TAG_h:
- GetValue(stp, first, last_op->a[arg].val);
if (last_op->a[arg].val > 65535) {
LoadError1(stp, "invalid range for character data type: %u",
last_op->a[arg].val);
@@ -1552,11 +1519,9 @@ load_code(LoaderState* stp)
break;
case TAG_z:
{
- BeamInstr ext_tag;
unsigned tag;
- GetValue(stp, first, ext_tag);
- switch (ext_tag) {
+ switch (last_op->a[arg].val) {
case 0: /* Floating point number */
{
Eterm* hp;
@@ -1648,7 +1613,8 @@ load_code(LoaderState* stp)
break;
}
default:
- LoadError1(stp, "invalid extended tag %d", ext_tag);
+ LoadError1(stp, "invalid extended tag %d",
+ last_op->a[arg].val);
break;
}
}
@@ -1659,7 +1625,6 @@ load_code(LoaderState* stp)
}
last_op->arity++;
}
-#undef GetValue
ASSERT(arity == last_op->arity);
@@ -2562,13 +2527,8 @@ should_gen_heap_bin(LoaderState* stp, GenOpArg Src)
static int
binary_too_big(LoaderState* stp, GenOpArg Size)
{
- return Size.type == TAG_u && ((Size.val >> (8*sizeof(Uint)-3)) != 0);
-}
-
-static int
-binary_too_big_bits(LoaderState* stp, GenOpArg Size)
-{
- return Size.type == TAG_u && (((Size.val+7)/8) >> (8*sizeof(Uint)-3) != 0);
+ return Size.type == TAG_o ||
+ (Size.type == TAG_u && ((Size.val >> (8*sizeof(Uint)-3)) != 0));
}
static GenOp*
@@ -4317,41 +4277,9 @@ load_printf(int line, LoaderState* context, char *fmt,...)
erts_send_error_to_logger(context->group_leader, dsbufp);
}
-
-static int
-get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result)
-{
- Uint count;
- Uint val;
-
- len_code >>= 5;
- ASSERT(len_code < 8);
- if (len_code == 7) {
- LoadError0(stp, "can't load integers bigger than 8 bytes yet\n");
- }
- count = len_code + 2;
- if (count == 5) {
- Uint msb;
- GetByte(stp, msb);
- if (msb == 0) {
- count--;
- }
- GetInt(stp, 4, *result);
- } else if (count <= 4) {
- GetInt(stp, count, val);
- *result = ((val << 8*(sizeof(val)-count)) >> 8*(sizeof(val)-count));
- } else {
- LoadError1(stp, "too big integer; %d bytes\n", count);
- }
- return 1;
-
- load_error:
- return 0;
-}
-
-
static int
-get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result)
+get_tag_and_value(LoaderState* stp, Uint len_code,
+ unsigned tag, BeamInstr* result)
{
Uint count;
Sint val;
@@ -4371,17 +4299,62 @@ get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result)
if (len_code < 7) {
count = len_code + 2;
} else {
- Uint tag;
+ unsigned sztag;
UWord len_word;
ASSERT(len_code == 7);
- GetTagAndValue(stp, tag, len_word);
- VerifyTag(stp, TAG_u, tag);
+ GetTagAndValue(stp, sztag, len_word);
+ VerifyTag(stp, sztag, TAG_u);
count = len_word + 9;
}
/*
- * Handle values up to the size of an int, meaning either a small or bignum.
+ * The value for tags except TAG_i must be an unsigned integer
+ * fitting in an Uint. If it does not fit, we'll indicate overflow
+ * by changing the tag to TAG_o.
+ */
+
+ if (tag != TAG_i) {
+ if (count == sizeof(Uint)+1) {
+ Uint msb;
+
+ /*
+ * The encoded value has one more byte than an Uint.
+ * It will still fit in an Uint if the most significant
+ * byte is 0.
+ */
+ GetByte(stp, msb);
+ GetInt(stp, sizeof(Uint), *result);
+ if (msb != 0) {
+ /* Overflow: Negative or too big. */
+ return TAG_o;
+ }
+ } else if (count == sizeof(Uint)) {
+ /*
+ * The value must be positive (or the encoded value would
+ * have been one byte longer).
+ */
+ GetInt(stp, count, *result);
+ } else if (count < sizeof(Uint)) {
+ GetInt(stp, count, *result);
+
+ /*
+ * If the sign bit is set, the value is negative
+ * (not allowed).
+ */
+ if (*result & ((Uint)1 << (count*8-1))) {
+ return TAG_o;
+ }
+ } else {
+ GetInt(stp, count, *result);
+ return TAG_o;
+ }
+ return tag;
+ }
+
+ /*
+ * TAG_i: First handle values up to the size of an Uint (i.e. either
+ * a small or a bignum).
*/
if (count <= sizeof(val)) {
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index d9dd80fa8b..b171e99e03 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -802,6 +802,12 @@ bif prim_file:internal_name2native/1
bif prim_file:internal_native2name/1
bif prim_file:internal_normalize_utf8/1
bif file:native_name_encoding/0
+
+#
+# New in R14B04.
+#
+bif erlang:check_old_code/1
+
#
# Obsolete
#
diff --git a/erts/emulator/beam/erl_afit_alloc.c b/erts/emulator/beam/erl_afit_alloc.c
index e8b594bb47..d397cd8848 100644
--- a/erts/emulator/beam/erl_afit_alloc.c
+++ b/erts/emulator/beam/erl_afit_alloc.c
@@ -43,9 +43,9 @@
/* Prototypes of callback functions */
static Block_t * get_free_block (Allctr_t *, Uint,
- Block_t *, Uint);
-static void link_free_block (Allctr_t *, Block_t *);
-static void unlink_free_block (Allctr_t *, Block_t *);
+ Block_t *, Uint, Uint32);
+static void link_free_block (Allctr_t *, Block_t *, Uint32);
+static void unlink_free_block (Allctr_t *, Block_t *, Uint32);
static Eterm info_options (Allctr_t *, char *, int *,
@@ -72,6 +72,8 @@ erts_afalc_start(AFAllctr_t *afallctr,
is a struct). */
Allctr_t *allctr = (Allctr_t *) afallctr;
+ init->sbmbct = 0; /* Small mbc not supported by afit */
+
sys_memcpy((void *) afallctr, (void *) &nulled_state, sizeof(AFAllctr_t));
allctr->mbc_header_size = sizeof(Carrier_t);
@@ -105,7 +107,8 @@ erts_afalc_start(AFAllctr_t *afallctr,
}
static Block_t *
-get_free_block(Allctr_t *allctr, Uint size, Block_t *cand_blk, Uint cand_size)
+get_free_block(Allctr_t *allctr, Uint size, Block_t *cand_blk, Uint cand_size,
+ Uint32 flags)
{
AFAllctr_t *afallctr = (AFAllctr_t *) allctr;
@@ -123,7 +126,7 @@ get_free_block(Allctr_t *allctr, Uint size, Block_t *cand_blk, Uint cand_size)
}
static void
-link_free_block(Allctr_t *allctr, Block_t *block)
+link_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
AFFreeBlock_t *blk = (AFFreeBlock_t *) block;
AFAllctr_t *afallctr = (AFAllctr_t *) allctr;
@@ -144,7 +147,7 @@ link_free_block(Allctr_t *allctr, Block_t *block)
}
static void
-unlink_free_block(Allctr_t *allctr, Block_t *block)
+unlink_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
AFFreeBlock_t *blk = (AFFreeBlock_t *) block;
AFAllctr_t *afallctr = (AFAllctr_t *) allctr;
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index cda404af5e..bbc8a445a7 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -50,6 +50,9 @@
#include "erl_bestfit_alloc.h"
#define GET_ERL_AF_ALLOC_IMPL
#include "erl_afit_alloc.h"
+#define GET_ERL_AOFF_ALLOC_IMPL
+#include "erl_ao_firstfit_alloc.h"
+
#define ERTS_ALC_DEFAULT_MAX_THR_PREF 16
@@ -85,15 +88,19 @@ typedef union {
char align_bfa[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(BFAllctr_t))];
AFAllctr_t afa;
char align_afa[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(AFAllctr_t))];
+ AOFFAllctr_t aoffa;
+ char align_aoffa[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(AOFFAllctr_t))];
} ErtsAllocatorState_t;
-static ErtsAllocatorState_t sl_alloc_state;
+static ErtsAllocatorState_t sbmbc_alloc_state;
static ErtsAllocatorState_t std_alloc_state;
static ErtsAllocatorState_t ll_alloc_state;
#if HALFWORD_HEAP
-static ErtsAllocatorState_t std_alloc_low_state;
-static ErtsAllocatorState_t ll_alloc_low_state;
+static ErtsAllocatorState_t sbmbc_low_alloc_state;
+static ErtsAllocatorState_t std_low_alloc_state;
+static ErtsAllocatorState_t ll_low_alloc_state;
#endif
+static ErtsAllocatorState_t sl_alloc_state;
static ErtsAllocatorState_t temp_alloc_state;
static ErtsAllocatorState_t eheap_alloc_state;
static ErtsAllocatorState_t binary_alloc_state;
@@ -120,7 +127,8 @@ static void *fix_core_alloc(Uint size)
enum allctr_type {
GOODFIT,
BESTFIT,
- AFIT
+ AFIT,
+ AOFIRSTFIT
};
struct au_init {
@@ -132,6 +140,7 @@ struct au_init {
GFAllctrInit_t gf;
BFAllctrInit_t bf;
AFAllctrInit_t af;
+ AOFFAllctrInit_t aoff;
} init;
struct {
int mmbcs;
@@ -145,7 +154,8 @@ struct au_init {
ERTS_DEFAULT_ALLCTR_INIT, \
ERTS_DEFAULT_GF_ALLCTR_INIT, \
ERTS_DEFAULT_BF_ALLCTR_INIT, \
- ERTS_DEFAULT_AF_ALLCTR_INIT \
+ ERTS_DEFAULT_AF_ALLCTR_INIT, \
+ ERTS_DEFAULT_AOFF_ALLCTR_INIT \
}
typedef struct {
@@ -162,6 +172,7 @@ typedef struct {
char *mtrace;
char *nodename;
} instr;
+ struct au_init sbmbc_alloc;
struct au_init sl_alloc;
struct au_init std_alloc;
struct au_init ll_alloc;
@@ -171,8 +182,9 @@ typedef struct {
struct au_init ets_alloc;
struct au_init driver_alloc;
#if HALFWORD_HEAP
- struct au_init std_alloc_low;
- struct au_init ll_alloc_low;
+ struct au_init sbmbc_low_alloc;
+ struct au_init std_low_alloc;
+ struct au_init ll_low_alloc;
#endif
} erts_alc_hndl_args_init_t;
@@ -185,6 +197,34 @@ do { \
} while (0)
static void
+set_default_sbmbc_alloc_opts(struct au_init *ip)
+{
+ SET_DEFAULT_ALLOC_OPTS(ip);
+ ip->enable = 0;
+ ip->thr_spec = 0;
+ ip->atype = BESTFIT;
+ ip->init.bf.ao = 1;
+ ip->init.util.ramv = 0;
+ ip->init.util.mmsbc = 0;
+ ip->init.util.mmmbc = 500;
+ ip->init.util.sbct = ~((UWord) 0);
+ ip->init.util.name_prefix = "sbmbc_";
+ ip->init.util.alloc_no = ERTS_ALC_A_SBMBC;
+#ifndef SMALL_MEMORY
+ ip->init.util.mmbcs = 2*1024*1024; /* Main carrier size */
+#else
+ ip->init.util.mmbcs = 1*1024*1024; /* Main carrier size */
+#endif
+ ip->init.util.ts = ERTS_ALC_MTA_SBMBC;
+ ip->init.util.asbcst = 0;
+ ip->init.util.rsbcst = 0;
+ ip->init.util.rsbcmt = 0;
+ ip->init.util.rmbcmt = 0;
+ ip->init.util.sbmbct = 0;
+ ip->init.util.sbmbcs = 0;
+}
+
+static void
set_default_sl_alloc_opts(struct au_init *ip)
{
SET_DEFAULT_ALLOC_OPTS(ip);
@@ -202,6 +242,7 @@ set_default_sl_alloc_opts(struct au_init *ip)
ip->init.util.ts = ERTS_ALC_MTA_SHORT_LIVED;
ip->init.util.rsbcst = 80;
#if HALFWORD_HEAP
+ ip->init.util.force = 1;
ip->init.util.low_mem = 1;
#endif
@@ -249,6 +290,8 @@ set_default_ll_alloc_opts(struct au_init *ip)
ip->init.util.rsbcst = 0;
ip->init.util.rsbcmt = 0;
ip->init.util.rmbcmt = 0;
+ ip->init.util.sbmbct = 0;
+ ip->init.util.sbmbcs = 0;
}
static void
@@ -269,6 +312,7 @@ set_default_temp_alloc_opts(struct au_init *ip)
ip->init.util.rsbcst = 90;
ip->init.util.rmbcmt = 100;
#if HALFWORD_HEAP
+ ip->init.util.force = 1;
ip->init.util.low_mem = 1;
#endif
}
@@ -291,6 +335,7 @@ set_default_eheap_alloc_opts(struct au_init *ip)
ip->init.util.ts = ERTS_ALC_MTA_EHEAP;
ip->init.util.rsbcst = 50;
#if HALFWORD_HEAP
+ ip->init.util.force = 1;
ip->init.util.low_mem = 1;
#endif
}
@@ -436,10 +481,13 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
hdbg_init();
#endif
+ erts_have_sbmbc_alloc = 0;
+
erts_sys_alloc_init();
init_thr_ix(erts_no_schedulers);
erts_init_utils_mem();
+ set_default_sbmbc_alloc_opts(&init.sbmbc_alloc);
set_default_sl_alloc_opts(&init.sl_alloc);
set_default_std_alloc_opts(&init.std_alloc);
set_default_ll_alloc_opts(&init.ll_alloc);
@@ -453,6 +501,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
handle_args(argc, argv, &init);
if (erts_no_schedulers <= 1) {
+ init.sbmbc_alloc.thr_spec = 0;
init.sl_alloc.thr_spec = 0;
init.std_alloc.thr_spec = 0;
init.ll_alloc.thr_spec = 0;
@@ -464,6 +513,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
if (init.erts_alloc_config) {
/* Adjust flags that erts_alloc_config won't like */
+ init.sbmbc_alloc.thr_spec = 0;
init.temp_alloc.thr_spec = 0;
init.sl_alloc.thr_spec = 0;
init.std_alloc.thr_spec = 0;
@@ -480,6 +530,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
init.temp_alloc.thr_spec = erts_no_schedulers;
/* Others must use thread preferred interface */
+ adjust_tpref(&init.sbmbc_alloc, erts_no_schedulers);
adjust_tpref(&init.sl_alloc, erts_no_schedulers);
adjust_tpref(&init.std_alloc, erts_no_schedulers);
adjust_tpref(&init.ll_alloc, erts_no_schedulers);
@@ -497,6 +548,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
* The following allocators cannot be run with afit strategy.
* Make sure they don't...
*/
+ refuse_af_strategy(&init.sbmbc_alloc);
refuse_af_strategy(&init.sl_alloc);
refuse_af_strategy(&init.std_alloc);
refuse_af_strategy(&init.ll_alloc);
@@ -518,6 +570,7 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
erts_afalc_init();
erts_bfalc_init();
erts_gfalc_init();
+ erts_aoffalc_init();
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
erts_allctrs[i].alloc = NULL;
@@ -551,19 +604,30 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
#if HALFWORD_HEAP
/* Init low memory variants by cloning */
- init.std_alloc_low = init.std_alloc;
- init.std_alloc_low.init.util.alloc_no = ERTS_ALC_A_STANDARD_LOW;
- init.std_alloc_low.init.util.low_mem = 1;
-
- init.ll_alloc_low = init.ll_alloc;
- init.ll_alloc_low.init.util.alloc_no = ERTS_ALC_A_LONG_LIVED_LOW;
- init.ll_alloc_low.init.util.low_mem = 1;
-
- set_au_allocator(ERTS_ALC_A_STANDARD_LOW, &init.std_alloc_low);
- set_au_allocator(ERTS_ALC_A_LONG_LIVED_LOW, &init.ll_alloc_low);
+ init.sbmbc_low_alloc = init.sbmbc_alloc;
+ init.sbmbc_low_alloc.init.util.name_prefix = "sbmbc_low_";
+ init.sbmbc_low_alloc.init.util.alloc_no = ERTS_ALC_A_SBMBC_LOW;
+ init.sbmbc_low_alloc.init.util.low_mem = 1;
+
+ init.std_low_alloc = init.std_alloc;
+ init.std_low_alloc.init.util.name_prefix = "std_low_";
+ init.std_low_alloc.init.util.alloc_no = ERTS_ALC_A_STANDARD_LOW;
+ init.std_low_alloc.init.util.force = 1;
+ init.std_low_alloc.init.util.low_mem = 1;
+
+ init.ll_low_alloc = init.ll_alloc;
+ init.ll_low_alloc.init.util.name_prefix = "ll_low_";
+ init.ll_low_alloc.init.util.alloc_no = ERTS_ALC_A_LONG_LIVED_LOW;
+ init.ll_low_alloc.init.util.force = 1;
+ init.ll_low_alloc.init.util.low_mem = 1;
+
+ set_au_allocator(ERTS_ALC_A_SBMBC_LOW, &init.sbmbc_low_alloc);
+ set_au_allocator(ERTS_ALC_A_STANDARD_LOW, &init.std_low_alloc);
+ set_au_allocator(ERTS_ALC_A_LONG_LIVED_LOW, &init.ll_low_alloc);
#endif /* HALFWORD */
set_au_allocator(ERTS_ALC_A_TEMPORARY, &init.temp_alloc);
+ set_au_allocator(ERTS_ALC_A_SBMBC, &init.sbmbc_alloc);
set_au_allocator(ERTS_ALC_A_SHORT_LIVED, &init.sl_alloc);
set_au_allocator(ERTS_ALC_A_STANDARD, &init.std_alloc);
set_au_allocator(ERTS_ALC_A_LONG_LIVED, &init.ll_alloc);
@@ -593,6 +657,20 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
erts_mtrace_init(init.instr.mtrace, init.instr.nodename);
+ /* sbmbc_alloc() needs to be started first */
+ start_au_allocator(ERTS_ALC_A_SBMBC,
+ &init.sbmbc_alloc,
+ &sbmbc_alloc_state);
+#if HALFWORD_HEAP
+ start_au_allocator(ERTS_ALC_A_SBMBC_LOW,
+ &init.sbmbc_low_alloc,
+ &sbmbc_low_alloc_state);
+ erts_have_sbmbc_alloc = (init.sbmbc_alloc.enable
+ && init.sbmbc_low_alloc.enable);
+#else
+ erts_have_sbmbc_alloc = init.sbmbc_alloc.enable;
+#endif
+
start_au_allocator(ERTS_ALC_A_TEMPORARY,
&init.temp_alloc,
&temp_alloc_state);
@@ -610,11 +688,11 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
&ll_alloc_state);
#if HALFWORD_HEAP
start_au_allocator(ERTS_ALC_A_LONG_LIVED_LOW,
- &init.ll_alloc_low,
- &ll_alloc_low_state);
+ &init.ll_low_alloc,
+ &ll_low_alloc_state);
start_au_allocator(ERTS_ALC_A_STANDARD_LOW,
- &init.std_alloc_low,
- &std_alloc_low_state);
+ &init.std_low_alloc,
+ &std_low_alloc_state);
#endif
start_au_allocator(ERTS_ALC_A_EHEAP,
&init.eheap_alloc,
@@ -680,14 +758,11 @@ set_au_allocator(ErtsAlcType_t alctr_n, struct au_init *init)
ErtsAllocatorInfo_t *ai = &erts_allctrs_info[alctr_n];
ErtsAllocatorThrSpec_t *tspec = &erts_allctr_thr_spec[alctr_n];
-#if HALFWORD_HEAP
- /* If halfword heap, silently ignore any disabling of internal
- * allocators for low memory
+ /*
+ * Some allocators are forced on if halfword heap is used.
*/
- if (init->init.util.low_mem) {
+ if (init->init.util.force)
init->enable = 1;
- }
-#endif
if (!init->enable) {
af->alloc = erts_sys_alloc;
@@ -837,6 +912,12 @@ start_au_allocator(ErtsAlcType_t alctr_n,
&init->init.af,
&init->init.util);
break;
+ case AOFIRSTFIT:
+ as = (void *) erts_aoffalc_start((AOFFAllctr_t *) as0,
+ &init->init.aoff,
+ &init->init.util);
+ break;
+
default:
as = NULL;
ASSERT(0);
@@ -947,6 +1028,20 @@ get_kb_value(char *param_end, char** argv, int* ip)
}
static Uint
+get_byte_value(char *param_end, char** argv, int* ip)
+{
+ Sint tmp;
+ char *rest;
+ char *param = argv[*ip]+1;
+ char *value = get_value(param_end, argv, ip);
+ errno = 0;
+ tmp = (Sint) strtol(value, &rest, 10);
+ if (errno != 0 || rest == value || tmp < 0)
+ bad_value(param, param_end, value);
+ return (Uint) tmp;
+}
+
+static Uint
get_amount_value(char *param_end, char** argv, int* ip)
{
Sint tmp;
@@ -1017,6 +1112,9 @@ handle_au_arg(struct au_init *auip,
else if (strcmp("af", alg) == 0) {
auip->atype = AFIT;
}
+ else if (strcmp("aoff", alg) == 0) {
+ auip->atype = AOFIRSTFIT;
+ }
else {
bad_value(param, sub_param + 1, alg);
}
@@ -1085,6 +1183,12 @@ handle_au_arg(struct au_init *auip,
if(has_prefix("sbct", sub_param)) {
auip->init.util.sbct = get_kb_value(sub_param + 4, argv, ip);
}
+ else if (has_prefix("sbmbcs", sub_param)) {
+ auip->init.util.sbmbcs = get_byte_value(sub_param + 6, argv, ip);
+ }
+ else if (has_prefix("sbmbct", sub_param)) {
+ auip->init.util.sbmbct = get_byte_value(sub_param + 6, argv, ip);
+ }
else if (has_prefix("smbcs", sub_param)) {
auip->default_.smbcs = 0;
auip->init.util.smbcs = get_kb_value(sub_param + 5, argv, ip);
@@ -1123,6 +1227,7 @@ static void
handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
{
struct au_init *aui[] = {
+ &init->sbmbc_alloc,
&init->binary_alloc,
&init->std_alloc,
&init->ets_alloc,
@@ -1150,6 +1255,9 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
case 'B':
handle_au_arg(&init->binary_alloc, &argv[i][3], argv, &i);
break;
+ case 'C':
+ handle_au_arg(&init->sbmbc_alloc, &argv[i][3], argv, &i);
+ break;
case 'D':
handle_au_arg(&init->std_alloc, &argv[i][3], argv, &i);
break;
@@ -1856,12 +1964,16 @@ 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 except sbmbc_alloc *have* to be enabled */
for (ai = ERTS_ALC_A_MIN; ai <= ERTS_ALC_A_MAX; ai++) {
switch (ai) {
case ERTS_ALC_A_SYSTEM:
case ERTS_ALC_A_FIXED_SIZE:
+ case ERTS_ALC_A_SBMBC:
+#if HALFWORD_HEAP
+ case ERTS_ALC_A_SBMBC_LOW:
+#endif
break;
default:
if (!erts_allctrs_info[ai].enabled
@@ -1901,6 +2013,12 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
* Often not thread safe and usually never
* contain any allocated memory.
*/
+ case ERTS_ALC_A_SBMBC:
+ /* Included in other allocators */
+#if HALFWORD_HEAP
+ case ERTS_ALC_A_SBMBC_LOW:
+ /* Included in other allocators */
+#endif
continue;
case ERTS_ALC_A_EHEAP:
save = &size.processes;
@@ -2882,6 +3000,7 @@ unsigned long erts_alc_test(unsigned long op,
case 0x2: return erts_bfalc_test(op, a1, a2);
case 0x3: return erts_afalc_test(op, a1, a2);
case 0x4: return erts_mseg_test(op, a1, a2, a3);
+ case 0x5: return erts_aoffalc_test(op, a1, a2);
case 0xf:
switch (op) {
case 0xf00:
@@ -2925,6 +3044,7 @@ unsigned long erts_alc_test(unsigned long op,
init.atype = GOODFIT;
init.init.util.name_prefix = (char *) a1;
init.init.util.ts = a2 ? 1 : 0;
+ init.init.util.sbmbct = 0;
if ((char **) a3) {
char **argv = (char **) a3;
@@ -2960,6 +3080,14 @@ unsigned long erts_alc_test(unsigned long op,
&init.init.af,
&init.init.util);
break;
+ case AOFIRSTFIT:
+ allctr = erts_aoffalc_start((AOFFAllctr_t *)
+ erts_alloc(ERTS_ALC_T_UNDEF,
+ sizeof(AOFFAllctr_t)),
+ &init.init.aoff,
+ &init.init.util);
+ break;
+
default:
ASSERT(0);
allctr = NULL;
diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index ce792d4d17..c35a60da22 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -99,6 +99,14 @@ unsigned long erts_alc_test(unsigned long,
#define ERTS_ALC_MIN_LONG_LIVED_TIME (10*60*1000)
+#if HALFWORD_HEAP
+#define ERTS_IS_SBMBC_ALLOCATOR_NO__(NO) \
+ ((NO) == ERTS_ALC_A_SBMBC || (NO) == ERTS_ALC_A_SBMBC_LOW)
+#else
+#define ERTS_IS_SBMBC_ALLOCATOR_NO__(NO) \
+ ((NO) == ERTS_ALC_A_SBMBC)
+#endif
+
typedef struct {
int alloc_util;
int enabled;
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index c6cc0e1fac..eda0831441 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -65,6 +65,11 @@
allocator SYSTEM true sys_alloc
+allocator SBMBC true sbmbc_alloc
++if halfword
+allocator SBMBC_LOW true sbmbc_low_alloc
++endif
+
+if smp
allocator TEMPORARY true temp_alloc
@@ -76,8 +81,8 @@ allocator ETS true ets_alloc
allocator FIXED_SIZE true fix_alloc
+if halfword
-allocator LONG_LIVED_LOW true ll_alloc_low
-allocator STANDARD_LOW true std_alloc_low
+allocator LONG_LIVED_LOW true ll_low_alloc
+allocator STANDARD_LOW true std_low_alloc
+endif
+else # Non smp build
@@ -91,8 +96,8 @@ allocator ETS false ets_alloc
allocator FIXED_SIZE false fix_alloc
+if halfword
-allocator LONG_LIVED_LOW false ll_alloc_low
-allocator STANDARD_LOW false std_alloc_low
+allocator LONG_LIVED_LOW false ll_low_alloc
+allocator STANDARD_LOW false std_low_alloc
+endif
+endif
@@ -134,6 +139,7 @@ class SYSTEM system_data
#
# <TYPE> <ALLOCATOR> <CLASS> <DESCRIPTION>
+type SBMBC SBMBC SYSTEM small_block_mbc
type PROC FIXED_SIZE PROCESSES proc
type ATOM FIXED_SIZE ATOM atom_entry
type MODULE FIXED_SIZE CODE module_entry
@@ -330,6 +336,7 @@ type SSB SHORT_LIVED PROCESSES ssb
+if halfword
+type SBMBC_LOW SBMBC_LOW SYSTEM small_block_mbc_low
type DDLL_PROCESS STANDARD_LOW SYSTEM ddll_processes
type MONITOR_LH STANDARD_LOW PROCESSES monitor_lh
type NLINK_LH STANDARD_LOW PROCESSES nlink_lh
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index cc04ef65bf..d51ed0c36d 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -66,6 +66,7 @@
static int atoms_initialized = 0;
static int initialized = 0;
+int erts_have_sbmbc_alloc;
#if HAVE_ERTS_MSEG
@@ -85,8 +86,6 @@ static int initialized = 0;
#undef ASSERT
#define ASSERT ASSERT_EXPR
-#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE ((UWord) 1)
-
#if 0
/* Can be useful for debugging */
#define MBC_REALLOC_ALWAYS_MOVES
@@ -275,14 +274,26 @@ static void check_blk_carrier(Allctr_t *, Block_t *);
#ifdef DEBUG
#define DEBUG_CHECK_CARRIER_NO_SZ(AP) \
- ASSERT(((AP)->sbcs.curr_mseg.no && (AP)->sbcs.curr_mseg.size) \
- || (!(AP)->sbcs.curr_mseg.no && !(AP)->sbcs.curr_mseg.size));\
- ASSERT(((AP)->sbcs.curr_sys_alloc.no && (AP)->sbcs.curr_sys_alloc.size)\
- || (!(AP)->sbcs.curr_sys_alloc.no && !(AP)->sbcs.curr_sys_alloc.size));\
- ASSERT(((AP)->mbcs.curr_mseg.no && (AP)->mbcs.curr_mseg.size) \
- || (!(AP)->mbcs.curr_mseg.no && !(AP)->mbcs.curr_mseg.size));\
- ASSERT(((AP)->mbcs.curr_sys_alloc.no && (AP)->mbcs.curr_sys_alloc.size)\
- || (!(AP)->mbcs.curr_sys_alloc.no && !(AP)->mbcs.curr_sys_alloc.size))
+ ASSERT(((AP)->sbcs.curr.norm.mseg.no \
+ && (AP)->sbcs.curr.norm.mseg.size) \
+ || (!(AP)->sbcs.curr.norm.mseg.no \
+ && !(AP)->sbcs.curr.norm.mseg.size)); \
+ ASSERT(((AP)->sbcs.curr.norm.sys_alloc.no \
+ && (AP)->sbcs.curr.norm.sys_alloc.size) \
+ || (!(AP)->sbcs.curr.norm.sys_alloc.no \
+ && !(AP)->sbcs.curr.norm.sys_alloc.size)); \
+ ASSERT(((AP)->mbcs.curr.norm.mseg.no \
+ && (AP)->mbcs.curr.norm.mseg.size) \
+ || (!(AP)->mbcs.curr.norm.mseg.no \
+ && !(AP)->mbcs.curr.norm.mseg.size)); \
+ ASSERT(((AP)->mbcs.curr.norm.sys_alloc.no \
+ && (AP)->mbcs.curr.norm.sys_alloc.size) \
+ || (!(AP)->mbcs.curr.norm.sys_alloc.no \
+ && !(AP)->mbcs.curr.norm.sys_alloc.size)); \
+ ASSERT(((AP)->sbmbcs.curr.small_block.no \
+ && (AP)->sbmbcs.curr.small_block.size) \
+ || (!(AP)->sbmbcs.curr.small_block.no \
+ && !(AP)->sbmbcs.curr.small_block.size))
#else
#define DEBUG_CHECK_CARRIER_NO_SZ(AP)
@@ -292,27 +303,27 @@ static void check_blk_carrier(Allctr_t *, Block_t *);
(AP)->sbcs.blocks.curr.size += (BSZ); \
if ((AP)->sbcs.blocks.max.size < (AP)->sbcs.blocks.curr.size) \
(AP)->sbcs.blocks.max.size = (AP)->sbcs.blocks.curr.size; \
- if ((AP)->sbcs.max.no < ((AP)->sbcs.curr_mseg.no \
- + (AP)->sbcs.curr_sys_alloc.no)) \
- (AP)->sbcs.max.no = ((AP)->sbcs.curr_mseg.no \
- + (AP)->sbcs.curr_sys_alloc.no); \
- if ((AP)->sbcs.max.size < ((AP)->sbcs.curr_mseg.size \
- + (AP)->sbcs.curr_sys_alloc.size)) \
- (AP)->sbcs.max.size = ((AP)->sbcs.curr_mseg.size \
- + (AP)->sbcs.curr_sys_alloc.size)
+ if ((AP)->sbcs.max.no < ((AP)->sbcs.curr.norm.mseg.no \
+ + (AP)->sbcs.curr.norm.sys_alloc.no)) \
+ (AP)->sbcs.max.no = ((AP)->sbcs.curr.norm.mseg.no \
+ + (AP)->sbcs.curr.norm.sys_alloc.no); \
+ if ((AP)->sbcs.max.size < ((AP)->sbcs.curr.norm.mseg.size \
+ + (AP)->sbcs.curr.norm.sys_alloc.size)) \
+ (AP)->sbcs.max.size = ((AP)->sbcs.curr.norm.mseg.size \
+ + (AP)->sbcs.curr.norm.sys_alloc.size)
#define STAT_MSEG_SBC_ALLOC(AP, CSZ, BSZ) \
do { \
- (AP)->sbcs.curr_mseg.no++; \
- (AP)->sbcs.curr_mseg.size += (CSZ); \
+ (AP)->sbcs.curr.norm.mseg.no++; \
+ (AP)->sbcs.curr.norm.mseg.size += (CSZ); \
STAT_SBC_ALLOC((AP), (BSZ)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
#define STAT_SYS_ALLOC_SBC_ALLOC(AP, CSZ, BSZ) \
do { \
- (AP)->sbcs.curr_sys_alloc.no++; \
- (AP)->sbcs.curr_sys_alloc.size += (CSZ); \
+ (AP)->sbcs.curr.norm.sys_alloc.no++; \
+ (AP)->sbcs.curr.norm.sys_alloc.size += (CSZ); \
STAT_SBC_ALLOC((AP), (BSZ)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
@@ -324,85 +335,111 @@ do { \
#define STAT_MSEG_SBC_FREE(AP, CSZ, BSZ) \
do { \
- ASSERT((AP)->sbcs.curr_mseg.no > 0); \
- (AP)->sbcs.curr_mseg.no--; \
- ASSERT((AP)->sbcs.curr_mseg.size >= (CSZ)); \
- (AP)->sbcs.curr_mseg.size -= (CSZ); \
+ ASSERT((AP)->sbcs.curr.norm.mseg.no > 0); \
+ (AP)->sbcs.curr.norm.mseg.no--; \
+ ASSERT((AP)->sbcs.curr.norm.mseg.size >= (CSZ)); \
+ (AP)->sbcs.curr.norm.mseg.size -= (CSZ); \
STAT_SBC_FREE((AP), (BSZ)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
#define STAT_SYS_ALLOC_SBC_FREE(AP, CSZ, BSZ) \
do { \
- ASSERT((AP)->sbcs.curr_sys_alloc.no > 0); \
- (AP)->sbcs.curr_sys_alloc.no--; \
- ASSERT((AP)->sbcs.curr_sys_alloc.size >= (CSZ)); \
- (AP)->sbcs.curr_sys_alloc.size -= (CSZ); \
+ ASSERT((AP)->sbcs.curr.norm.sys_alloc.no > 0); \
+ (AP)->sbcs.curr.norm.sys_alloc.no--; \
+ ASSERT((AP)->sbcs.curr.norm.sys_alloc.size >= (CSZ)); \
+ (AP)->sbcs.curr.norm.sys_alloc.size -= (CSZ); \
STAT_SBC_FREE((AP), (BSZ)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
#define STAT_MBC_ALLOC(AP) \
- if ((AP)->mbcs.max.no < ((AP)->mbcs.curr_mseg.no \
- + (AP)->mbcs.curr_sys_alloc.no)) \
- (AP)->mbcs.max.no = ((AP)->mbcs.curr_mseg.no \
- + (AP)->mbcs.curr_sys_alloc.no); \
- if ((AP)->mbcs.max.size < ((AP)->mbcs.curr_mseg.size \
- + (AP)->mbcs.curr_sys_alloc.size)) \
- (AP)->mbcs.max.size = ((AP)->mbcs.curr_mseg.size \
- + (AP)->mbcs.curr_sys_alloc.size)
+ if ((AP)->mbcs.max.no < ((AP)->mbcs.curr.norm.mseg.no \
+ + (AP)->mbcs.curr.norm.sys_alloc.no)) \
+ (AP)->mbcs.max.no = ((AP)->mbcs.curr.norm.mseg.no \
+ + (AP)->mbcs.curr.norm.sys_alloc.no); \
+ if ((AP)->mbcs.max.size < ((AP)->mbcs.curr.norm.mseg.size \
+ + (AP)->mbcs.curr.norm.sys_alloc.size)) \
+ (AP)->mbcs.max.size = ((AP)->mbcs.curr.norm.mseg.size \
+ + (AP)->mbcs.curr.norm.sys_alloc.size)
+
+#define STAT_SBMBC_ALLOC(AP, CSZ) \
+do { \
+ (AP)->sbmbcs.curr.small_block.no++; \
+ (AP)->sbmbcs.curr.small_block.size += (CSZ); \
+ if ((AP)->sbmbcs.max.no < (AP)->sbmbcs.curr.small_block.no) \
+ (AP)->sbmbcs.max.no = (AP)->sbmbcs.curr.small_block.no; \
+ if ((AP)->sbmbcs.max.size < (AP)->sbmbcs.curr.small_block.size) \
+ (AP)->sbmbcs.max.size = (AP)->sbmbcs.curr.small_block.size; \
+ DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
+} while (0)
#define STAT_MSEG_MBC_ALLOC(AP, CSZ) \
do { \
- (AP)->mbcs.curr_mseg.no++; \
- (AP)->mbcs.curr_mseg.size += (CSZ); \
+ (AP)->mbcs.curr.norm.mseg.no++; \
+ (AP)->mbcs.curr.norm.mseg.size += (CSZ); \
STAT_MBC_ALLOC((AP)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
#define STAT_SYS_ALLOC_MBC_ALLOC(AP, CSZ) \
do { \
- (AP)->mbcs.curr_sys_alloc.no++; \
- (AP)->mbcs.curr_sys_alloc.size += (CSZ); \
+ (AP)->mbcs.curr.norm.sys_alloc.no++; \
+ (AP)->mbcs.curr.norm.sys_alloc.size += (CSZ); \
STAT_MBC_ALLOC((AP)); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
+#define STAT_SBMBC_FREE(AP, CSZ) \
+do { \
+ ASSERT((AP)->sbmbcs.curr.small_block.no > 0); \
+ (AP)->sbmbcs.curr.small_block.no--; \
+ ASSERT((AP)->sbmbcs.curr.small_block.size >= (CSZ)); \
+ (AP)->sbmbcs.curr.small_block.size -= (CSZ); \
+ DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
+} while (0)
+
#define STAT_MSEG_MBC_FREE(AP, CSZ) \
do { \
- ASSERT((AP)->mbcs.curr_mseg.no > 0); \
- (AP)->mbcs.curr_mseg.no--; \
- ASSERT((AP)->mbcs.curr_mseg.size >= (CSZ)); \
- (AP)->mbcs.curr_mseg.size -= (CSZ); \
+ ASSERT((AP)->mbcs.curr.norm.mseg.no > 0); \
+ (AP)->mbcs.curr.norm.mseg.no--; \
+ ASSERT((AP)->mbcs.curr.norm.mseg.size >= (CSZ)); \
+ (AP)->mbcs.curr.norm.mseg.size -= (CSZ); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
#define STAT_SYS_ALLOC_MBC_FREE(AP, CSZ) \
do { \
- ASSERT((AP)->mbcs.curr_sys_alloc.no > 0); \
- (AP)->mbcs.curr_sys_alloc.no--; \
- ASSERT((AP)->mbcs.curr_sys_alloc.size >= (CSZ)); \
- (AP)->mbcs.curr_sys_alloc.size -= (CSZ); \
+ ASSERT((AP)->mbcs.curr.norm.sys_alloc.no > 0); \
+ (AP)->mbcs.curr.norm.sys_alloc.no--; \
+ ASSERT((AP)->mbcs.curr.norm.sys_alloc.size >= (CSZ)); \
+ (AP)->mbcs.curr.norm.sys_alloc.size -= (CSZ); \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
-#define STAT_MBC_BLK_ALLOC(AP, BSZ) \
+#define STAT_MBC_BLK_ALLOC(AP, BSZ, FLGS) \
do { \
- (AP)->mbcs.blocks.curr.no++; \
- if ((AP)->mbcs.blocks.max.no < (AP)->mbcs.blocks.curr.no) \
- (AP)->mbcs.blocks.max.no = (AP)->mbcs.blocks.curr.no; \
- (AP)->mbcs.blocks.curr.size += (BSZ); \
- if ((AP)->mbcs.blocks.max.size < (AP)->mbcs.blocks.curr.size) \
- (AP)->mbcs.blocks.max.size = (AP)->mbcs.blocks.curr.size; \
+ CarriersStats_t *cstats__ = (((FLGS) & ERTS_ALCU_FLG_SBMBC) \
+ ? &(AP)->sbmbcs \
+ : &(AP)->mbcs); \
+ cstats__->blocks.curr.no++; \
+ if (cstats__->blocks.max.no < cstats__->blocks.curr.no) \
+ cstats__->blocks.max.no = cstats__->blocks.curr.no; \
+ cstats__->blocks.curr.size += (BSZ); \
+ if (cstats__->blocks.max.size < cstats__->blocks.curr.size) \
+ cstats__->blocks.max.size = cstats__->blocks.curr.size; \
} while (0)
-#define STAT_MBC_BLK_FREE(AP, BSZ) \
+#define STAT_MBC_BLK_FREE(AP, BSZ, FLGS) \
do { \
- ASSERT((AP)->mbcs.blocks.curr.no > 0); \
- (AP)->mbcs.blocks.curr.no--; \
- ASSERT((AP)->mbcs.blocks.curr.size >= (BSZ)); \
- (AP)->mbcs.blocks.curr.size -= (BSZ); \
+ CarriersStats_t *cstats__ = (((FLGS) & ERTS_ALCU_FLG_SBMBC) \
+ ? &(AP)->sbmbcs \
+ : &(AP)->mbcs); \
+ ASSERT(cstats__->blocks.curr.no > 0); \
+ cstats__->blocks.curr.no--; \
+ ASSERT(cstats__->blocks.curr.size >= (BSZ)); \
+ cstats__->blocks.curr.size -= (BSZ); \
} while (0)
/* Debug stuff... */
@@ -410,7 +447,7 @@ do { \
static UWord carrier_alignment;
#define DEBUG_SAVE_ALIGNMENT(C) \
do { \
- UWord algnmnt__ = sizeof(Unit_t) - (((UWord) (C)) % sizeof(Unit_t)); \
+ UWord algnmnt__ = sizeof(Unit_t) - (((UWord) (C)) % sizeof(Unit_t));\
carrier_alignment = MIN(carrier_alignment, algnmnt__); \
ASSERT(((UWord) (C)) % sizeof(UWord) == 0); \
} while (0)
@@ -524,8 +561,8 @@ static Uint
get_next_mbc_size(Allctr_t *allctr)
{
Uint size;
- int cs = (allctr->mbcs.curr_mseg.no
- + allctr->mbcs.curr_sys_alloc.no
+ int cs = (allctr->mbcs.curr.norm.mseg.no
+ + allctr->mbcs.curr.norm.sys_alloc.no
- (allctr->main_carrier ? 1 : 0));
ASSERT(cs >= 0);
@@ -609,7 +646,8 @@ unlink_carrier(CarrierList_t *cl, Carrier_t *crr)
}
}
-
+static Block_t *create_sbmbc(Allctr_t *allctr, Uint umem_sz);
+static void destroy_sbmbc(Allctr_t *allctr, Block_t *blk);
static Block_t *create_carrier(Allctr_t *, Uint, UWord);
static void destroy_carrier(Allctr_t *, Block_t *);
@@ -619,39 +657,57 @@ static void destroy_carrier(Allctr_t *, Block_t *);
* block in a sbc.
*/
static ERTS_INLINE void *
-mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp)
+mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp, Uint32 *alcu_flgsp)
{
Block_t *blk;
+ Uint get_blk_sz;
+ Uint sbmbct;
ASSERT(size);
ASSERT(size < allctr->sbc_threshold);
- *blk_szp = UMEMSZ2BLKSZ(allctr, size);
+ *blk_szp = get_blk_sz = UMEMSZ2BLKSZ(allctr, size);
+
+ sbmbct = allctr->sbmbc_threshold;
+ if (sbmbct) {
+ if (get_blk_sz < sbmbct) {
+ *alcu_flgsp |= ERTS_ALCU_FLG_SBMBC;
+ if (get_blk_sz + allctr->min_block_size > sbmbct) {
+ /* Since we use block size to determine if blocks are
+ located in sbmbc or not... */
+ get_blk_sz += allctr->min_block_size;
+ }
+ }
+ }
- blk = (*allctr->get_free_block)(allctr, *blk_szp, NULL, 0);
+ blk = (*allctr->get_free_block)(allctr, get_blk_sz, NULL, 0, *alcu_flgsp);
-#if HALFWORD_HEAP
if (!blk) {
- blk = create_carrier(allctr, *blk_szp, CFLG_MBC|CFLG_FORCE_MSEG);
- }
+ if ((*alcu_flgsp) & ERTS_ALCU_FLG_SBMBC)
+ blk = create_sbmbc(allctr, get_blk_sz);
+ else {
+#if HALFWORD_HEAP
+ blk = create_carrier(allctr, get_blk_sz, CFLG_MBC|CFLG_FORCE_MSEG);
#else
- if (!blk) {
- blk = create_carrier(allctr, *blk_szp, CFLG_MBC);
- if (!blk) {
- /* Emergency! We couldn't create the carrier as we wanted.
- Try to place it in a sys_alloced sbc. */
- blk = create_carrier(allctr,
- size,
- CFLG_SBC|CFLG_FORCE_SIZE|CFLG_FORCE_SYS_ALLOC);
+ blk = create_carrier(allctr, get_blk_sz, CFLG_MBC);
+ if (!blk) {
+ /* Emergency! We couldn't create the carrier as we wanted.
+ Try to place it in a sys_alloced sbc. */
+ blk = create_carrier(allctr,
+ size,
+ (CFLG_SBC
+ | CFLG_FORCE_SIZE
+ | CFLG_FORCE_SYS_ALLOC));
+ }
+#endif
}
}
-#endif
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
if (IS_MBC_BLK(blk)) {
- (*allctr->link_free_block)(allctr, blk);
+ (*allctr->link_free_block)(allctr, blk, *alcu_flgsp);
HARD_CHECK_BLK_CARRIER(allctr, blk);
- (*allctr->unlink_free_block)(allctr, blk);
+ (*allctr->unlink_free_block)(allctr, blk, *alcu_flgsp);
}
#endif
@@ -664,7 +720,8 @@ mbc_alloc_finalize(Allctr_t *allctr,
Uint org_blk_sz,
UWord flags,
Uint want_blk_sz,
- int valid_blk_info)
+ int valid_blk_info,
+ Uint32 alcu_flgs)
{
Uint blk_sz;
Uint nxt_blk_sz;
@@ -700,7 +757,7 @@ mbc_alloc_finalize(Allctr_t *allctr,
SET_PREV_BLK_FREE(nxt_nxt_blk);
}
}
- (*allctr->link_free_block)(allctr, nxt_blk);
+ (*allctr->link_free_block)(allctr, nxt_blk, alcu_flgs);
ASSERT(IS_NOT_LAST_BLK(blk));
ASSERT(IS_FREE_BLK(nxt_blk));
@@ -741,7 +798,7 @@ mbc_alloc_finalize(Allctr_t *allctr,
: IS_NOT_LAST_BLK(blk));
}
- STAT_MBC_BLK_ALLOC(allctr, blk_sz);
+ STAT_MBC_BLK_ALLOC(allctr, blk_sz, alcu_flgs);
ASSERT(IS_ALLOCED_BLK(blk));
ASSERT(blk_sz == BLK_SZ(blk));
@@ -761,7 +818,8 @@ mbc_alloc(Allctr_t *allctr, Uint size)
{
Block_t *blk;
Uint blk_sz;
- blk = mbc_alloc_block(allctr, size, &blk_sz);
+ Uint32 alcu_flgs = 0;
+ blk = mbc_alloc_block(allctr, size, &blk_sz, &alcu_flgs);
if (!blk)
return NULL;
if (IS_MBC_BLK(blk))
@@ -770,7 +828,8 @@ mbc_alloc(Allctr_t *allctr, Uint size)
BLK_SZ(blk),
GET_BLK_HDR_FLGS(blk),
blk_sz,
- 1);
+ 1,
+ alcu_flgs);
return BLK2UMEM(blk);
}
@@ -779,6 +838,7 @@ mbc_free(Allctr_t *allctr, void *p)
{
Uint is_first_blk;
Uint is_last_blk;
+ Uint32 alcu_flgs = 0;
Uint blk_sz;
Block_t *blk;
Block_t *nxt_blk;
@@ -788,13 +848,15 @@ mbc_free(Allctr_t *allctr, void *p)
blk = UMEM2BLK(p);
blk_sz = BLK_SZ(blk);
+ if (blk_sz < allctr->sbmbc_threshold)
+ alcu_flgs |= ERTS_ALCU_FLG_SBMBC;
ASSERT(IS_MBC_BLK(blk));
ASSERT(blk_sz >= allctr->min_block_size);
HARD_CHECK_BLK_CARRIER(allctr, blk);
- STAT_MBC_BLK_FREE(allctr, blk_sz);
+ STAT_MBC_BLK_FREE(allctr, blk_sz, alcu_flgs);
is_first_blk = IS_FIRST_BLK(blk);
is_last_blk = IS_LAST_BLK(blk);
@@ -802,7 +864,7 @@ mbc_free(Allctr_t *allctr, void *p)
if (!is_first_blk && IS_PREV_BLK_FREE(blk)) {
/* Coalesce with previous block... */
blk = PREV_BLK(blk);
- (*allctr->unlink_free_block)(allctr, blk);
+ (*allctr->unlink_free_block)(allctr, blk, alcu_flgs);
blk_sz += BLK_SZ(blk);
is_first_blk = IS_FIRST_BLK(blk);
@@ -818,7 +880,7 @@ mbc_free(Allctr_t *allctr, void *p)
nxt_blk = NXT_BLK(blk);
if (IS_FREE_BLK(nxt_blk)) {
/* Coalesce with next block... */
- (*allctr->unlink_free_block)(allctr, nxt_blk);
+ (*allctr->unlink_free_block)(allctr, nxt_blk, alcu_flgs);
blk_sz += BLK_SZ(nxt_blk);
SET_BLK_SZ(blk, blk_sz);
@@ -850,16 +912,20 @@ mbc_free(Allctr_t *allctr, void *p)
if (is_first_blk
&& is_last_blk
- && allctr->main_carrier != FBLK2MBC(allctr, blk))
- destroy_carrier(allctr, blk);
+ && allctr->main_carrier != FBLK2MBC(allctr, blk)) {
+ if (alcu_flgs & ERTS_ALCU_FLG_SBMBC)
+ destroy_sbmbc(allctr, blk);
+ else
+ destroy_carrier(allctr, blk);
+ }
else {
- (*allctr->link_free_block)(allctr, blk);
+ (*allctr->link_free_block)(allctr, blk, alcu_flgs);
HARD_CHECK_BLK_CARRIER(allctr, blk);
}
}
static void *
-mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
+mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint32 alcu_flgs)
{
void *new_p;
Uint old_blk_sz;
@@ -867,7 +933,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
#ifndef MBC_REALLOC_ALWAYS_MOVES
Block_t *new_blk, *cand_blk;
Uint cand_blk_sz;
- Uint blk_sz;
+ Uint blk_sz, get_blk_sz;
Block_t *nxt_blk;
Uint nxt_blk_sz;
Uint is_last_blk;
@@ -883,10 +949,16 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
ASSERT(old_blk_sz >= allctr->min_block_size);
#ifdef MBC_REALLOC_ALWAYS_MOVES
- if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
+ if (alcu_flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
#else /* !MBC_REALLOC_ALWAYS_MOVES */
- blk_sz = UMEMSZ2BLKSZ(allctr, size);
+ get_blk_sz = blk_sz = UMEMSZ2BLKSZ(allctr, size);
+ if ((alcu_flgs & ERTS_ALCU_FLG_SBMBC)
+ && (blk_sz + allctr->min_block_size > allctr->sbmbc_threshold)) {
+ /* Since we use block size to determine if blocks are
+ located in sbmbc or not... */
+ get_blk_sz = blk_sz + allctr->min_block_size;
+ }
ASSERT(IS_ALLOCED_BLK(blk));
ASSERT(IS_MBC_BLK(blk));
@@ -901,6 +973,9 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
Uint diff_sz_val = old_blk_sz - blk_sz;
Uint old_blk_sz_val = old_blk_sz;
+ if (get_blk_sz >= old_blk_sz)
+ return p;
+
if (diff_sz_val >= (~((Uint) 0) / 100)) {
/* div both by 128 */
old_blk_sz_val >>= 7;
@@ -909,7 +984,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
/* Avoid fragmentation by moving the block if it is shrunk much */
if (100*diff_sz_val > allctr->mbc_move_threshold*old_blk_sz_val) {
- if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
+ if (alcu_flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
cand_blk_sz = old_blk_sz;
@@ -926,9 +1001,10 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
}
new_blk = (*allctr->get_free_block)(allctr,
- blk_sz,
+ get_blk_sz,
cand_blk,
- cand_blk_sz);
+ cand_blk_sz,
+ alcu_flgs);
if (new_blk || cand_blk != blk)
goto move_into_new_blk;
@@ -952,8 +1028,8 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
nxt_blk_sz,
SBH_THIS_FREE|SBH_PREV_ALLOCED|SBH_NOT_LAST_BLK);
- STAT_MBC_BLK_FREE(allctr, old_blk_sz);
- STAT_MBC_BLK_ALLOC(allctr, blk_sz);
+ STAT_MBC_BLK_FREE(allctr, old_blk_sz, alcu_flgs);
+ STAT_MBC_BLK_ALLOC(allctr, blk_sz, alcu_flgs);
ASSERT(BLK_SZ(blk) >= allctr->min_block_size);
@@ -964,7 +1040,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
if (IS_FREE_BLK(nxt_nxt_blk)) {
/* Coalesce with next free block... */
nxt_blk_sz += BLK_SZ(nxt_nxt_blk);
- (*allctr->unlink_free_block)(allctr, nxt_nxt_blk);
+ (*allctr->unlink_free_block)(allctr, nxt_nxt_blk, alcu_flgs);
SET_BLK_SZ(nxt_blk, nxt_blk_sz);
is_last_blk = IS_LAST_BLK(nxt_nxt_blk);
@@ -979,7 +1055,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
}
}
- (*allctr->link_free_block)(allctr, nxt_blk);
+ (*allctr->link_free_block)(allctr, nxt_blk, alcu_flgs);
ASSERT(IS_ALLOCED_BLK(blk));
@@ -1009,12 +1085,12 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
if (!is_last_blk) {
nxt_blk = NXT_BLK(blk);
nxt_blk_sz = BLK_SZ(nxt_blk);
- if (IS_FREE_BLK(nxt_blk) && blk_sz <= old_blk_sz + nxt_blk_sz) {
+ if (IS_FREE_BLK(nxt_blk) && get_blk_sz <= old_blk_sz + nxt_blk_sz) {
/* Grow into next block... */
HARD_CHECK_BLK_CARRIER(allctr, blk);
- (*allctr->unlink_free_block)(allctr, nxt_blk);
+ (*allctr->unlink_free_block)(allctr, nxt_blk, alcu_flgs);
nxt_blk_sz -= blk_sz - old_blk_sz;
is_last_blk = IS_LAST_BLK(nxt_blk);
@@ -1051,13 +1127,13 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
else
SET_BLK_SZ_FTR(nxt_blk, nxt_blk_sz);
- (*allctr->link_free_block)(allctr, nxt_blk);
+ (*allctr->link_free_block)(allctr, nxt_blk, alcu_flgs);
ASSERT(IS_FREE_BLK(nxt_blk));
}
- STAT_MBC_BLK_FREE(allctr, old_blk_sz);
- STAT_MBC_BLK_ALLOC(allctr, blk_sz);
+ STAT_MBC_BLK_FREE(allctr, old_blk_sz, alcu_flgs);
+ STAT_MBC_BLK_ALLOC(allctr, blk_sz, alcu_flgs);
ASSERT(IS_ALLOCED_BLK(blk));
@@ -1088,7 +1164,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
}
}
- if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
+ if (alcu_flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
/* Need to grow in another block */
@@ -1108,7 +1184,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
}
}
- if (cand_blk_sz < blk_sz) {
+ if (cand_blk_sz < get_blk_sz) {
/* We wont fit in cand_blk get a new one */
#endif /* !MBC_REALLOC_ALWAYS_MOVES */
@@ -1127,9 +1203,10 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
/* We will at least fit in cand_blk */
new_blk = (*allctr->get_free_block)(allctr,
- blk_sz,
+ get_blk_sz,
cand_blk,
- cand_blk_sz);
+ cand_blk_sz,
+ alcu_flgs);
move_into_new_blk:
/*
* new_blk, and cand_blk have to be correctly set
@@ -1142,7 +1219,8 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
BLK_SZ(new_blk),
GET_BLK_HDR_FLGS(new_blk),
blk_sz,
- 1);
+ 1,
+ alcu_flgs);
new_p = BLK2UMEM(new_blk);
sys_memcpy(new_p, p, MIN(size, old_blk_sz - ABLK_HDR_SZ));
mbc_free(allctr, p);
@@ -1164,7 +1242,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
HARD_CHECK_BLK_CARRIER(allctr, blk);
- (*allctr->unlink_free_block)(allctr, new_blk); /* prev */
+ (*allctr->unlink_free_block)(allctr, new_blk, alcu_flgs); /* prev */
if (is_last_blk)
new_blk_flgs |= LAST_BLK_HDR_FLG;
@@ -1173,7 +1251,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
if (IS_FREE_BLK(nxt_blk)) {
new_blk_flgs |= GET_LAST_BLK_HDR_FLG(nxt_blk);
new_blk_sz += BLK_SZ(nxt_blk);
- (*allctr->unlink_free_block)(allctr, nxt_blk);
+ (*allctr->unlink_free_block)(allctr, nxt_blk, alcu_flgs);
}
}
@@ -1196,9 +1274,10 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
new_blk_sz,
new_blk_flgs,
blk_sz,
- 0);
+ 0,
+ alcu_flgs);
- STAT_MBC_BLK_FREE(allctr, old_blk_sz);
+ STAT_MBC_BLK_FREE(allctr, old_blk_sz, alcu_flgs);
return new_p;
}
@@ -1243,6 +1322,100 @@ do { \
#define CHECK_1BLK_CARRIER(A, SBC, MSEGED, C, CSZ, B, BSZ)
#endif
+static Block_t *
+create_sbmbc(Allctr_t *allctr, Uint umem_sz)
+{
+ Block_t *blk;
+ Uint blk_sz;
+ Uint crr_sz = allctr->sbmbc_size;
+ Carrier_t *crr;
+
+#if HALFWORD_HEAP
+ if (allctr->mseg_opt.low_mem)
+ crr = erts_alloc(ERTS_ALC_T_SBMBC_LOW, crr_sz);
+ else
+#endif
+ crr = erts_alloc(ERTS_ALC_T_SBMBC, crr_sz);
+
+ INC_CC(allctr->calls.sbmbc_alloc);
+ SET_CARRIER_HDR(crr, crr_sz, SCH_SYS_ALLOC|SCH_MBC);
+
+ blk = MBC2FBLK(allctr, crr);
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
+ crr_sz -= sizeof(UWord);
+#endif
+
+ blk_sz = UNIT_FLOOR(crr_sz - allctr->mbc_header_size);
+
+ SET_MBC_BLK_FTR(((UWord *) blk)[-1]);
+ SET_BLK_HDR(blk, blk_sz, SBH_THIS_FREE|SBH_PREV_FREE|SBH_LAST_BLK);
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ *((Carrier_t **) NXT_BLK(blk)) = crr;
+#endif
+
+ link_carrier(&allctr->sbmbc_list, crr);
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
+ crr_sz += sizeof(UWord);
+#endif
+
+ STAT_SBMBC_ALLOC(allctr, crr_sz);
+ CHECK_1BLK_CARRIER(allctr, 0, 0, crr, crr_sz, blk, blk_sz);
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
+ crr_sz -= sizeof(UWord);
+#endif
+ if (allctr->creating_mbc)
+ (*allctr->creating_mbc)(allctr, crr, ERTS_ALCU_FLG_SBMBC);
+
+ DEBUG_SAVE_ALIGNMENT(crr);
+ return blk;
+}
+
+static void
+destroy_sbmbc(Allctr_t *allctr, Block_t *blk)
+{
+ Uint crr_sz;
+ Carrier_t *crr;
+
+ ASSERT(IS_FIRST_BLK(blk));
+
+ ASSERT(IS_MBC_BLK(blk));
+
+ crr = FBLK2MBC(allctr, blk);
+ crr_sz = CARRIER_SZ(crr);
+
+#ifdef DEBUG
+ if (!allctr->stopped) {
+ ASSERT(IS_LAST_BLK(blk));
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ (*allctr->link_free_block)(allctr, blk, ERTS_ALCU_FLG_SBMBC);
+ HARD_CHECK_BLK_CARRIER(allctr, blk);
+ (*allctr->unlink_free_block)(allctr, blk, ERTS_ALCU_FLG_SBMBC);
+#endif
+ }
+#endif
+
+ STAT_SBMBC_FREE(allctr, crr_sz);
+
+ unlink_carrier(&allctr->sbmbc_list, crr);
+ if (allctr->destroying_mbc)
+ (*allctr->destroying_mbc)(allctr, crr, ERTS_ALCU_FLG_SBMBC);
+
+ INC_CC(allctr->calls.sbmbc_free);
+
+#if HALFWORD_HEAP
+ if (allctr->mseg_opt.low_mem)
+ erts_free(ERTS_ALC_T_SBMBC_LOW, crr);
+ else
+#endif
+ erts_free(ERTS_ALC_T_SBMBC, crr);
+}
static Block_t *
create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
@@ -1271,11 +1444,11 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
if (erts_mseg_no() >= max_mseg_carriers)
goto try_sys_alloc;
if (flags & CFLG_SBC) {
- if (allctr->sbcs.curr_mseg.no >= allctr->max_mseg_sbcs)
+ if (allctr->sbcs.curr.norm.mseg.no >= allctr->max_mseg_sbcs)
goto try_sys_alloc;
}
else {
- if (allctr->mbcs.curr_mseg.no >= allctr->max_mseg_mbcs)
+ if (allctr->mbcs.curr.norm.mseg.no >= allctr->max_mseg_mbcs)
goto try_sys_alloc;
}
@@ -1289,7 +1462,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
if (crr_sz < allctr->mbc_header_size + blk_sz)
crr_sz = allctr->mbc_header_size + blk_sz;
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(UWord))
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
crr_sz += sizeof(UWord);
#endif
}
@@ -1330,7 +1503,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
&& bcrr_sz < allctr->smallest_mbc_size)
bcrr_sz = allctr->smallest_mbc_size;
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(UWord))
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
bcrr_sz += sizeof(UWord);
#endif
@@ -1385,7 +1558,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
blk = MBC2FBLK(allctr, crr);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(UWord))
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
crr_sz -= sizeof(UWord);
#endif
@@ -1406,16 +1579,16 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
link_carrier(&allctr->mbc_list, crr);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(UWord))
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
crr_sz += sizeof(UWord);
#endif
CHECK_1BLK_CARRIER(allctr, 0, is_mseg, crr, crr_sz, blk, blk_sz);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(UWord))
+ if (allctr->mbc_header_size % sizeof(Unit_t) == 0)
crr_sz -= sizeof(UWord);
#endif
if (allctr->creating_mbc)
- (*allctr->creating_mbc)(allctr, crr);
+ (*allctr->creating_mbc)(allctr, crr, 0);
}
@@ -1595,9 +1768,9 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk)
ASSERT(IS_LAST_BLK(blk));
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- (*allctr->link_free_block)(allctr, blk);
+ (*allctr->link_free_block)(allctr, blk, 0);
HARD_CHECK_BLK_CARRIER(allctr, blk);
- (*allctr->unlink_free_block)(allctr, blk);
+ (*allctr->unlink_free_block)(allctr, blk, 0);
#endif
}
#endif
@@ -1614,7 +1787,7 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk)
unlink_carrier(&allctr->mbc_list, crr);
if (allctr->destroying_mbc)
- (*allctr->destroying_mbc)(allctr, crr);
+ (*allctr->destroying_mbc)(allctr, crr, 0);
}
@@ -1658,12 +1831,15 @@ static struct {
Eterm lmbcs;
Eterm smbcs;
Eterm mbcgs;
+ Eterm sbmbcs;
+ Eterm sbmbct;
#if HAVE_ERTS_MSEG
Eterm mmc;
#endif
Eterm ycs;
+ /* Eterm sbmbcs; */
Eterm mbcs;
Eterm sbcs;
Eterm sys_alloc_carriers_size;
@@ -1688,6 +1864,8 @@ static struct {
Eterm mseg_dealloc;
Eterm mseg_realloc;
#endif
+ Eterm sbmbc_alloc;
+ Eterm sbmbc_free;
#ifdef DEBUG
Eterm end_of_atoms;
#endif
@@ -1746,12 +1924,15 @@ init_atoms(Allctr_t *allctr)
AM_INIT(lmbcs);
AM_INIT(smbcs);
AM_INIT(mbcgs);
+ AM_INIT(sbmbcs);
+ AM_INIT(sbmbct);
#if HAVE_ERTS_MSEG
AM_INIT(mmc);
#endif
AM_INIT(ycs);
+ /*AM_INIT(sbmbcs);*/
AM_INIT(mbcs);
AM_INIT(sbcs);
AM_INIT(sys_alloc_carriers_size);
@@ -1776,6 +1957,8 @@ init_atoms(Allctr_t *allctr)
AM_INIT(mseg_dealloc);
AM_INIT(mseg_realloc);
#endif
+ AM_INIT(sbmbc_free);
+ AM_INIT(sbmbc_alloc);
#ifdef DEBUG
for (atom = (Eterm *) &am; atom < &am.end_of_atoms; atom++) {
@@ -1869,7 +2052,9 @@ sz_info_carriers(Allctr_t *allctr,
Uint *szp)
{
Eterm res = THE_NON_VALUE;
- Uint curr_size = cs->curr_mseg.size + cs->curr_sys_alloc.size;
+ Uint curr_size = (cs == &allctr->sbmbcs
+ ? cs->curr.small_block.size
+ : cs->curr.norm.mseg.size + cs->curr.norm.sys_alloc.size);
if (print_to_p) {
int to = *print_to_p;
@@ -1917,8 +2102,17 @@ info_carriers(Allctr_t *allctr,
Uint *szp)
{
Eterm res = THE_NON_VALUE;
- Uint curr_no = cs->curr_mseg.no + cs->curr_sys_alloc.no;
- Uint curr_size = cs->curr_mseg.size + cs->curr_sys_alloc.size;
+ Uint curr_no, curr_size;
+ int small_block = cs == &allctr->sbmbcs;
+
+ if (small_block) {
+ curr_no = cs->curr.small_block.no;
+ curr_size = cs->curr.small_block.size;
+ }
+ else {
+ curr_no = cs->curr.norm.mseg.no + cs->curr.norm.sys_alloc.no;
+ curr_size = cs->curr.norm.mseg.size + cs->curr.norm.sys_alloc.size;
+ }
if (print_to_p) {
int to = *print_to_p;
@@ -1944,18 +2138,20 @@ info_carriers(Allctr_t *allctr,
curr_no,
cs->max.no,
cs->max_ever.no);
+ if (!small_block) {
#if HAVE_ERTS_MSEG
- erts_print(to,
- arg,
- "%smseg carriers: %bpu\n",
- prefix,
- cs->curr_mseg.no);
-#endif
- erts_print(to,
- arg,
- "%ssys_alloc carriers: %bpu\n",
- prefix,
- cs->curr_sys_alloc.no);
+ erts_print(to,
+ arg,
+ "%smseg carriers: %bpu\n",
+ prefix,
+ cs->curr.norm.mseg.no);
+#endif
+ erts_print(to,
+ arg,
+ "%ssys_alloc carriers: %bpu\n",
+ prefix,
+ cs->curr.norm.sys_alloc.no);
+ }
erts_print(to,
arg,
"%scarriers size: %beu %bpu %bpu\n",
@@ -1963,43 +2159,49 @@ info_carriers(Allctr_t *allctr,
curr_size,
cs->max.size,
cs->max_ever.size);
+ if (!small_block) {
#if HAVE_ERTS_MSEG
- erts_print(to,
- arg,
- "%smseg carriers size: %bpu\n",
- prefix,
- cs->curr_mseg.size);
-#endif
- erts_print(to,
- arg,
- "%ssys_alloc carriers size: %bpu\n",
- prefix,
- cs->curr_sys_alloc.size);
+ erts_print(to,
+ arg,
+ "%smseg carriers size: %bpu\n",
+ prefix,
+ cs->curr.norm.mseg.size);
+#endif
+ erts_print(to,
+ arg,
+ "%ssys_alloc carriers size: %bpu\n",
+ prefix,
+ cs->curr.norm.sys_alloc.size);
+ }
}
if (hpp || szp) {
res = NIL;
- add_2tup(hpp, szp, &res,
- am.sys_alloc_carriers_size,
- bld_unstable_uint(hpp, szp, cs->curr_sys_alloc.size));
+ if (!small_block) {
+ add_2tup(hpp, szp, &res,
+ am.sys_alloc_carriers_size,
+ bld_unstable_uint(hpp, szp, cs->curr.norm.sys_alloc.size));
#if HAVE_ERTS_MSEG
- add_2tup(hpp, szp, &res,
- am.mseg_alloc_carriers_size,
- bld_unstable_uint(hpp, szp, cs->curr_mseg.size));
+ add_2tup(hpp, szp, &res,
+ am.mseg_alloc_carriers_size,
+ bld_unstable_uint(hpp, szp, cs->curr.norm.mseg.size));
#endif
+ }
add_4tup(hpp, szp, &res,
am.carriers_size,
bld_unstable_uint(hpp, szp, curr_size),
bld_unstable_uint(hpp, szp, cs->max.size),
bld_unstable_uint(hpp, szp, cs->max_ever.size));
- add_2tup(hpp, szp, &res,
- am.sys_alloc_carriers,
- bld_unstable_uint(hpp, szp, cs->curr_sys_alloc.no));
+ if (!small_block) {
+ add_2tup(hpp, szp, &res,
+ am.sys_alloc_carriers,
+ bld_unstable_uint(hpp, szp, cs->curr.norm.sys_alloc.no));
#if HAVE_ERTS_MSEG
- add_2tup(hpp, szp, &res,
- am.mseg_alloc_carriers,
- bld_unstable_uint(hpp, szp, cs->curr_mseg.no));
+ add_2tup(hpp, szp, &res,
+ am.mseg_alloc_carriers,
+ bld_unstable_uint(hpp, szp, cs->curr.norm.mseg.no));
#endif
+ }
add_4tup(hpp, szp, &res,
am.carriers,
bld_unstable_uint(hpp, szp, curr_no),
@@ -2077,6 +2279,9 @@ info_calls(Allctr_t *allctr,
PRINT_CC_5(to, arg, prefix, "free", allctr->calls.this_free);
PRINT_CC_5(to, arg, prefix, "realloc", allctr->calls.this_realloc);
+ PRINT_CC_4(to, arg, "sbmbc_alloc", allctr->calls.sbmbc_alloc);
+ PRINT_CC_4(to, arg, "sbmbc_free", allctr->calls.sbmbc_free);
+
#if HAVE_ERTS_MSEG
PRINT_CC_4(to, arg, "mseg_alloc", allctr->calls.mseg_alloc);
PRINT_CC_4(to, arg, "mseg_dealloc", allctr->calls.mseg_dealloc);
@@ -2128,6 +2333,14 @@ info_calls(Allctr_t *allctr,
bld_unstable_uint(hpp, szp, allctr->calls.mseg_alloc.no));
#endif
add_3tup(hpp, szp, &res,
+ am.sbmbc_free,
+ bld_unstable_uint(hpp, szp, allctr->calls.sbmbc_free.giga_no),
+ bld_unstable_uint(hpp, szp, allctr->calls.sbmbc_free.no));
+ add_3tup(hpp, szp, &res,
+ am.sbmbc_alloc,
+ bld_unstable_uint(hpp, szp, allctr->calls.sbmbc_alloc.giga_no),
+ bld_unstable_uint(hpp, szp, allctr->calls.sbmbc_alloc.no));
+ add_3tup(hpp, szp, &res,
allctr->name.realloc,
bld_unstable_uint(hpp, szp, allctr->calls.this_realloc.giga_no),
bld_unstable_uint(hpp, szp, allctr->calls.this_realloc.no));
@@ -2191,7 +2404,9 @@ info_options(Allctr_t *allctr,
#endif
"option lmbcs: %beu\n"
"option smbcs: %beu\n"
- "option mbcgs: %beu\n",
+ "option mbcgs: %beu\n"
+ "option sbmbcs: %beu\n"
+ "option sbmbct: %beu\n",
topt,
allctr->ramv ? "true" : "false",
#if HALFWORD_HEAP
@@ -2211,7 +2426,9 @@ info_options(Allctr_t *allctr,
#endif
allctr->largest_mbc_size,
allctr->smallest_mbc_size,
- allctr->mbc_growth_stages);
+ allctr->mbc_growth_stages,
+ allctr->sbmbc_size,
+ allctr->sbmbc_threshold);
}
res = (*allctr->info_options)(allctr, "option ", print_to_p, print_to_arg,
@@ -2219,6 +2436,12 @@ info_options(Allctr_t *allctr,
if (hpp || szp) {
add_2tup(hpp, szp, &res,
+ am.sbmbct,
+ bld_uint(hpp, szp, allctr->sbmbc_threshold));
+ add_2tup(hpp, szp, &res,
+ am.sbmbcs,
+ bld_uint(hpp, szp, allctr->sbmbc_size));
+ add_2tup(hpp, szp, &res,
am.mbcgs,
bld_uint(hpp, szp, allctr->mbc_growth_stages));
add_2tup(hpp, szp, &res,
@@ -2285,10 +2508,10 @@ update_max_ever_values(CarriersStats_t *cs)
static ERTS_INLINE void
reset_max_values(CarriersStats_t *cs)
{
- cs->max.no = cs->curr_mseg.no + cs->curr_sys_alloc.no;
- cs->max.size = cs->curr_mseg.size + cs->curr_sys_alloc.size;
- cs->blocks.max.no = cs->blocks.curr.no;
- cs->blocks.max.size = cs->blocks.curr.size;
+ cs->max.no = cs->curr.norm.mseg.no + cs->curr.norm.sys_alloc.no;
+ cs->max.size = cs->curr.norm.mseg.size + cs->curr.norm.sys_alloc.size;
+ cs->blocks.max.no = cs->blocks.curr.no;
+ cs->blocks.max.size = cs->blocks.curr.size;
}
@@ -2367,7 +2590,7 @@ erts_alcu_sz_info(Allctr_t *allctr,
Uint **hpp,
Uint *szp)
{
- Eterm res, mbcs, sbcs;
+ Eterm res, sbmbcs, mbcs, sbcs;
res = THE_NON_VALUE;
@@ -2389,24 +2612,29 @@ erts_alcu_sz_info(Allctr_t *allctr,
/* Update sbc values not continously updated */
allctr->sbcs.blocks.curr.no
- = allctr->sbcs.curr_mseg.no + allctr->sbcs.curr_sys_alloc.no;
+ = allctr->sbcs.curr.norm.mseg.no + allctr->sbcs.curr.norm.sys_alloc.no;
allctr->sbcs.blocks.max.no = allctr->sbcs.max.no;
+ update_max_ever_values(&allctr->sbmbcs);
update_max_ever_values(&allctr->mbcs);
update_max_ever_values(&allctr->sbcs);
- mbcs = sz_info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p,
- print_to_arg, hpp, szp);
- sbcs = sz_info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p,
- print_to_arg, hpp, szp);
+ sbmbcs = sz_info_carriers(allctr, &allctr->sbmbcs, "sbmbcs ", print_to_p,
+ print_to_arg, hpp, szp);
+ mbcs = sz_info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p,
+ print_to_arg, hpp, szp);
+ sbcs = sz_info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p,
+ print_to_arg, hpp, szp);
if (hpp || szp) {
res = NIL;
add_2tup(hpp, szp, &res, am.sbcs, sbcs);
add_2tup(hpp, szp, &res, am.mbcs, mbcs);
+ add_2tup(hpp, szp, &res, am.sbmbcs, sbmbcs);
}
if (begin_max_period) {
+ reset_max_values(&allctr->sbmbcs);
reset_max_values(&allctr->mbcs);
reset_max_values(&allctr->sbcs);
}
@@ -2428,7 +2656,7 @@ erts_alcu_info(Allctr_t *allctr,
Uint **hpp,
Uint *szp)
{
- Eterm res, sett, mbcs, sbcs, calls;
+ Eterm res, sett, sbmbcs, mbcs, sbcs, calls;
res = THE_NON_VALUE;
@@ -2450,9 +2678,10 @@ erts_alcu_info(Allctr_t *allctr,
/* Update sbc values not continously updated */
allctr->sbcs.blocks.curr.no
- = allctr->sbcs.curr_mseg.no + allctr->sbcs.curr_sys_alloc.no;
+ = allctr->sbcs.curr.norm.mseg.no + allctr->sbcs.curr.norm.sys_alloc.no;
allctr->sbcs.blocks.max.no = allctr->sbcs.max.no;
+ update_max_ever_values(&allctr->sbmbcs);
update_max_ever_values(&allctr->mbcs);
update_max_ever_values(&allctr->sbcs);
@@ -2464,11 +2693,13 @@ erts_alcu_info(Allctr_t *allctr,
ERTS_ALCU_VSN_STR);
}
- sett = info_options(allctr, print_to_p, print_to_arg, hpp, szp);
- mbcs = info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p,
- print_to_arg, hpp, szp);
- sbcs = info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p,
- print_to_arg, hpp, szp);
+ sett = info_options(allctr, print_to_p, print_to_arg, hpp, szp);
+ sbmbcs = info_carriers(allctr, &allctr->sbmbcs, "sbmbcs ", print_to_p,
+ print_to_arg, hpp, szp);
+ mbcs = info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p,
+ print_to_arg, hpp, szp);
+ sbcs = info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p,
+ print_to_arg, hpp, szp);
calls = info_calls(allctr, print_to_p, print_to_arg, hpp, szp);
if (hpp || szp) {
@@ -2477,6 +2708,7 @@ erts_alcu_info(Allctr_t *allctr,
add_2tup(hpp, szp, &res, am.calls, calls);
add_2tup(hpp, szp, &res, am.sbcs, sbcs);
add_2tup(hpp, szp, &res, am.mbcs, mbcs);
+ add_2tup(hpp, szp, &res, am.sbmbcs, sbmbcs);
add_2tup(hpp, szp, &res, am.options, sett);
add_3tup(hpp, szp, &res,
am.versions,
@@ -2485,6 +2717,7 @@ erts_alcu_info(Allctr_t *allctr,
}
if (begin_max_period) {
+ reset_max_values(&allctr->sbmbcs);
reset_max_values(&allctr->mbcs);
reset_max_values(&allctr->sbcs);
}
@@ -2508,12 +2741,14 @@ erts_alcu_current_size(Allctr_t *allctr, AllctrSize_t *size)
erts_mtx_lock(&allctr->mutex);
#endif
- size->carriers = allctr->mbcs.curr_mseg.size;
- size->carriers += allctr->mbcs.curr_sys_alloc.size;
- size->carriers += allctr->sbcs.curr_mseg.size;
- size->carriers += allctr->sbcs.curr_sys_alloc.size;
+ size->carriers = allctr->mbcs.curr.norm.mseg.size;
+ size->carriers += allctr->mbcs.curr.norm.sys_alloc.size;
+ size->carriers += allctr->sbmbcs.curr.small_block.size;
+ size->carriers += allctr->sbcs.curr.norm.mseg.size;
+ size->carriers += allctr->sbcs.curr.norm.sys_alloc.size;
size->blocks = allctr->mbcs.blocks.curr.size;
+ size->blocks += allctr->sbmbcs.blocks.curr.size;
size->blocks += allctr->sbcs.blocks.curr.size;
#ifdef USE_THREADS
@@ -2725,7 +2960,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
void *extra,
void *p,
Uint size,
- UWord flgs)
+ Uint32 alcu_flgs)
{
Allctr_t *allctr = (Allctr_t *) extra;
Block_t *blk;
@@ -2758,9 +2993,32 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
blk = UMEM2BLK(p);
+ if (allctr->sbmbc_threshold > 0) {
+ Uint old_sz, new_sz, lim;
+ lim = allctr->sbmbc_threshold;
+ old_sz = BLK_SZ(blk);
+ new_sz = UMEMSZ2BLKSZ(allctr, size);
+ if ((old_sz < lim && lim <= new_sz)
+ || (new_sz < lim && lim <= old_sz)) {
+ /* *Need* to move it... */
+
+ INC_CC(allctr->calls.this_realloc);
+ res = do_erts_alcu_alloc(type, extra, size);
+ DEC_CC(allctr->calls.this_alloc);
+
+ sys_memcpy(res, p, MIN(size, old_sz - ABLK_HDR_SZ));
+
+ do_erts_alcu_free(type, extra, p);
+ DEC_CC(allctr->calls.this_free);
+ return res;
+ }
+ if (old_sz < lim)
+ alcu_flgs |= ERTS_ALCU_FLG_SBMBC;
+ }
+
if (size < allctr->sbc_threshold) {
if (IS_MBC_BLK(blk))
- res = mbc_realloc(allctr, p, size, flgs);
+ res = mbc_realloc(allctr, p, size, alcu_flgs);
else {
Uint used_sz = allctr->sbc_header_size + ABLK_HDR_SZ + size;
Uint crr_sz;
@@ -2791,7 +3049,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
if (100*diff_sz_val < allctr->sbc_move_threshold*crr_sz_val)
/* Data won't be copied into a new carrier... */
goto do_carrier_resize;
- else if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
+ else if (alcu_flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
res = mbc_alloc(allctr, size);
@@ -2814,7 +3072,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
#endif
res = new_blk ? BLK2UMEM(new_blk) : NULL;
}
- else if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
+ else if (alcu_flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
else {
#if HALFWORD_HEAP
@@ -3174,6 +3432,26 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
allctr->min_block_size = UNIT_CEILING(allctr->min_block_size
+ sizeof(UWord));
+
+ allctr->sbmbc_threshold = init->sbmbct;
+
+ if (!erts_have_sbmbc_alloc
+ || ERTS_IS_SBMBC_ALLOCATOR_NO__(allctr->alloc_no))
+ allctr->sbmbc_threshold = 0;
+
+ if (!allctr->sbmbc_threshold)
+ allctr->sbmbc_size = 0;
+ else {
+ Uint min_size;
+ allctr->sbmbc_size = init->sbmbcs;
+ min_size = allctr->sbmbc_threshold;
+ min_size += allctr->min_block_size;
+ min_size += allctr->mbc_header_size;
+ if (allctr->sbmbc_size < min_size)
+ allctr->sbmbc_size = min_size;
+ }
+
+
#if HAVE_ERTS_MSEG
if (allctr->mseg_opt.abs_shrink_th > ~((UWord) 0) / 100)
allctr->mseg_opt.abs_shrink_th = ~((UWord) 0) / 100;
@@ -3185,12 +3463,16 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_mtx_init_x_opt(&allctr->mutex,
- "alcu_allocator",
- make_small(allctr->alloc_no),
- ERTS_LCNT_LT_ALLOC);
+ ERTS_IS_SBMBC_ALLOCATOR_NO__(allctr->alloc_no)
+ ? "sbmbc_alloc"
+ : "alcu_allocator",
+ make_small(allctr->alloc_no),
+ ERTS_LCNT_LT_ALLOC);
#else
erts_mtx_init_x(&allctr->mutex,
- "alcu_allocator",
+ ERTS_IS_SBMBC_ALLOCATOR_NO__(allctr->alloc_no)
+ ? "sbmbc_alloc"
+ : "alcu_allocator",
make_small(allctr->alloc_no));
#endif /*ERTS_ENABLE_LOCK_COUNT*/
@@ -3260,7 +3542,7 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
if (!blk)
goto error;
- (*allctr->link_free_block)(allctr, blk);
+ (*allctr->link_free_block)(allctr, blk, 0);
HARD_CHECK_BLK_CARRIER(allctr, blk);
@@ -3290,6 +3572,8 @@ erts_alcu_stop(Allctr_t *allctr)
destroy_carrier(allctr, SBC2BLK(allctr, allctr->sbc_list.first));
while (allctr->mbc_list.first)
destroy_carrier(allctr, MBC2FBLK(allctr, allctr->mbc_list.first));
+ while (allctr->sbmbc_list.first)
+ destroy_sbmbc(allctr, MBC2FBLK(allctr, allctr->sbmbc_list.first));
#ifdef USE_THREADS
if (allctr->thread_safe)
@@ -3387,13 +3671,15 @@ erts_alcu_verify_unused(Allctr_t *allctr)
{
UWord no;
- no = allctr->sbcs.curr_mseg.no;
- no += allctr->sbcs.curr_sys_alloc.no;
+ no = allctr->sbcs.curr.norm.mseg.no;
+ no += allctr->sbcs.curr.norm.sys_alloc.no;
no += allctr->mbcs.blocks.curr.no;
+ no += allctr->sbmbcs.blocks.curr.no;
if (no) {
UWord sz = allctr->sbcs.blocks.curr.size;
sz += allctr->mbcs.blocks.curr.size;
+ sz += allctr->sbmbcs.blocks.curr.size;
erl_exit(ERTS_ABORT_EXIT,
"%salloc() used when expected to be unused!\n"
"Total amount of blocks allocated: %bpu\n"
@@ -3492,7 +3778,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
(*allctr->check_block)(allctr, blk, (int) is_free_blk);
if (IS_LAST_BLK(blk)) {
- carrier_end = ((char *) NXT_BLK(blk)) + sizeof(UWord);
+ carrier_end = ((char *) NXT_BLK(blk));
mbc = *((Carrier_t **) NXT_BLK(blk));
prev_blk = NULL;
blk = MBC2FBLK(allctr, mbc);
@@ -3507,9 +3793,9 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
ASSERT(IS_MB_CARRIER(mbc));
ASSERT((((char *) mbc)
+ allctr->mbc_header_size
- + tot_blk_sz
- + sizeof(UWord)) == carrier_end);
- ASSERT(((char *) mbc) + CARRIER_SZ(mbc) == carrier_end);
+ + tot_blk_sz) == carrier_end);
+ ASSERT(((char *) mbc) + CARRIER_SZ(mbc) - sizeof(Unit_t) <= carrier_end
+ && carrier_end <= ((char *) mbc) + CARRIER_SZ(mbc));
if (allctr->check_mbc)
(*allctr->check_mbc)(allctr, mbc);
@@ -3523,6 +3809,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
cl = &allctr->mbc_list;
}
+#if 0 /* FIXIT sbmbc */
if (cl->first == crr) {
ASSERT(!crr->prev);
}
@@ -3537,6 +3824,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
ASSERT(crr->next);
ASSERT(crr->next->prev == crr);
}
+#endif
}
#endif
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index ddf84c086c..fed4d3dbe6 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -34,6 +34,7 @@ typedef struct {
typedef struct {
char *name_prefix;
ErtsAlcType_t alloc_no;
+ int force;
int ts;
int tspec;
int tpref;
@@ -50,6 +51,8 @@ typedef struct {
UWord lmbcs;
UWord smbcs;
UWord mbcgs;
+ UWord sbmbct;
+ UWord sbmbcs;
} AllctrInit_t;
typedef struct {
@@ -67,6 +70,7 @@ typedef struct {
#define ERTS_DEFAULT_ALLCTR_INIT { \
NULL, \
ERTS_ALC_A_INVALID, /* (number) alloc_no: allocator number */\
+ 0, /* (bool) force: force enabled */\
1, /* (bool) ts: thread safe */\
0, /* (bool) tspec: thread specific */\
0, /* (bool) tpref: thread preferred */\
@@ -82,7 +86,9 @@ typedef struct {
10, /* (amount) mmmbc: max mseg mbcs */\
10*1024*1024, /* (bytes) lmbcs: largest mbc size */\
1024*1024, /* (bytes) smbcs: smallest mbc size */\
- 10 /* (amount) mbcgs: mbc growth stages */\
+ 10, /* (amount) mbcgs: mbc growth stages */\
+ 256, /* (bytes) sbmbct: small block mbc threshold */\
+ 8*1024 /* (bytes) sbmbcs: small block mbc size */\
}
#else /* if SMALL_MEMORY */
@@ -95,6 +101,7 @@ typedef struct {
#define ERTS_DEFAULT_ALLCTR_INIT { \
NULL, \
ERTS_ALC_A_INVALID, /* (number) alloc_no: allocator number */\
+ 0, /* (bool) force: force enabled */\
1, /* (bool) ts: thread safe */\
0, /* (bool) tspec: thread specific */\
0, /* (bool) tpref: thread preferred */\
@@ -109,7 +116,9 @@ typedef struct {
10, /* (amount) mmmbc: max mseg mbcs */\
1024*1024, /* (bytes) lmbcs: largest mbc size */\
128*1024, /* (bytes) smbcs: smallest mbc size */\
- 10 /* (amount) mbcgs: mbc growth stages */\
+ 10, /* (amount) mbcgs: mbc growth stages */\
+ 256, /* (bytes) sbmbct: small block mbc threshold */\
+ 8*1024 /* (bytes) sbmbcs: small block mbc size */\
}
#endif
@@ -144,6 +153,9 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *);
#if defined(GET_ERL_ALLOC_UTIL_IMPL) && !defined(ERL_ALLOC_UTIL_IMPL__)
#define ERL_ALLOC_UTIL_IMPL__
+#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE (((Uint32) 1) << 0)
+#define ERTS_ALCU_FLG_SBMBC (((Uint32) 1) << 1)
+
#ifdef USE_THREADS
#define ERL_THREADS_EMU_INTERNAL__
#include "erl_threads.h"
@@ -188,6 +200,8 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *);
#define CARRIER_SZ(C) \
((C)->chdr & SZ_MASK)
+extern int erts_have_sbmbc_alloc;
+
typedef union {char c[8]; long l; double d;} Unit_t;
typedef struct Carrier_t_ Carrier_t;
@@ -216,8 +230,13 @@ typedef struct {
} StatValues_t;
typedef struct {
- StatValues_t curr_mseg;
- StatValues_t curr_sys_alloc;
+ union {
+ struct {
+ StatValues_t mseg;
+ StatValues_t sys_alloc;
+ } norm;
+ StatValues_t small_block;
+ } curr;
StatValues_t max;
StatValues_t max_ever;
struct {
@@ -257,6 +276,8 @@ struct Allctr_t_ {
Uint largest_mbc_size;
Uint smallest_mbc_size;
Uint mbc_growth_stages;
+ Uint sbmbc_threshold;
+ Uint sbmbc_size;
#if HAVE_ERTS_MSEG
ErtsMsegOpt_t mseg_opt;
#endif
@@ -269,6 +290,7 @@ struct Allctr_t_ {
Uint min_block_size;
/* Carriers */
+ CarrierList_t sbmbc_list;
CarrierList_t mbc_list;
CarrierList_t sbc_list;
@@ -277,15 +299,15 @@ struct Allctr_t_ {
/* Callback functions (first 4 are mandatory) */
Block_t * (*get_free_block) (Allctr_t *, Uint,
- Block_t *, Uint);
- void (*link_free_block) (Allctr_t *, Block_t *);
- void (*unlink_free_block) (Allctr_t *, Block_t *);
+ Block_t *, Uint, Uint32);
+ void (*link_free_block) (Allctr_t *, Block_t *, Uint32);
+ void (*unlink_free_block) (Allctr_t *, Block_t *, Uint32);
Eterm (*info_options) (Allctr_t *, char *, int *,
void *, Uint **, Uint *);
Uint (*get_next_mbc_size) (Allctr_t *);
- void (*creating_mbc) (Allctr_t *, Carrier_t *);
- void (*destroying_mbc) (Allctr_t *, Carrier_t *);
+ void (*creating_mbc) (Allctr_t *, Carrier_t *, Uint32);
+ void (*destroying_mbc) (Allctr_t *, Carrier_t *, Uint32);
void (*init_atoms) (void);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
@@ -312,6 +334,8 @@ struct Allctr_t_ {
CallCounter_t this_alloc;
CallCounter_t this_free;
CallCounter_t this_realloc;
+ CallCounter_t sbmbc_alloc;
+ CallCounter_t sbmbc_free;
CallCounter_t mseg_alloc;
CallCounter_t mseg_dealloc;
CallCounter_t mseg_realloc;
@@ -322,6 +346,7 @@ struct Allctr_t_ {
CarriersStats_t sbcs;
CarriersStats_t mbcs;
+ CarriersStats_t sbmbcs;
#ifdef DEBUG
#ifdef USE_THREADS
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.c b/erts/emulator/beam/erl_ao_firstfit_alloc.c
new file mode 100644
index 0000000000..002852cdad
--- /dev/null
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.c
@@ -0,0 +1,972 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+
+/*
+ * Description: An "address order first fit" allocator
+ * based on a Red-Black (binary search) Tree. 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.
+ *
+ * This module is a callback-module for erl_alloc_util.c
+ *
+ * Algorithm: The tree nodes are free-blocks ordered in address order.
+ * Every node also keeps the size of the largest block in its
+ * sub-tree ('max_size'). By that we can start from root and keep
+ * left (for low addresses) while dismissing entire sub-trees with
+ * too small blocks.
+ *
+ * Authors: Rickard Green/Sverker Eriksson
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "global.h"
+#define GET_ERL_AOFF_ALLOC_IMPL
+#include "erl_ao_firstfit_alloc.h"
+
+#ifdef DEBUG
+#if 0
+#define HARD_DEBUG
+#endif
+#else
+#undef HARD_DEBUG
+#endif
+
+#define MIN_MBC_SZ (16*1024)
+#define MIN_MBC_FIRST_FREE_SZ (4*1024)
+
+#define TREE_NODE_FLG (((Uint) 1) << 0)
+#define RED_FLG (((Uint) 1) << 1)
+#ifdef HARD_DEBUG
+# define LEFT_VISITED_FLG (((Uint) 1) << 2)
+# define RIGHT_VISITED_FLG (((Uint) 1) << 3)
+#endif
+
+#define IS_RED(N) (((AOFF_RBTree_t *) (N)) \
+ && ((AOFF_RBTree_t *) (N))->flags & RED_FLG)
+#define IS_BLACK(N) (!IS_RED(((AOFF_RBTree_t *) (N))))
+
+#define SET_RED(N) (((AOFF_RBTree_t *) (N))->flags |= RED_FLG)
+#define SET_BLACK(N) (((AOFF_RBTree_t *) (N))->flags &= ~RED_FLG)
+
+#undef ASSERT
+#define ASSERT ASSERT_EXPR
+
+#if 1
+#define RBT_ASSERT ASSERT
+#else
+#define RBT_ASSERT(x)
+#endif
+
+
+/* Types... */
+typedef struct AOFF_RBTree_t_ AOFF_RBTree_t;
+
+struct AOFF_RBTree_t_ {
+ Block_t hdr;
+ Uint flags;
+ AOFF_RBTree_t *parent;
+ AOFF_RBTree_t *left;
+ AOFF_RBTree_t *right;
+ Uint max_sz; /* of all blocks in this sub-tree */
+};
+
+#ifdef HARD_DEBUG
+static AOFF_RBTree_t * check_tree(AOFF_RBTree_t* root, Uint);
+#endif
+
+
+/* Calculate 'max_size' of tree node x by only looking at the direct children
+ * of x and x itself.
+ */
+static ERTS_INLINE Uint node_max_size(AOFF_RBTree_t *x)
+{
+ Uint sz = BLK_SZ(x);
+ if (x->left && x->left->max_sz > sz) {
+ sz = x->left->max_sz;
+ }
+ if (x->right && x->right->max_sz > sz) {
+ sz = x->right->max_sz;
+ }
+ return sz;
+}
+
+/* Set new possibly lower 'max_size' of node and propagate change toward root
+*/
+static ERTS_INLINE void lower_max_size(AOFF_RBTree_t *node,
+ AOFF_RBTree_t* stop_at)
+{
+ AOFF_RBTree_t* x = node;
+ Uint old_max = x->max_sz;
+ Uint new_max = node_max_size(x);
+
+ if (new_max < old_max) {
+ x->max_sz = new_max;
+ while ((x=x->parent) != stop_at && x->max_sz == old_max) {
+ x->max_sz = node_max_size(x);
+ }
+ ASSERT(x == stop_at || x->max_sz > old_max);
+ }
+ else ASSERT(new_max == old_max);
+}
+
+
+/* Prototypes of callback functions */
+static Block_t* aoff_get_free_block(Allctr_t *, Uint, Block_t *, Uint, Uint32 flags);
+static void aoff_link_free_block(Allctr_t *, Block_t*, Uint32 flags);
+static void aoff_unlink_free_block(Allctr_t *allctr, Block_t *del, Uint32 flags);
+
+static Eterm info_options(Allctr_t *, char *, int *, void *, Uint **, Uint *);
+static void init_atoms(void);
+
+
+
+#ifdef DEBUG
+
+/* Destroy all tree fields */
+#define DESTROY_TREE_NODE(N) \
+ sys_memset((void *) (((Block_t *) (N)) + 1), \
+ 0xff, \
+ (sizeof(AOFF_RBTree_t) - sizeof(Block_t)))
+
+#else
+
+#define DESTROY_TREE_NODE(N)
+
+#endif
+
+
+static int atoms_initialized = 0;
+
+void
+erts_aoffalc_init(void)
+{
+ atoms_initialized = 0;
+}
+
+Allctr_t *
+erts_aoffalc_start(AOFFAllctr_t *alc,
+ AOFFAllctrInit_t* aoffinit,
+ AllctrInit_t *init)
+{
+ AOFFAllctr_t nulled_state = {{0}};
+ /* {{0}} is used instead of {0}, in order to avoid (an incorrect) gcc
+ warning. gcc warns if {0} is used as initializer of a struct when
+ the first member is a struct (not if, for example, the third member
+ is a struct). */
+ Allctr_t *allctr = (Allctr_t *) alc;
+
+ sys_memcpy((void *) alc, (void *) &nulled_state, sizeof(AOFFAllctr_t));
+
+ allctr->mbc_header_size = sizeof(Carrier_t);
+ allctr->min_mbc_size = MIN_MBC_SZ;
+ allctr->min_mbc_first_free_size = MIN_MBC_FIRST_FREE_SZ;
+ allctr->min_block_size = sizeof(AOFF_RBTree_t);
+
+ allctr->vsn_str = ERTS_ALC_AOFF_ALLOC_VSN_STR;
+
+
+ /* Callback functions */
+
+ allctr->get_free_block = aoff_get_free_block;
+ allctr->link_free_block = aoff_link_free_block;
+ allctr->unlink_free_block = aoff_unlink_free_block;
+ allctr->info_options = info_options;
+
+ allctr->get_next_mbc_size = NULL;
+ allctr->creating_mbc = NULL;
+ allctr->destroying_mbc = NULL;
+ allctr->init_atoms = init_atoms;
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ allctr->check_block = NULL;
+ allctr->check_mbc = NULL;
+#endif
+
+ allctr->atoms_initialized = 0;
+
+ if (!erts_alcu_start(allctr, init))
+ return NULL;
+
+ return allctr;
+}
+
+/*
+ * Red-Black Tree operations needed
+ */
+
+static ERTS_INLINE void
+left_rotate(AOFF_RBTree_t **root, AOFF_RBTree_t *x)
+{
+ AOFF_RBTree_t *y = x->right;
+ x->right = y->left;
+ if (y->left)
+ y->left->parent = x;
+ y->parent = x->parent;
+ if (!y->parent) {
+ RBT_ASSERT(*root == x);
+ *root = y;
+ }
+ else if (x == x->parent->left)
+ x->parent->left = y;
+ else {
+ RBT_ASSERT(x == x->parent->right);
+ x->parent->right = y;
+ }
+ y->left = x;
+ x->parent = y;
+
+ y->max_sz = x->max_sz;
+ x->max_sz = node_max_size(x);
+ ASSERT(y->max_sz >= x->max_sz);
+}
+
+static ERTS_INLINE void
+right_rotate(AOFF_RBTree_t **root, AOFF_RBTree_t *x)
+{
+ AOFF_RBTree_t *y = x->left;
+ x->left = y->right;
+ if (y->right)
+ y->right->parent = x;
+ y->parent = x->parent;
+ if (!y->parent) {
+ RBT_ASSERT(*root == x);
+ *root = y;
+ }
+ else if (x == x->parent->right)
+ x->parent->right = y;
+ else {
+ RBT_ASSERT(x == x->parent->left);
+ x->parent->left = y;
+ }
+ y->right = x;
+ x->parent = y;
+ y->max_sz = x->max_sz;
+ x->max_sz = node_max_size(x);
+ ASSERT(y->max_sz >= x->max_sz);
+}
+
+
+/*
+ * Replace node x with node y
+ * NOTE: block header of y is not changed
+ */
+static ERTS_INLINE void
+replace(AOFF_RBTree_t **root, AOFF_RBTree_t *x, AOFF_RBTree_t *y)
+{
+
+ if (!x->parent) {
+ RBT_ASSERT(*root == x);
+ *root = y;
+ }
+ else if (x == x->parent->left)
+ x->parent->left = y;
+ else {
+ RBT_ASSERT(x == x->parent->right);
+ x->parent->right = y;
+ }
+ if (x->left) {
+ RBT_ASSERT(x->left->parent == x);
+ x->left->parent = y;
+ }
+ if (x->right) {
+ RBT_ASSERT(x->right->parent == x);
+ x->right->parent = y;
+ }
+
+ y->flags = x->flags;
+ y->parent = x->parent;
+ y->right = x->right;
+ y->left = x->left;
+
+ y->max_sz = x->max_sz;
+ lower_max_size(y, NULL);
+ DESTROY_TREE_NODE(x);
+}
+
+static void
+tree_insert_fixup(AOFF_RBTree_t** root, AOFF_RBTree_t *blk)
+{
+ AOFF_RBTree_t *x = blk, *y;
+
+ /*
+ * Rearrange the tree so that it satisfies the Red-Black Tree properties
+ */
+
+ RBT_ASSERT(x != *root && IS_RED(x->parent));
+ do {
+
+ /*
+ * 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.
+ */
+
+ RBT_ASSERT(IS_RED(x));
+ RBT_ASSERT(IS_BLACK(x->parent->parent));
+ RBT_ASSERT(x->parent->parent);
+
+ if (x->parent == x->parent->parent->left) {
+ y = x->parent->parent->right;
+ if (IS_RED(y)) {
+ SET_BLACK(y);
+ x = x->parent;
+ SET_BLACK(x);
+ x = x->parent;
+ SET_RED(x);
+ }
+ else {
+
+ if (x == x->parent->right) {
+ x = x->parent;
+ left_rotate(root, x);
+ }
+
+ RBT_ASSERT(x == x->parent->parent->left->left);
+ RBT_ASSERT(IS_RED(x));
+ RBT_ASSERT(IS_RED(x->parent));
+ RBT_ASSERT(IS_BLACK(x->parent->parent));
+ RBT_ASSERT(IS_BLACK(y));
+
+ SET_BLACK(x->parent);
+ SET_RED(x->parent->parent);
+ right_rotate(root, x->parent->parent);
+
+ RBT_ASSERT(x == x->parent->left);
+ RBT_ASSERT(IS_RED(x));
+ RBT_ASSERT(IS_RED(x->parent->right));
+ RBT_ASSERT(IS_BLACK(x->parent));
+ break;
+ }
+ }
+ else {
+ RBT_ASSERT(x->parent == x->parent->parent->right);
+ y = x->parent->parent->left;
+ if (IS_RED(y)) {
+ SET_BLACK(y);
+ x = x->parent;
+ SET_BLACK(x);
+ x = x->parent;
+ SET_RED(x);
+ }
+ else {
+
+ if (x == x->parent->left) {
+ x = x->parent;
+ right_rotate(root, x);
+ }
+
+ RBT_ASSERT(x == x->parent->parent->right->right);
+ RBT_ASSERT(IS_RED(x));
+ RBT_ASSERT(IS_RED(x->parent));
+ RBT_ASSERT(IS_BLACK(x->parent->parent));
+ RBT_ASSERT(IS_BLACK(y));
+
+ SET_BLACK(x->parent);
+ SET_RED(x->parent->parent);
+ left_rotate(root, x->parent->parent);
+
+ RBT_ASSERT(x == x->parent->right);
+ RBT_ASSERT(IS_RED(x));
+ RBT_ASSERT(IS_RED(x->parent->left));
+ RBT_ASSERT(IS_BLACK(x->parent));
+ break;
+ }
+ }
+ } while (x != *root && IS_RED(x->parent));
+
+ SET_BLACK(*root);
+}
+
+static void
+aoff_unlink_free_block(Allctr_t *allctr, Block_t *del, Uint32 flags)
+{
+ AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
+ AOFF_RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &alc->sbmbc_root : &alc->mbc_root);
+ Uint spliced_is_black;
+ AOFF_RBTree_t *x, *y, *z = (AOFF_RBTree_t *) del;
+ AOFF_RBTree_t null_x; /* null_x is used to get the fixup started when we
+ splice out a node without children. */
+
+ null_x.parent = NULL;
+
+#ifdef HARD_DEBUG
+ check_tree(*root, 0);
+#endif
+
+ /* Remove node from tree... */
+
+ /* Find node to splice out */
+ if (!z->left || !z->right)
+ y = z;
+ else
+ /* Set y to z:s successor */
+ for(y = z->right; y->left; y = y->left);
+ /* splice out y */
+ x = y->left ? y->left : y->right;
+ spliced_is_black = IS_BLACK(y);
+ if (x) {
+ x->parent = y->parent;
+ }
+ else if (spliced_is_black) {
+ x = &null_x;
+ x->flags = 0;
+ SET_BLACK(x);
+ x->right = x->left = NULL;
+ x->max_sz = 0;
+ x->parent = y->parent;
+ y->left = x;
+ }
+
+ if (!y->parent) {
+ RBT_ASSERT(*root == y);
+ *root = x;
+ }
+ else {
+ if (y == y->parent->left) {
+ y->parent->left = x;
+ }
+ else {
+ RBT_ASSERT(y == y->parent->right);
+ y->parent->right = x;
+ }
+ if (y->parent != z) {
+ lower_max_size(y->parent, (y==z ? NULL : z));
+ }
+ }
+ if (y != z) {
+ /* We spliced out the successor of z; replace z by the successor */
+ replace(root, z, y);
+ }
+
+ if (spliced_is_black) {
+ /* We removed a black node which makes the resulting tree
+ violate the Red-Black Tree properties. Fixup tree... */
+
+ while (IS_BLACK(x) && x->parent) {
+
+ /*
+ * 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
+ */
+
+ if (x == x->parent->left) {
+ y = x->parent->right;
+ RBT_ASSERT(y);
+ if (IS_RED(y)) {
+ RBT_ASSERT(y->right);
+ RBT_ASSERT(y->left);
+ SET_BLACK(y);
+ RBT_ASSERT(IS_BLACK(x->parent));
+ SET_RED(x->parent);
+ left_rotate(root, x->parent);
+ y = x->parent->right;
+ }
+ RBT_ASSERT(y);
+ RBT_ASSERT(IS_BLACK(y));
+ if (IS_BLACK(y->left) && IS_BLACK(y->right)) {
+ SET_RED(y);
+ x = x->parent;
+ }
+ else {
+ if (IS_BLACK(y->right)) {
+ SET_BLACK(y->left);
+ SET_RED(y);
+ right_rotate(root, y);
+ y = x->parent->right;
+ }
+ RBT_ASSERT(y);
+ if (IS_RED(x->parent)) {
+
+ SET_BLACK(x->parent);
+ SET_RED(y);
+ }
+ RBT_ASSERT(y->right);
+ SET_BLACK(y->right);
+ left_rotate(root, x->parent);
+ x = *root;
+ break;
+ }
+ }
+ else {
+ RBT_ASSERT(x == x->parent->right);
+ y = x->parent->left;
+ RBT_ASSERT(y);
+ if (IS_RED(y)) {
+ RBT_ASSERT(y->right);
+ RBT_ASSERT(y->left);
+ SET_BLACK(y);
+ RBT_ASSERT(IS_BLACK(x->parent));
+ SET_RED(x->parent);
+ right_rotate(root, x->parent);
+ y = x->parent->left;
+ }
+ RBT_ASSERT(y);
+ RBT_ASSERT(IS_BLACK(y));
+ if (IS_BLACK(y->right) && IS_BLACK(y->left)) {
+ SET_RED(y);
+ x = x->parent;
+ }
+ else {
+ if (IS_BLACK(y->left)) {
+ SET_BLACK(y->right);
+ SET_RED(y);
+ left_rotate(root, y);
+ y = x->parent->left;
+ }
+ RBT_ASSERT(y);
+ if (IS_RED(x->parent)) {
+ SET_BLACK(x->parent);
+ SET_RED(y);
+ }
+ RBT_ASSERT(y->left);
+ SET_BLACK(y->left);
+ right_rotate(root, x->parent);
+ x = *root;
+ break;
+ }
+ }
+ }
+ SET_BLACK(x);
+
+ if (null_x.parent) {
+ if (null_x.parent->left == &null_x)
+ null_x.parent->left = NULL;
+ else {
+ RBT_ASSERT(null_x.parent->right == &null_x);
+ null_x.parent->right = NULL;
+ }
+ RBT_ASSERT(!null_x.left);
+ RBT_ASSERT(!null_x.right);
+ }
+ else if (*root == &null_x) {
+ *root = NULL;
+ RBT_ASSERT(!null_x.left);
+ RBT_ASSERT(!null_x.right);
+ }
+ }
+
+ DESTROY_TREE_NODE(del);
+
+#ifdef HARD_DEBUG
+ check_tree(*root, 0);
+#endif
+}
+
+static void
+aoff_link_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
+{
+ AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
+ AOFF_RBTree_t *blk = (AOFF_RBTree_t *) block;
+ AOFF_RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &alc->sbmbc_root : &alc->mbc_root);
+ Uint blk_sz = BLK_SZ(blk);
+
+#ifdef HARD_DEBUG
+ check_tree(*root, 0);
+#endif
+
+ blk->flags = 0;
+ blk->left = NULL;
+ blk->right = NULL;
+ blk->max_sz = blk_sz;
+
+ if (!*root) {
+ blk->parent = NULL;
+ SET_BLACK(blk);
+ *root = blk;
+ }
+ else {
+ AOFF_RBTree_t *x = *root;
+ while (1) {
+ if (x->max_sz < blk_sz) {
+ x->max_sz = blk_sz;
+ }
+ if (blk < x) {
+ if (!x->left) {
+ blk->parent = x;
+ x->left = blk;
+ break;
+ }
+ x = x->left;
+ }
+ else {
+ if (!x->right) {
+ blk->parent = x;
+ x->right = blk;
+ break;
+ }
+ x = x->right;
+ }
+
+ }
+
+ /* Insert block into size tree */
+ RBT_ASSERT(blk->parent);
+
+ SET_RED(blk);
+ if (IS_RED(blk->parent))
+ tree_insert_fixup(root, blk);
+ }
+
+#ifdef HARD_DEBUG
+ check_tree(*root, 0);
+#endif
+}
+
+static Block_t *
+aoff_get_free_block(Allctr_t *allctr, Uint size,
+ Block_t *cand_blk, Uint cand_size, Uint32 flags)
+{
+ AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
+ AOFF_RBTree_t *x = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? alc->sbmbc_root : alc->mbc_root);
+ AOFF_RBTree_t *blk = NULL;
+#ifdef HARD_DEBUG
+ AOFF_RBTree_t* dbg_blk = check_tree(x, size);
+#endif
+
+ ASSERT(!cand_blk || cand_size >= size);
+
+ while (x) {
+ if (x->left && x->left->max_sz >= size) {
+ x = x->left;
+ }
+ else if (BLK_SZ(x) >= size) {
+ blk = x;
+ break;
+ }
+ else {
+ x = x->right;
+ }
+ }
+
+#ifdef HARD_DEBUG
+ ASSERT(blk == dbg_blk);
+#endif
+
+ if (!blk)
+ return NULL;
+
+ if (cand_blk && cand_blk < &blk->hdr) {
+ return NULL; /* cand_blk was better */
+ }
+
+ aoff_unlink_free_block(allctr, (Block_t *) blk, flags);
+
+ return (Block_t *) blk;
+}
+
+
+/*
+ * info_options()
+ */
+
+static struct {
+ Eterm as;
+ Eterm aoff;
+#ifdef DEBUG
+ Eterm end_of_atoms;
+#endif
+} am;
+
+static void ERTS_INLINE atom_init(Eterm *atom, char *name)
+{
+ *atom = am_atom_put(name, strlen(name));
+}
+#define AM_INIT(AM) atom_init(&am.AM, #AM)
+
+static void
+init_atoms(void)
+{
+#ifdef DEBUG
+ Eterm *atom;
+#endif
+
+ if (atoms_initialized)
+ return;
+
+#ifdef DEBUG
+ for (atom = (Eterm *) &am; atom <= &am.end_of_atoms; atom++) {
+ *atom = THE_NON_VALUE;
+ }
+#endif
+ AM_INIT(as);
+ AM_INIT(aoff);
+
+#ifdef DEBUG
+ for (atom = (Eterm *) &am; atom < &am.end_of_atoms; atom++) {
+ ASSERT(*atom != THE_NON_VALUE);
+ }
+#endif
+
+ atoms_initialized = 1;
+}
+
+
+#define bld_uint erts_bld_uint
+#define bld_cons erts_bld_cons
+#define bld_tuple erts_bld_tuple
+
+static ERTS_INLINE void
+add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
+{
+ *lp = bld_cons(hpp, szp, bld_tuple(hpp, szp, 2, el1, el2), *lp);
+}
+
+static Eterm
+info_options(Allctr_t *allctr,
+ char *prefix,
+ int *print_to_p,
+ void *print_to_arg,
+ Uint **hpp,
+ Uint *szp)
+{
+ Eterm res = THE_NON_VALUE;
+
+ if (print_to_p) {
+ erts_print(*print_to_p,
+ print_to_arg,
+ "%sas: %s\n",
+ prefix,
+ "aoff");
+ }
+
+ if (hpp || szp) {
+
+ if (!atoms_initialized)
+ erl_exit(1, "%s:%d: Internal error: Atoms not initialized",
+ __FILE__, __LINE__);;
+
+ res = NIL;
+ add_2tup(hpp, szp, &res, am.as, am.aoff);
+ }
+
+ return res;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * NOTE: erts_aoffalc_test() is only supposed to be used for testing. *
+ * *
+ * Keep alloc_SUITE_data/allocator_test.h updated if changes are made *
+ * to erts_aoffalc_test() *
+\* */
+
+unsigned long
+erts_aoffalc_test(unsigned long op, unsigned long a1, unsigned long a2)
+{
+ switch (op) {
+ case 0x500: return (unsigned long) 0; /* IS_AOBF */
+ case 0x501: return (unsigned long) ((AOFFAllctr_t *) a1)->mbc_root;
+ case 0x502: return (unsigned long) ((AOFF_RBTree_t *) a1)->parent;
+ case 0x503: return (unsigned long) ((AOFF_RBTree_t *) a1)->left;
+ case 0x504: return (unsigned long) ((AOFF_RBTree_t *) a1)->right;
+ case 0x506: return (unsigned long) IS_BLACK((AOFF_RBTree_t *) a1);
+ case 0x508: return (unsigned long) 1; /* IS_AOFF */
+ case 0x509: return (unsigned long) ((AOFF_RBTree_t *) a1)->max_sz;
+ default: ASSERT(0); return ~((unsigned long) 0);
+ }
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Debug functions *
+\* */
+
+
+#ifdef HARD_DEBUG
+
+#define IS_LEFT_VISITED(FB) ((FB)->flags & LEFT_VISITED_FLG)
+#define IS_RIGHT_VISITED(FB) ((FB)->flags & RIGHT_VISITED_FLG)
+
+#define SET_LEFT_VISITED(FB) ((FB)->flags |= LEFT_VISITED_FLG)
+#define SET_RIGHT_VISITED(FB) ((FB)->flags |= RIGHT_VISITED_FLG)
+
+#define UNSET_LEFT_VISITED(FB) ((FB)->flags &= ~LEFT_VISITED_FLG)
+#define UNSET_RIGHT_VISITED(FB) ((FB)->flags &= ~RIGHT_VISITED_FLG)
+
+
+#if 0
+# define PRINT_TREE
+#else
+# undef PRINT_TREE
+#endif
+
+#ifdef PRINT_TREE
+static void print_tree(AOFF_RBTree_t*);
+#endif
+
+/*
+ * Checks that the order between parent and children are correct,
+ * and that the Red-Black Tree properies are satisfied. if size > 0,
+ * check_tree() returns the node that satisfies "address order first fit"
+ *
+ * The Red-Black Tree properies are:
+ * 1. Every node is either red or black.
+ * 2. Every leaf (NIL) is black.
+ * 3. If a node is red, then both its children are black.
+ * 4. Every simple path from a node to a descendant leaf
+ * contains the same number of black nodes.
+ *
+ * + own.max_size == MAX(own.size, left.max_size, right.max_size)
+ */
+
+static AOFF_RBTree_t *
+check_tree(AOFF_RBTree_t* root, Uint size)
+{
+ AOFF_RBTree_t *res = NULL;
+ Sint blacks;
+ Sint curr_blacks;
+ AOFF_RBTree_t *x;
+
+#ifdef PRINT_TREE
+ print_tree(root);
+#endif
+
+ if (!root)
+ return res;
+
+ x = root;
+ ASSERT(IS_BLACK(x));
+ ASSERT(!x->parent);
+ curr_blacks = 1;
+ blacks = -1;
+
+ while (x) {
+ if (!IS_LEFT_VISITED(x)) {
+ SET_LEFT_VISITED(x);
+ if (x->left) {
+ x = x->left;
+ if (IS_BLACK(x))
+ curr_blacks++;
+ continue;
+ }
+ else {
+ if (blacks < 0)
+ blacks = curr_blacks;
+ ASSERT(blacks == curr_blacks);
+ }
+ }
+
+ if (!IS_RIGHT_VISITED(x)) {
+ SET_RIGHT_VISITED(x);
+ if (x->right) {
+ x = x->right;
+ if (IS_BLACK(x))
+ curr_blacks++;
+ continue;
+ }
+ else {
+ if (blacks < 0)
+ blacks = curr_blacks;
+ ASSERT(blacks == curr_blacks);
+ }
+ }
+
+
+ if (IS_RED(x)) {
+ ASSERT(IS_BLACK(x->right));
+ ASSERT(IS_BLACK(x->left));
+ }
+
+ ASSERT(x->parent || x == root);
+
+ if (x->left) {
+ ASSERT(x->left->parent == x);
+ ASSERT(x->left < x);
+ ASSERT(x->left->max_sz <= x->max_sz);
+ }
+
+ if (x->right) {
+ ASSERT(x->right->parent == x);
+ ASSERT(x->right > x);
+ ASSERT(x->right->max_sz <= x->max_sz);
+ }
+ ASSERT(x->max_sz >= BLK_SZ(x));
+ ASSERT(x->max_sz == BLK_SZ(x)
+ || x->max_sz == (x->left ? x->left->max_sz : 0)
+ || x->max_sz == (x->right ? x->right->max_sz : 0));
+
+ if (size && BLK_SZ(x) >= size) {
+ if (!res || x < res) {
+ res = x;
+ }
+ }
+
+ UNSET_LEFT_VISITED(x);
+ UNSET_RIGHT_VISITED(x);
+ if (IS_BLACK(x))
+ curr_blacks--;
+ x = x->parent;
+
+ }
+
+ ASSERT(curr_blacks == 0);
+
+ UNSET_LEFT_VISITED(root);
+ UNSET_RIGHT_VISITED(root);
+
+ return res;
+
+}
+
+
+#ifdef PRINT_TREE
+#define INDENT_STEP 2
+
+#include <stdio.h>
+
+static void
+print_tree_aux(AOFF_RBTree_t *x, int indent)
+{
+ int i;
+
+ if (x) {
+ print_tree_aux(x->right, indent + INDENT_STEP);
+ for (i = 0; i < indent; i++) {
+ putc(' ', stderr);
+ }
+ fprintf(stderr, "%s: sz=%lu addr=0x%lx max_size=%lu\r\n",
+ IS_BLACK(x) ? "BLACK" : "RED",
+ BLK_SZ(x), (Uint)x, x->max_sz);
+ print_tree_aux(x->left, indent + INDENT_STEP);
+ }
+}
+
+
+static void
+print_tree(AOFF_RBTree_t* root)
+{
+ fprintf(stderr, " --- AOFF tree begin ---\r\n");
+ print_tree_aux(root, 0);
+ fprintf(stderr, " --- AOFF tree end ---\r\n");
+}
+
+#endif /* PRINT_TREE */
+
+#endif /* HARD_DEBUG */
+
diff --git a/erts/emulator/beam/erl_ao_firstfit_alloc.h b/erts/emulator/beam/erl_ao_firstfit_alloc.h
new file mode 100644
index 0000000000..0bf0ec8cee
--- /dev/null
+++ b/erts/emulator/beam/erl_ao_firstfit_alloc.h
@@ -0,0 +1,60 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+
+#ifndef ERL_AO_FIRSTFIT_ALLOC__
+#define ERL_AO_FIRSTFIT_ALLOC__
+
+#include "erl_alloc_util.h"
+
+#define ERTS_ALC_AOFF_ALLOC_VSN_STR "0.9"
+
+typedef struct AOFFAllctr_t_ AOFFAllctr_t;
+
+typedef struct {
+ int dummy;
+} AOFFAllctrInit_t;
+
+#define ERTS_DEFAULT_AOFF_ALLCTR_INIT {0/*dummy*/}
+
+void erts_aoffalc_init(void);
+Allctr_t *erts_aoffalc_start(AOFFAllctr_t *, AOFFAllctrInit_t*, AllctrInit_t *);
+
+#endif /* #ifndef ERL_AO_FIRSTFIT_ALLOC__ */
+
+
+
+#if defined(GET_ERL_AOFF_ALLOC_IMPL) && !defined(ERL_AOFF_ALLOC_IMPL__)
+#define ERL_AOFF_ALLOC_IMPL__
+
+#define GET_ERL_ALLOC_UTIL_IMPL
+#include "erl_alloc_util.h"
+
+
+struct AOFFAllctr_t_ {
+ Allctr_t allctr; /* Has to be first! */
+
+ struct AOFF_RBTree_t_* mbc_root;
+ struct AOFF_RBTree_t_* sbmbc_root;
+};
+
+unsigned long erts_aoffalc_test(unsigned long, unsigned long, unsigned long);
+
+#endif /* #if defined(GET_ERL_AOFF_ALLOC_IMPL)
+ && !defined(ERL_AOFF_ALLOC_IMPL__) */
diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c
index a920bd2c8c..91b64411d4 100644
--- a/erts/emulator/beam/erl_async.c
+++ b/erts/emulator/beam/erl_async.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2000-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_bestfit_alloc.c b/erts/emulator/beam/erl_bestfit_alloc.c
index 3035e5df16..5e3032ddaa 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.c
+++ b/erts/emulator/beam/erl_bestfit_alloc.c
@@ -84,24 +84,24 @@
#ifdef HARD_DEBUG
-static RBTree_t * check_tree(BFAllctr_t *, Uint);
+static RBTree_t * check_tree(RBTree_t, int, Uint);
#endif
-static void tree_delete(Allctr_t *allctr, Block_t *del);
+static void tree_delete(Allctr_t *allctr, Block_t *del, Uint32 flags);
/* Prototypes of callback functions */
/* "address order best fit" specific callback functions */
static Block_t * aobf_get_free_block (Allctr_t *, Uint,
- Block_t *, Uint);
-static void aobf_link_free_block (Allctr_t *, Block_t *);
+ Block_t *, Uint, Uint32);
+static void aobf_link_free_block (Allctr_t *, Block_t *, Uint32);
#define aobf_unlink_free_block tree_delete
/* "best fit" specific callback functions */
static Block_t * bf_get_free_block (Allctr_t *, Uint,
- Block_t *, Uint);
-static void bf_link_free_block (Allctr_t *, Block_t *);
-static ERTS_INLINE void bf_unlink_free_block (Allctr_t *, Block_t *);
+ Block_t *, Uint, Uint32);
+static void bf_link_free_block (Allctr_t *, Block_t *, Uint32);
+static ERTS_INLINE void bf_unlink_free_block (Allctr_t *, Block_t *, Uint32);
static Eterm info_options (Allctr_t *, char *, int *,
@@ -303,7 +303,7 @@ replace(RBTree_t **root, RBTree_t *x, RBTree_t *y)
}
static void
-tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
+tree_insert_fixup(RBTree_t **root, RBTree_t *blk)
{
RBTree_t *x = blk, *y;
@@ -311,7 +311,7 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
* Rearrange the tree so that it satisfies the Red-Black Tree properties
*/
- RBT_ASSERT(x != bfallctr->root && IS_RED(x->parent));
+ RBT_ASSERT(x != *root && IS_RED(x->parent));
do {
/*
@@ -336,7 +336,7 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
if (x == x->parent->right) {
x = x->parent;
- left_rotate(&bfallctr->root, x);
+ left_rotate(root, x);
}
RBT_ASSERT(x == x->parent->parent->left->left);
@@ -347,7 +347,7 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
SET_BLACK(x->parent);
SET_RED(x->parent->parent);
- right_rotate(&bfallctr->root, x->parent->parent);
+ right_rotate(root, x->parent->parent);
RBT_ASSERT(x == x->parent->left);
RBT_ASSERT(IS_RED(x));
@@ -370,7 +370,7 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
if (x == x->parent->left) {
x = x->parent;
- right_rotate(&bfallctr->root, x);
+ right_rotate(root, x);
}
RBT_ASSERT(x == x->parent->parent->right->right);
@@ -381,7 +381,7 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
SET_BLACK(x->parent);
SET_RED(x->parent->parent);
- left_rotate(&bfallctr->root, x->parent->parent);
+ left_rotate(root, x->parent->parent);
RBT_ASSERT(x == x->parent->right);
RBT_ASSERT(IS_RED(x));
@@ -390,9 +390,9 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
break;
}
}
- } while (x != bfallctr->root && IS_RED(x->parent));
+ } while (x != *root && IS_RED(x->parent));
- SET_BLACK(bfallctr->root);
+ SET_BLACK(*root);
}
@@ -402,18 +402,22 @@ tree_insert_fixup(BFAllctr_t *bfallctr, RBTree_t *blk)
* callback function in the address order case.
*/
static void
-tree_delete(Allctr_t *allctr, Block_t *del)
+tree_delete(Allctr_t *allctr, Block_t *del, Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
Uint spliced_is_black;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
RBTree_t *x, *y, *z = (RBTree_t *) del;
RBTree_t null_x; /* null_x is used to get the fixup started when we
splice out a node without children. */
null_x.parent = NULL;
+
#ifdef HARD_DEBUG
- check_tree(bfallctr, 0);
+ check_tree(*root, bfallctr->address_order, 0);
#endif
/* Remove node from tree... */
@@ -440,8 +444,8 @@ tree_delete(Allctr_t *allctr, Block_t *del)
}
if (!y->parent) {
- RBT_ASSERT(bfallctr->root == y);
- bfallctr->root = x;
+ RBT_ASSERT(*root == y);
+ *root = x;
}
else if (y == y->parent->left)
y->parent->left = x;
@@ -451,7 +455,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
}
if (y != z) {
/* We spliced out the successor of z; replace z by the successor */
- replace(&bfallctr->root, z, y);
+ replace(root, z, y);
}
if (spliced_is_black) {
@@ -476,7 +480,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
SET_BLACK(y);
RBT_ASSERT(IS_BLACK(x->parent));
SET_RED(x->parent);
- left_rotate(&bfallctr->root, x->parent);
+ left_rotate(root, x->parent);
y = x->parent->right;
}
RBT_ASSERT(y);
@@ -489,7 +493,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
if (IS_BLACK(y->right)) {
SET_BLACK(y->left);
SET_RED(y);
- right_rotate(&bfallctr->root, y);
+ right_rotate(root, y);
y = x->parent->right;
}
RBT_ASSERT(y);
@@ -500,8 +504,8 @@ tree_delete(Allctr_t *allctr, Block_t *del)
}
RBT_ASSERT(y->right);
SET_BLACK(y->right);
- left_rotate(&bfallctr->root, x->parent);
- x = bfallctr->root;
+ left_rotate(root, x->parent);
+ x = *root;
break;
}
}
@@ -515,7 +519,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
SET_BLACK(y);
RBT_ASSERT(IS_BLACK(x->parent));
SET_RED(x->parent);
- right_rotate(&bfallctr->root, x->parent);
+ right_rotate(root, x->parent);
y = x->parent->left;
}
RBT_ASSERT(y);
@@ -528,7 +532,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
if (IS_BLACK(y->left)) {
SET_BLACK(y->right);
SET_RED(y);
- left_rotate(&bfallctr->root, y);
+ left_rotate(root, y);
y = x->parent->left;
}
RBT_ASSERT(y);
@@ -538,8 +542,8 @@ tree_delete(Allctr_t *allctr, Block_t *del)
}
RBT_ASSERT(y->left);
SET_BLACK(y->left);
- right_rotate(&bfallctr->root, x->parent);
- x = bfallctr->root;
+ right_rotate(root, x->parent);
+ x = *root;
break;
}
}
@@ -556,8 +560,8 @@ tree_delete(Allctr_t *allctr, Block_t *del)
RBT_ASSERT(!null_x.left);
RBT_ASSERT(!null_x.right);
}
- else if (bfallctr->root == &null_x) {
- bfallctr->root = NULL;
+ else if (*root == &null_x) {
+ *root = NULL;
RBT_ASSERT(!null_x.left);
RBT_ASSERT(!null_x.right);
}
@@ -567,7 +571,7 @@ tree_delete(Allctr_t *allctr, Block_t *del)
DESTROY_TREE_NODE(del);
#ifdef HARD_DEBUG
- check_tree(bfallctr, 0);
+ check_tree(root, bfallctr->address_order, 0);
#endif
}
@@ -577,23 +581,28 @@ tree_delete(Allctr_t *allctr, Block_t *del)
\* */
static void
-aobf_link_free_block(Allctr_t *allctr, Block_t *block)
+aobf_link_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
RBTree_t *blk = (RBTree_t *) block;
Uint blk_sz = BLK_SZ(blk);
+
+
blk->flags = 0;
blk->left = NULL;
blk->right = NULL;
- if (!bfallctr->root) {
+ if (!*root) {
blk->parent = NULL;
SET_BLACK(blk);
- bfallctr->root = blk;
+ *root = blk;
}
else {
- RBTree_t *x = bfallctr->root;
+ RBTree_t *x = *root;
while (1) {
Uint size;
@@ -623,28 +632,32 @@ aobf_link_free_block(Allctr_t *allctr, Block_t *block)
SET_RED(blk);
if (IS_RED(blk->parent))
- tree_insert_fixup(bfallctr, blk);
+ tree_insert_fixup(root, blk);
}
#ifdef HARD_DEBUG
- check_tree(bfallctr, 0);
+ check_tree(root, 1, 0);
#endif
}
#if 0 /* tree_delete() is directly used instead */
static void
-aobf_unlink_free_block(Allctr_t *allctr, Block_t *block)
+aobf_unlink_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
- tree_delete(allctr, block);
+ tree_delete(allctr, block, flags);
}
#endif
static Block_t *
aobf_get_free_block(Allctr_t *allctr, Uint size,
- Block_t *cand_blk, Uint cand_size)
+ Block_t *cand_blk, Uint cand_size,
+ Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
- RBTree_t *x = bfallctr->root;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
+ RBTree_t *x = *root;
RBTree_t *blk = NULL;
Uint blk_sz;
@@ -665,7 +678,7 @@ aobf_get_free_block(Allctr_t *allctr, Uint size,
return NULL;
#ifdef HARD_DEBUG
- ASSERT(blk == check_tree(bfallctr, size));
+ ASSERT(blk == check_tree(root, 1, size));
#endif
if (cand_blk) {
@@ -676,7 +689,7 @@ aobf_get_free_block(Allctr_t *allctr, Uint size,
return NULL; /* cand_blk was better */
}
- aobf_unlink_free_block(allctr, (Block_t *) blk);
+ aobf_unlink_free_block(allctr, (Block_t *) blk, flags);
return (Block_t *) blk;
}
@@ -687,9 +700,12 @@ aobf_get_free_block(Allctr_t *allctr, Uint size,
\* */
static void
-bf_link_free_block(Allctr_t *allctr, Block_t *block)
+bf_link_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
RBTree_t *blk = (RBTree_t *) block;
Uint blk_sz = BLK_SZ(blk);
@@ -700,13 +716,13 @@ bf_link_free_block(Allctr_t *allctr, Block_t *block)
blk->left = NULL;
blk->right = NULL;
- if (!bfallctr->root) {
+ if (!*root) {
blk->parent = NULL;
SET_BLACK(blk);
- bfallctr->root = blk;
+ *root = blk;
}
else {
- RBTree_t *x = bfallctr->root;
+ RBTree_t *x = *root;
while (1) {
Uint size;
@@ -745,7 +761,7 @@ bf_link_free_block(Allctr_t *allctr, Block_t *block)
SET_RED(blk);
if (IS_RED(blk->parent))
- tree_insert_fixup(bfallctr, blk);
+ tree_insert_fixup(root, blk);
}
@@ -753,14 +769,17 @@ bf_link_free_block(Allctr_t *allctr, Block_t *block)
LIST_NEXT(blk) = NULL;
#ifdef HARD_DEBUG
- check_tree(bfallctr, 0);
+ check_tree(root, 0, 0);
#endif
}
static ERTS_INLINE void
-bf_unlink_free_block(Allctr_t *allctr, Block_t *block)
+bf_unlink_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
RBTree_t *x = (RBTree_t *) block;
if (IS_LIST_ELEM(x)) {
@@ -778,9 +797,9 @@ bf_unlink_free_block(Allctr_t *allctr, Block_t *block)
ASSERT(IS_LIST_ELEM(LIST_NEXT(x)));
#ifdef HARD_DEBUG
- check_tree(bfallctr, 0);
+ check_tree(root, 0, 0);
#endif
- replace(&bfallctr->root, x, LIST_NEXT(x));
+ replace(root, x, LIST_NEXT(x));
#ifdef HARD_DEBUG
check_tree(bfallctr, 0);
@@ -788,7 +807,7 @@ bf_unlink_free_block(Allctr_t *allctr, Block_t *block)
}
else {
/* Remove from tree */
- tree_delete(allctr, block);
+ tree_delete(allctr, block, flags);
}
DESTROY_LIST_ELEM(x);
@@ -797,10 +816,14 @@ bf_unlink_free_block(Allctr_t *allctr, Block_t *block)
static Block_t *
bf_get_free_block(Allctr_t *allctr, Uint size,
- Block_t *cand_blk, Uint cand_size)
+ Block_t *cand_blk, Uint cand_size,
+ Uint32 flags)
{
BFAllctr_t *bfallctr = (BFAllctr_t *) allctr;
- RBTree_t *x = bfallctr->root;
+ RBTree_t **root = ((flags & ERTS_ALCU_FLG_SBMBC)
+ ? &bfallctr->sbmbc_root
+ : &bfallctr->mbc_root);
+ RBTree_t *x = *root;
RBTree_t *blk = NULL;
Uint blk_sz;
@@ -827,7 +850,7 @@ bf_get_free_block(Allctr_t *allctr, Uint size,
#ifdef HARD_DEBUG
{
- RBTree_t *ct_blk = check_tree(bfallctr, size);
+ RBTree_t *ct_blk = check_tree(root, 0, size);
ASSERT(BLK_SZ(ct_blk) == BLK_SZ(blk));
}
#endif
@@ -839,7 +862,7 @@ bf_get_free_block(Allctr_t *allctr, Uint size,
the tree node */
blk = LIST_NEXT(blk) ? LIST_NEXT(blk) : blk;
- bf_unlink_free_block(allctr, (Block_t *) blk);
+ bf_unlink_free_block(allctr, (Block_t *) blk, flags);
return (Block_t *) blk;
}
@@ -949,13 +972,14 @@ erts_bfalc_test(unsigned long op, unsigned long a1, unsigned long a2)
{
switch (op) {
case 0x200: return (unsigned long) ((BFAllctr_t *) a1)->address_order;
- case 0x201: return (unsigned long) ((BFAllctr_t *) a1)->root;
+ case 0x201: return (unsigned long) ((BFAllctr_t *) a1)->mbc_root;
case 0x202: return (unsigned long) ((RBTree_t *) a1)->parent;
case 0x203: return (unsigned long) ((RBTree_t *) a1)->left;
case 0x204: return (unsigned long) ((RBTree_t *) a1)->right;
case 0x205: return (unsigned long) ((RBTreeList_t *) a1)->next;
case 0x206: return (unsigned long) IS_BLACK((RBTree_t *) a1);
case 0x207: return (unsigned long) IS_TREE_NODE((RBTree_t *) a1);
+ case 0x208: return (unsigned long) 0; /* IS_AOFF */
default: ASSERT(0); return ~((unsigned long) 0);
}
}
@@ -985,7 +1009,7 @@ erts_bfalc_test(unsigned long op, unsigned long a1, unsigned long a2)
#endif
#ifdef PRINT_TREE
-static void print_tree(BFAllctr_t *);
+static void print_tree(RBTree_t *, int);
#endif
/*
@@ -1003,7 +1027,7 @@ static void print_tree(BFAllctr_t *);
*/
static RBTree_t *
-check_tree(BFAllctr_t *bfallctr, Uint size)
+check_tree(RBTree_t *root, int ao, Uint size)
{
RBTree_t *res = NULL;
Sint blacks;
@@ -1011,13 +1035,13 @@ check_tree(BFAllctr_t *bfallctr, Uint size)
RBTree_t *x;
#ifdef PRINT_TREE
- print_tree(bfallctr);
+ print_tree(root, ao);
#endif
- if (!bfallctr->root)
+ if (!root)
return res;
- x = bfallctr->root;
+ x = root;
ASSERT(IS_BLACK(x));
ASSERT(!x->parent);
curr_blacks = 1;
@@ -1060,11 +1084,11 @@ check_tree(BFAllctr_t *bfallctr, Uint size)
ASSERT(IS_BLACK(x->left));
}
- ASSERT(x->parent || x == bfallctr->root);
+ ASSERT(x->parent || x == root);
if (x->left) {
ASSERT(x->left->parent == x);
- if (bfallctr->address_order) {
+ if (ao) {
ASSERT(BLK_SZ(x->left) < BLK_SZ(x)
|| (BLK_SZ(x->left) == BLK_SZ(x) && x->left < x));
}
@@ -1076,7 +1100,7 @@ check_tree(BFAllctr_t *bfallctr, Uint size)
if (x->right) {
ASSERT(x->right->parent == x);
- if (bfallctr->address_order) {
+ if (ao) {
ASSERT(BLK_SZ(x->right) > BLK_SZ(x)
|| (BLK_SZ(x->right) == BLK_SZ(x) && x->right > x));
}
@@ -1087,7 +1111,7 @@ check_tree(BFAllctr_t *bfallctr, Uint size)
}
if (size && BLK_SZ(x) >= size) {
- if (bfallctr->address_order) {
+ if (ao) {
if (!res
|| BLK_SZ(x) < BLK_SZ(res)
|| (BLK_SZ(x) == BLK_SZ(res) && x < res))
@@ -1109,8 +1133,8 @@ check_tree(BFAllctr_t *bfallctr, Uint size)
ASSERT(curr_blacks == 0);
- UNSET_LEFT_VISITED(bfallctr->root);
- UNSET_RIGHT_VISITED(bfallctr->root);
+ UNSET_LEFT_VISITED(root);
+ UNSET_RIGHT_VISITED(root);
return res;
@@ -1148,11 +1172,11 @@ print_tree_aux(RBTree_t *x, int indent)
static void
-print_tree(BFAllctr_t *bfallctr)
+print_tree(RBTree_t *root, int ao)
{
- char *type = bfallctr->address_order ? "Size-Adress" : "Size";
+ char *type = ao ? "Size-Adress" : "Size";
fprintf(stderr, " --- %s tree begin ---\r\n", type);
- print_tree_aux(bfallctr->root, 0);
+ print_tree_aux(root, 0);
fprintf(stderr, " --- %s tree end ---\r\n", type);
}
diff --git a/erts/emulator/beam/erl_bestfit_alloc.h b/erts/emulator/beam/erl_bestfit_alloc.h
index cb35e21e57..faa2d9742e 100644
--- a/erts/emulator/beam/erl_bestfit_alloc.h
+++ b/erts/emulator/beam/erl_bestfit_alloc.h
@@ -54,7 +54,8 @@ typedef struct RBTree_t_ RBTree_t;
struct BFAllctr_t_ {
Allctr_t allctr; /* Has to be first! */
- RBTree_t * root;
+ RBTree_t * mbc_root;
+ RBTree_t * sbmbc_root;
int address_order;
};
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 0174e5fc43..e56084b9cb 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 0f67733fa4..3309ea706b 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -150,7 +150,7 @@ void erts_bits_destroy_state(ERL_BITS_PROTO_0);
* NBYTES(x) returns the number of bytes needed to store x bits.
*/
-#define NBYTES(x) (((x) + 7) >> 3)
+#define NBYTES(x) (((Uint64)(x) + (Uint64) 7) >> 3)
#define BYTE_OFFSET(ofs) ((Uint) (ofs) >> 3)
#define BIT_OFFSET(ofs) ((ofs) & 7)
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index e0a6aa05c6..eb50f56502 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -338,13 +338,13 @@ static ERTS_INLINE void db_unlock(DbTable* tb, db_lock_kind_t kind)
ASSERT(tb != meta_pid_to_tab && tb != meta_pid_to_fixed_tab);
if (tb->common.type & DB_FINE_LOCKED) {
- if (tb->common.is_thread_safe) {
- ASSERT(kind == LCK_WRITE);
+ if (kind == LCK_WRITE) {
+ ASSERT(tb->common.is_thread_safe);
tb->common.is_thread_safe = 0;
erts_smp_rwmtx_rwunlock(&tb->common.rwlock);
}
else {
- ASSERT(kind != LCK_WRITE);
+ ASSERT(!tb->common.is_thread_safe);
erts_smp_rwmtx_runlock(&tb->common.rwlock);
}
}
@@ -543,9 +543,9 @@ static int remove_named_tab(DbTable *tb, int have_lock)
* We keep our increased refc over this op in order to
* prevent the table from disapearing.
*/
- erts_smp_rwmtx_rwunlock(&tb->common.rwlock);
+ db_unlock(tb, LCK_WRITE);
erts_smp_rwmtx_rwlock(rwlock);
- erts_smp_rwmtx_rwlock(&tb->common.rwlock);
+ db_lock(tb, LCK_WRITE);
}
#endif
@@ -1650,24 +1650,6 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
tb->common.status &= ~(DB_PROTECTED|DB_PUBLIC|DB_PRIVATE);
tb->common.status |= DB_DELETE;
- mmtl = get_meta_main_tab_lock(tb->common.slot);
-#ifdef ERTS_SMP
- if (erts_smp_rwmtx_tryrwlock(mmtl) == EBUSY) {
- /*
- * We keep our increased refc over this op in order to
- * prevent the table from disapearing.
- */
- erts_smp_rwmtx_rwunlock(&tb->common.rwlock);
- erts_smp_rwmtx_rwlock(mmtl);
- erts_smp_rwmtx_rwlock(&tb->common.rwlock);
- }
-#endif
- /* We must keep the slot, to be found by db_proc_dead() if process dies */
- MARK_SLOT_DEAD(tb->common.slot);
- erts_smp_rwmtx_rwunlock(mmtl);
- if (is_atom(tb->common.id))
- remove_named_tab(tb, 0);
-
if (tb->common.owner != BIF_P->id) {
DeclareTmpHeap(meta_tuple,3,BIF_P);
@@ -1691,6 +1673,25 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
UnUseTmpHeap(3,BIF_P);
}
+
+ mmtl = get_meta_main_tab_lock(tb->common.slot);
+#ifdef ERTS_SMP
+ if (erts_smp_rwmtx_tryrwlock(mmtl) == EBUSY) {
+ /*
+ * We keep our increased refc over this op in order to
+ * prevent the table from disapearing.
+ */
+ db_unlock(tb, LCK_WRITE);
+ erts_smp_rwmtx_rwlock(mmtl);
+ db_lock(tb, LCK_WRITE);
+ }
+#endif
+ /* We must keep the slot, to be found by db_proc_dead() if process dies */
+ MARK_SLOT_DEAD(tb->common.slot);
+ erts_smp_rwmtx_rwunlock(mmtl);
+ if (is_atom(tb->common.id))
+ remove_named_tab(tb, 0);
+
/* disable inheritance */
free_heir_data(tb);
tb->common.heir = am_none;
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index c3b074f782..e5be1f253a 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1731,6 +1731,7 @@ Eterm db_prog_match(Process *c_p, Binary *bprog,
#define BEGIN_ATOMIC_TRACE(p) \
do { \
if (! atomic_trace) { \
+ erts_refc_inc(&bprog->refc, 2); \
erts_smp_proc_unlock((p), ERTS_PROC_LOCK_MAIN); \
erts_smp_block_system(0); \
atomic_trace = !0; \
@@ -1741,6 +1742,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog,
if (atomic_trace) { \
erts_smp_release_system(); \
erts_smp_proc_lock((p), ERTS_PROC_LOCK_MAIN); \
+ if (erts_refc_dectest(&bprog->refc, 0) == 0) {\
+ erts_bin_free(bprog); \
+ } \
atomic_trace = 0; \
} \
} while (0)
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 069b71ab0d..401967a8de 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 5edcd667e7..e3445bcdc5 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -100,14 +100,14 @@ static Uint combined_message_size(Process* p);
static void remove_message_buffers(Process* p);
static int major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl);
static int minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl);
-static void do_minor(Process *p, int new_sz, Eterm* objv, int nobj);
+static void do_minor(Process *p, Uint new_sz, Eterm* objv, int nobj);
static Eterm* sweep_rootset(Rootset *rootset, Eterm* htop, char* src, Uint src_size);
static Eterm* sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size);
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, int size_before,
+static Uint adjust_after_fullsweep(Process *p, Uint size_before,
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);
@@ -441,7 +441,15 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
p->last_old_htop = p->old_htop;
#endif
- return ((int) (HEAP_TOP(p) - HEAP_START(p)) / 10);
+ /* FIXME: This function should really return an Sint, i.e., a possibly
+ 64 bit wide signed integer, but that requires updating all the code
+ that calls it. For now, we just return INT_MAX if the result is too
+ large for an int. */
+ {
+ Sint result = (HEAP_TOP(p) - HEAP_START(p)) / 10;
+ if (result >= INT_MAX) return INT_MAX;
+ else return (int) result;
+ }
}
/*
@@ -599,7 +607,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, Uint lit_size)
char* area;
Uint area_size;
Eterm* old_htop;
- int n;
+ Uint n;
/*
* Set GC state.
@@ -731,7 +739,7 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
* This improved Estone by more than 1200 estones on my computer
* (Ultra Sparc 10).
*/
- size_t new_sz = erts_next_heap_size(HEAP_TOP(p) - HEAP_START(p), 1);
+ Uint new_sz = erts_next_heap_size(HEAP_TOP(p) - HEAP_START(p), 1);
/* Create new, empty old_heap */
n_old = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_OLD_HEAP,
@@ -871,12 +879,12 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
#endif /* HIPE */
static void
-do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
+do_minor(Process *p, Uint new_sz, Eterm* objv, int nobj)
{
Rootset rootset; /* Rootset for GC (stack, dictionary, etc). */
Roots* roots;
Eterm* n_htop;
- int n;
+ Uint n;
Eterm* ptr;
Eterm val;
Eterm gval;
@@ -1079,14 +1087,14 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
{
Rootset rootset;
Roots* roots;
- int size_before;
+ Uint size_before;
Eterm* n_heap;
Eterm* n_htop;
char* src = (char *) HEAP_START(p);
Uint src_size = (char *) HEAP_TOP(p) - src;
char* oh = (char *) OLD_HEAP(p);
Uint oh_size = (char *) OLD_HTOP(p) - oh;
- int n;
+ Uint n;
Uint new_sz;
Uint fragments = MBUF_SIZE(p) + combined_message_size(p);
ErlMessage *msgp;
@@ -1312,10 +1320,10 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
}
static Uint
-adjust_after_fullsweep(Process *p, int size_before, int need, Eterm *objv, int nobj)
+adjust_after_fullsweep(Process *p, Uint size_before, int need, Eterm *objv, int nobj)
{
- int wanted, sz, size_after, need_after;
- int stack_size = STACK_SZ_ON_HEAP(p);
+ Uint wanted, sz, size_after, need_after;
+ Uint stack_size = STACK_SZ_ON_HEAP(p);
Uint reclaimed_now;
size_after = (HEAP_TOP(p) - HEAP_START(p));
@@ -1915,8 +1923,8 @@ static void
grow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj)
{
Eterm* new_heap;
- int heap_size = HEAP_TOP(p) - HEAP_START(p);
- int stack_size = p->hend - p->stop;
+ Uint heap_size = HEAP_TOP(p) - HEAP_START(p);
+ Uint stack_size = p->hend - p->stop;
Sint offs;
ASSERT(HEAP_SIZE(p) < new_sz);
@@ -1954,10 +1962,10 @@ static void
shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj)
{
Eterm* new_heap;
- int heap_size = HEAP_TOP(p) - HEAP_START(p);
+ Uint heap_size = HEAP_TOP(p) - HEAP_START(p);
Sint offs;
- int stack_size = p->hend - p->stop;
+ Uint stack_size = p->hend - p->stop;
ASSERT(new_sz < p->heap_sz);
sys_memmove(p->heap + new_sz - stack_size, p->stop, stack_size *
diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c
index 76b206d76f..1cc508ac5a 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.c
+++ b/erts/emulator/beam/erl_goodfit_alloc.c
@@ -163,10 +163,10 @@ BKT_MIN_SZ(GFAllctr_t *gfallctr, int ix)
/* Prototypes of callback functions */
static Block_t * get_free_block (Allctr_t *, Uint,
- Block_t *, Uint);
-static void link_free_block (Allctr_t *, Block_t *);
-static void unlink_free_block (Allctr_t *, Block_t *);
-static void update_last_aux_mbc (Allctr_t *, Carrier_t *);
+ Block_t *, Uint, Uint32);
+static void link_free_block (Allctr_t *, Block_t *, Uint32);
+static void unlink_free_block (Allctr_t *, Block_t *, Uint32);
+static void update_last_aux_mbc (Allctr_t *, Carrier_t *, Uint32);
static Eterm info_options (Allctr_t *, char *, int *,
void *, Uint **, Uint *);
static void init_atoms (void);
@@ -197,6 +197,8 @@ erts_gfalc_start(GFAllctr_t *gfallctr,
is a struct). */
Allctr_t *allctr = (Allctr_t *) gfallctr;
+ init->sbmbct = 0; /* Small mbc not yet supported by goodfit */
+
sys_memcpy((void *) gfallctr, (void *) &nulled_state, sizeof(GFAllctr_t));
allctr->mbc_header_size = sizeof(Carrier_t);
@@ -379,7 +381,7 @@ search_bucket(Allctr_t *allctr, int ix, Uint size)
static Block_t *
get_free_block(Allctr_t *allctr, Uint size,
- Block_t *cand_blk, Uint cand_size)
+ Block_t *cand_blk, Uint cand_size, Uint32 flags)
{
GFAllctr_t *gfallctr = (GFAllctr_t *) allctr;
int unsafe_bi, min_bi;
@@ -398,7 +400,7 @@ get_free_block(Allctr_t *allctr, Uint size,
if (blk) {
if (cand_blk && cand_size <= BLK_SZ(blk))
return NULL; /* cand_blk was better */
- unlink_free_block(allctr, blk);
+ unlink_free_block(allctr, blk, flags);
return blk;
}
if (min_bi < NO_OF_BKTS - 1) {
@@ -418,14 +420,14 @@ get_free_block(Allctr_t *allctr, Uint size,
ASSERT(blk);
if (cand_blk && cand_size <= BLK_SZ(blk))
return NULL; /* cand_blk was better */
- unlink_free_block(allctr, blk);
+ unlink_free_block(allctr, blk, flags);
return blk;
}
static void
-link_free_block(Allctr_t *allctr, Block_t *block)
+link_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
GFAllctr_t *gfallctr = (GFAllctr_t *) allctr;
GFFreeBlock_t *blk = (GFFreeBlock_t *) block;
@@ -446,7 +448,7 @@ link_free_block(Allctr_t *allctr, Block_t *block)
}
static void
-unlink_free_block(Allctr_t *allctr, Block_t *block)
+unlink_free_block(Allctr_t *allctr, Block_t *block, Uint32 flags)
{
GFAllctr_t *gfallctr = (GFAllctr_t *) allctr;
GFFreeBlock_t *blk = (GFFreeBlock_t *) block;
@@ -467,7 +469,7 @@ unlink_free_block(Allctr_t *allctr, Block_t *block)
}
static void
-update_last_aux_mbc(Allctr_t *allctr, Carrier_t *mbc)
+update_last_aux_mbc(Allctr_t *allctr, Carrier_t *mbc, Uint32 flags)
{
GFAllctr_t *gfallctr = (GFAllctr_t *) allctr;
diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c
index f3f3c22933..04ea004ef7 100644
--- a/erts/emulator/beam/erl_instrument.c
+++ b/erts/emulator/beam/erl_instrument.c
@@ -1186,6 +1186,8 @@ erts_instr_init(int stat, int map_stat)
sys_memzero((void *) stats->n, sizeof(Stat_t)*(ERTS_ALC_N_MAX+1));
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
+ if (ERTS_IS_SBMBC_ALLOCATOR_NO__(i))
+ continue;
if (erts_allctrs_info[i].enabled)
stats->ap[i] = &stats->a[i];
else
@@ -1199,6 +1201,8 @@ erts_instr_init(int stat, int map_stat)
erts_instr_memory_map = 1;
erts_instr_stat = 1;
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
+ if (ERTS_IS_SBMBC_ALLOCATOR_NO__(i))
+ continue;
erts_allctrs[i].alloc = map_stat_alloc;
erts_allctrs[i].realloc = map_stat_realloc;
erts_allctrs[i].free = map_stat_free;
@@ -1209,6 +1213,8 @@ erts_instr_init(int stat, int map_stat)
else {
erts_instr_stat = 1;
for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; i++) {
+ if (ERTS_IS_SBMBC_ALLOCATOR_NO__(i))
+ continue;
erts_allctrs[i].alloc = stat_alloc;
erts_allctrs[i].realloc = stat_realloc;
erts_allctrs[i].free = stat_free;
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index 9180508a49..587d82f2bb 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -153,6 +153,7 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "instr", NULL },
{ "fix_alloc", "index" },
{ "alcu_allocator", "index" },
+ { "sbmbc_alloc", "index" },
{ "alcu_delayed_free", "index" },
{ "mseg", NULL },
#if HALFWORD_HEAP
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 68421b4387..d9b1a8e89d 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -833,8 +833,11 @@ ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i)
ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i)
{
+ if (IS_SSMALL(i)) {
+ return make_small(i);
+ }
#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
- return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2));
+ return small_to_big(i, alloc_heap(env,2));
#elif SIZEOF_LONG == 8
ensure_heap(env,3);
return erts_sint64_to_big(i, &env->hp);
@@ -843,8 +846,11 @@ ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i)
ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)
{
+ if (IS_USMALL(0,i)) {
+ return make_small(i);
+ }
#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
- return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2));
+ return uint_to_big(i,alloc_heap(env,2));
#elif SIZEOF_LONG == 8
ensure_heap(env,3);
return erts_uint64_to_big(i, &env->hp);
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 326021643f..e6b55c45e4 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_printf_term.h b/erts/emulator/beam/erl_printf_term.h
index 4ba22f12de..a48a3de34c 100644
--- a/erts/emulator/beam/erl_printf_term.h
+++ b/erts/emulator/beam/erl_printf_term.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index dacf228e92..158eb361a4 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 6caa1e0b2d..304ce22ef2 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -1236,7 +1236,7 @@ i_bs_init_heap I I I d
i_bs_init_heap_bin_heap I I I d
-bs_init_bits Fail Sz Words Regs Flags Dst | binary_too_big_bits(Sz) => system_limit Fail
+bs_init_bits Fail Sz=o Words Regs Flags Dst => system_limit Fail
bs_init_bits Fail Sz=u Words=u==0 Regs Flags Dst => i_bs_init_bits Sz Regs Dst
bs_init_bits Fail Sz=u Words Regs Flags Dst => i_bs_init_bits_heap Sz Words Regs Dst
diff --git a/erts/emulator/beam/safe_hash.c b/erts/emulator/beam/safe_hash.c
index 3e9243c77d..4c54e19cdb 100644
--- a/erts/emulator/beam/safe_hash.c
+++ b/erts/emulator/beam/safe_hash.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 40c4a0df08..ebc4469a23 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -3709,6 +3709,8 @@ static int inet_ctl_fdopen(inet_descriptor* desc, int domain, int type,
/* check that it is a socket and that the socket is bound */
if (IS_SOCKET_ERROR(sock_name(s, (struct sockaddr*) &name, &sz)))
return ctl_error(sock_errno(), rbuf, rsize);
+ if (name.sa.sa_family != domain)
+ return ctl_error(EINVAL, rbuf, rsize);
desc->s = s;
if ((desc->event = sock_create_event(desc)) == INVALID_EVENT)
return ctl_error(sock_errno(), rbuf, rsize);
@@ -9739,7 +9741,7 @@ static int packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
if (desc->active || (len != 8))
return ctl_error(EINVAL, rbuf, rsize);
timeout = get_int32(buf);
- /* The 2nd arg, Length(4), is ignored for both UDP ans SCTP protocols,
+ /* The 2nd arg, Length(4), is ignored for both UDP and SCTP protocols,
since they are msg-oriented. */
if (enq_async(desc, tbuf, PACKET_REQ_RECV) < 0)
diff --git a/erts/emulator/hipe/hipe_bif64.c b/erts/emulator/hipe/hipe_bif64.c
index 73784fc1e8..baaf5af2cd 100644
--- a/erts/emulator/hipe/hipe_bif64.c
+++ b/erts/emulator/hipe/hipe_bif64.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/hipe/hipe_bif64.h b/erts/emulator/hipe/hipe_bif64.h
index 9fd6b79605..6d494886ec 100644
--- a/erts/emulator/hipe/hipe_bif64.h
+++ b/erts/emulator/hipe/hipe_bif64.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/hipe/hipe_bif64.tab b/erts/emulator/hipe/hipe_bif64.tab
index 6e663cfd35..228318af39 100644
--- a/erts/emulator/hipe/hipe_bif64.tab
+++ b/erts/emulator/hipe/hipe_bif64.tab
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index 16f8fb1347..e3e8367b62 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -346,7 +346,12 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
p->arity = callee_arity;
}
- /* If process is in P_WAITING state, we schedule the next process */
+ /* Schedule next process if current process was hibernated or is waiting
+ for messages */
+ if (p->flags & F_HIBERNATE_SCHED) {
+ p->flags &= ~F_HIBERNATE_SCHED;
+ goto do_schedule;
+ }
if (p->status == P_WAITING) {
goto do_schedule;
}
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c
index 71b374527e..cd4de21d65 100644
--- a/erts/emulator/sys/common/erl_check_io.c
+++ b/erts/emulator/sys/common/erl_check_io.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index fbb66ee33b..8f116030a8 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/emulator/test/alloc_SUITE_data/allocator_test.h b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
index b869a4079c..8b34375980 100644
--- a/erts/emulator/test/alloc_SUITE_data/allocator_test.h
+++ b/erts/emulator/test/alloc_SUITE_data/allocator_test.h
@@ -82,15 +82,17 @@ typedef void* erts_cond;
#define NO_OF_BKTS ((Ulong) ALC_TEST0(0x102))
#define FIND_BKT(A, I) ((int) ALC_TEST2(0x103, (A), (I)))
-/* From erl_bestfit_alloc.c */
-#define IS_AOBF(A) ((Ulong) ALC_TEST1(0x200, (A)))
-#define RBT_ROOT(A) ((RBT_t *) ALC_TEST1(0x201, (A)))
-#define RBT_PARENT(T) ((RBT_t *) ALC_TEST1(0x202, (T)))
-#define RBT_LEFT(T) ((RBT_t *) ALC_TEST1(0x203, (T)))
-#define RBT_RIGHT(T) ((RBT_t *) ALC_TEST1(0x204, (T)))
-#define RBT_NEXT(T) ((RBTL_t *) ALC_TEST1(0x205, (T)))
-#define RBT_IS_BLACK(T) ((Ulong) ALC_TEST1(0x206, (T)))
-#define RBT_IS_TREE(T) ((Ulong) ALC_TEST1(0x207, (T)))
+/* From erl_bestfit_alloc.c and erl_ao_firstfit_alloc.c */
+#define IS_AOBF(A) ((Ulong) ALC_TEST1(RBT_OP(0), (A)))
+#define RBT_ROOT(A) ((RBT_t *) ALC_TEST1(RBT_OP(1), (A)))
+#define RBT_PARENT(T) ((RBT_t *) ALC_TEST1(RBT_OP(2), (T)))
+#define RBT_LEFT(T) ((RBT_t *) ALC_TEST1(RBT_OP(3), (T)))
+#define RBT_RIGHT(T) ((RBT_t *) ALC_TEST1(RBT_OP(4), (T)))
+#define RBT_NEXT(T) ((RBTL_t *) ALC_TEST1(RBT_OP(5), (T)))
+#define RBT_IS_BLACK(T) ((Ulong) ALC_TEST1(RBT_OP(6), (T)))
+#define RBT_IS_TREE(T) ((Ulong) ALC_TEST1(RBT_OP(7), (T)))
+#define IS_AOFF(A) ((Ulong) ALC_TEST1(RBT_OP(8), (A)))
+#define RBT_MAX_SZ(T) ((Ulong) ALC_TEST1(RBT_OP(9), (T)))
/* From erl_mseg.c */
#define HAVE_MSEG() ((int) ALC_TEST0(0x400))
diff --git a/erts/emulator/test/alloc_SUITE_data/coalesce.c b/erts/emulator/test/alloc_SUITE_data/coalesce.c
index c84da97d35..6f35d3279b 100644
--- a/erts/emulator/test/alloc_SUITE_data/coalesce.c
+++ b/erts/emulator/test/alloc_SUITE_data/coalesce.c
@@ -267,7 +267,7 @@ void
testcase_run(TestCaseState_t *tcs)
{
char *argv_org[] = {"-tmmbcs1024", "-tsbct2048", "-trmbcmt100", "-tas", NULL, NULL};
- char *alg[] = {"af", "gf", "bf", "aobf", NULL};
+ char *alg[] = {"af", "gf", "bf", "aobf", "aoff", NULL};
int i;
for (i = 0; alg[i]; i++) {
diff --git a/erts/emulator/test/alloc_SUITE_data/rbtree.c b/erts/emulator/test/alloc_SUITE_data/rbtree.c
index c97e0aac1a..4e7f821baf 100644
--- a/erts/emulator/test/alloc_SUITE_data/rbtree.c
+++ b/erts/emulator/test/alloc_SUITE_data/rbtree.c
@@ -34,6 +34,14 @@ typedef struct {
#define PRINT_TREE
#endif
+/* Ugly hack to steer the test code towards the right allocator */
+#define RBT_OP(CMD) (current_rbt_type_op_base + (CMD))
+static enum {
+ BESTFIT_OP_BASE = 0x200,
+ AO_FIRSTFIT_OP_BASE = 0x500
+}current_rbt_type_op_base;
+
+
#ifdef PRINT_TREE
#define INDENT_STEP 5
@@ -65,12 +73,11 @@ print_tree_aux(TestCaseState_t *tcs, RBT_t *x, int indent)
static void
-print_tree(TestCaseState_t *tcs, RBT_t *root, int aobf)
+print_tree(TestCaseState_t *tcs, RBT_t *root)
{
- char *type = aobf ? "Size-Adress" : "Size";
- testcase_printf(tcs, " --- %s tree begin ---\r\n", type);
+ testcase_printf(tcs, " --- Tree begin ---\r\n");
print_tree_aux(tcs, root, 0);
- testcase_printf(tcs, " --- %s tree end ---\r\n", type);
+ testcase_printf(tcs, " --- Tree end ---\r\n");
}
#endif
@@ -78,7 +85,8 @@ print_tree(TestCaseState_t *tcs, RBT_t *root, int aobf)
static RBT_t *
check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
{
- int i, max_i, address_order;
+ enum { BF, AOBF, AOFF }type;
+ int i, max_i;
char stk[128];
RBT_t *root, *x, *y, *res;
Ulong x_sz, y_sz, is_x_black;
@@ -86,11 +94,14 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
res = NULL;
- address_order = IS_AOBF(alc);
+ if (IS_AOBF(alc)) type = AOBF;
+ else if (IS_AOFF(alc)) type = AOFF;
+ else type = BF;
+
root = RBT_ROOT(alc);
#ifdef PRINT_TREE
- print_tree(tcs, root, address_order);
+ print_tree(tcs, root);
#endif
max_i = i = -1;
@@ -165,12 +176,18 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
if (y) {
y_sz = BLK_SZ(y);
ASSERT(tcs, RBT_PARENT(y) == x);
- if (address_order) {
+ switch (type) {
+ case AOBF:
ASSERT(tcs, y_sz < x_sz || (y_sz == x_sz && y < x));
- }
- else {
+ break;
+ case BF:
ASSERT(tcs, RBT_IS_TREE(y));
ASSERT(tcs, y_sz < x_sz);
+ break;
+ case AOFF:
+ ASSERT(tcs, y < x);
+ ASSERT(tcs, RBT_MAX_SZ(y) <= RBT_MAX_SZ(x));
+ break;
}
}
@@ -178,16 +195,22 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
if (y) {
y_sz = BLK_SZ(y);
ASSERT(tcs, RBT_PARENT(y) == x);
- if (address_order) {
+ switch (type) {
+ case AOBF:
ASSERT(tcs, y_sz > x_sz || (y_sz == x_sz && y > x));
- }
- else {
+ break;
+ case BF:
ASSERT(tcs, RBT_IS_TREE(y));
ASSERT(tcs, y_sz > x_sz);
+ break;
+ case AOFF:
+ ASSERT(tcs, y > x);
+ ASSERT(tcs, RBT_MAX_SZ(y) <= RBT_MAX_SZ(x));
+ break;
}
}
- if (!address_order) {
+ if (type == BF) {
Ulong l_sz;
RBTL_t *l = RBT_NEXT(x);
for (l = RBT_NEXT(x); l; l = RBT_NEXT(l)) {
@@ -202,13 +225,20 @@ check_tree(TestCaseState_t *tcs, Allctr_t *alc, Ulong size)
res = x;
else {
y_sz = BLK_SZ(res);
- if (address_order) {
+ switch (type) {
+ case AOBF:
if (x_sz < y_sz || (x_sz == y_sz && x < res))
res = x;
- }
- else {
- if (!res || x_sz < y_sz)
+ break;
+ case BF:
+ if (x_sz < y_sz)
res = x;
+ break;
+ case AOFF:
+ if (x < res) {
+ res = x;
+ }
+ break;
}
}
}
@@ -257,7 +287,7 @@ static void
test_it(TestCaseState_t *tcs)
{
int i;
- Allctr_t a = ((rbtree_test_data *) tcs->extra)->allocator;
+ Allctr_t* a = ((rbtree_test_data *) tcs->extra)->allocator;
void **blk = ((rbtree_test_data *) tcs->extra)->blk;
void **fence = ((rbtree_test_data *) tcs->extra)->fence;
Ulong min_blk_sz;
@@ -338,6 +368,7 @@ testcase_run(TestCaseState_t *tcs)
{
char *argv1[] = {"-tasbf", NULL};
char *argv2[] = {"-tasaobf", NULL};
+ char *argv3[] = {"-tasaoff", NULL};
Allctr_t *a;
rbtree_test_data *td;
@@ -355,6 +386,7 @@ testcase_run(TestCaseState_t *tcs)
testcase_printf(tcs, "Starting test of best fit...\n");
+ current_rbt_type_op_base = BESTFIT_OP_BASE;
td->allocator = a = START_ALC("rbtree_bf_", 0, argv1);
ASSERT(tcs, a);
@@ -371,6 +403,7 @@ testcase_run(TestCaseState_t *tcs)
testcase_printf(tcs, "Starting test of address order best fit...\n");
+ current_rbt_type_op_base = BESTFIT_OP_BASE;
td->allocator = a = START_ALC("rbtree_aobf_", 0, argv2);
ASSERT(tcs, a);
@@ -383,4 +416,19 @@ testcase_run(TestCaseState_t *tcs)
testcase_printf(tcs, "Address order best fit test succeeded!\n");
+ /* Address order first fit... */
+
+ testcase_printf(tcs, "Starting test of address order first fit...\n");
+
+ current_rbt_type_op_base = AO_FIRSTFIT_OP_BASE;
+ td->allocator = a = START_ALC("rbtree_aoff_", 0, argv3);
+
+ ASSERT(tcs, a);
+
+ test_it(tcs);
+
+ STOP_ALC(a);
+ td->allocator = NULL;
+
+ testcase_printf(tcs, "Address order first fit test succeeded!\n");
}
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index 1959803385..7fdf36711b 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -553,6 +553,11 @@ huge_float_check({'EXIT',{badarg,_}}) -> ok.
huge_binary(Config) when is_list(Config) ->
?line 16777216 = size(<<0:(id(1 bsl 26)),(-1):(id(1 bsl 26))>>),
+ ?line garbage_collect(),
+ ?line id(<<0:((1 bsl 32)-1)>>),
+ ?line garbage_collect(),
+ ?line id(<<0:(id((1 bsl 32)-1))>>),
+ ?line garbage_collect(),
ok.
system_limit(Config) when is_list(Config) ->
@@ -565,6 +570,10 @@ system_limit(Config) when is_list(Config) ->
?line {'EXIT',{system_limit,_}} =
(catch <<(id(<<>>))/binary,0:(id(1 bsl 100))>>),
+ %% Would fail to load.
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 67)>>),
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 64)+1)>>),
+
case WordSize of
4 ->
system_limit_32();
@@ -581,6 +590,14 @@ system_limit_32() ->
?line {'EXIT',{system_limit,_}} = (catch <<0:(id(8)),42:536870912/unit:8>>),
?line {'EXIT',{system_limit,_}} =
(catch <<0:(id(8)),42:(id(536870912))/unit:8>>),
+
+ %% The size would be silently truncated, resulting in a crash.
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 35)>>),
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 32)+1)>>),
+
+ %% Would fail to load.
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:(1 bsl 43)>>),
+ ?line {'EXIT',{system_limit,_}} = (catch <<0:((1 bsl 40)+1)>>),
ok.
badarg(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index a062cea117..29cbdedd17 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -20,7 +20,9 @@
-module(code_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
- new_binary_types/1,t_check_process_code/1,t_check_process_code_ets/1,
+ new_binary_types/1,
+ t_check_process_code/1,t_check_old_code/1,
+ t_check_process_code_ets/1,
external_fun/1,get_chunk/1,module_md5/1,make_stub/1,
make_stub_many_funs/1,constant_pools/1,
false_dependency/1,coverage/1]).
@@ -31,7 +33,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[new_binary_types, t_check_process_code,
- t_check_process_code_ets, external_fun, get_chunk,
+ t_check_process_code_ets, t_check_old_code, external_fun, get_chunk,
module_md5, make_stub, make_stub_many_funs,
constant_pools, false_dependency, coverage].
@@ -248,6 +250,32 @@ fun_refc(F) ->
Count.
+%% Test the erlang:check_old_code/1 BIF.
+t_check_old_code(Config) when is_list(Config) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line File = filename:join(Data, "my_code_test"),
+
+ ?line erlang:purge_module(my_code_test),
+ ?line erlang:delete_module(my_code_test),
+ ?line catch erlang:purge_module(my_code_test),
+
+ ?line false = erlang:check_old_code(my_code_test),
+
+ ?line {ok,my_code_test,Code} = compile:file(File, [binary]),
+ ?line {module,my_code_test} = code:load_binary(my_code_test, File, Code),
+
+ ?line false = erlang:check_old_code(my_code_test),
+ ?line {module,my_code_test} = code:load_binary(my_code_test, File, Code),
+ ?line true = erlang:check_old_code(my_code_test),
+
+ ?line true = erlang:purge_module(my_code_test),
+ ?line true = erlang:delete_module(my_code_test),
+ ?line true = erlang:purge_module(my_code_test),
+
+ ?line {'EXIT',_} = (catch erlang:check_old_code([])),
+
+ ok.
+
external_fun(Config) when is_list(Config) ->
?line false = erlang:function_exported(another_code_test, x, 1),
?line ExtFun = erlang:make_fun(id(another_code_test), x, 1),
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 1147549135..beee1b735f 100644
--- a/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/otp_9302_drv.c
@@ -19,8 +19,12 @@
#ifdef __WIN32__
#include <windows.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#include "erl_driver.h"
+static void stop(ErlDrvData drv_data);
static ErlDrvData start(ErlDrvPort port,
char *command);
static void output(ErlDrvData drv_data,
@@ -31,7 +35,7 @@ static void ready_async(ErlDrvData drv_data,
static ErlDrvEntry otp_9302_drv_entry = {
NULL /* init */,
start,
- NULL /* stop */,
+ stop,
output,
NULL /* ready_input */,
NULL /* ready_output */,
@@ -53,42 +57,121 @@ static ErlDrvEntry otp_9302_drv_entry = {
NULL /* handle_monitor */
};
+typedef struct Otp9302AsyncData_ Otp9302AsyncData;
+
+typedef struct {
+ ErlDrvMutex *mtx;
+ Otp9302AsyncData *start;
+ Otp9302AsyncData *end;
+} Otp9302MsgQ;
+
+typedef struct {
+ ErlDrvPort port;
+ int smp;
+ Otp9302MsgQ msgq;
+} Otp9302Data;
+
+struct Otp9302AsyncData_ {
+ Otp9302AsyncData *next;
+ ErlDrvPort port;
+ int smp;
+ int refc;
+ int block;
+ struct {
+ ErlDrvTermData port;
+ ErlDrvTermData receiver;
+ ErlDrvTermData msg;
+ } term_data;
+ Otp9302MsgQ *msgq;
+};
+
+
DRIVER_INIT(otp_9302_drv)
{
return &otp_9302_drv_entry;
}
+static void stop(ErlDrvData drv_data)
+{
+ Otp9302Data *data = (Otp9302Data *) drv_data;
+ if (!data->smp)
+ erl_drv_mutex_destroy(data->msgq.mtx);
+ driver_free(data);
+}
+
static ErlDrvData start(ErlDrvPort port,
char *command)
{
- return (ErlDrvData) port;
-}
+ Otp9302Data *data;
+ ErlDrvSysInfo sys_info;
-typedef struct {
- ErlDrvPort port;
- ErlDrvTermData receiver;
- int block;
- int cancel;
- int eoj;
-} Otp9302AsyncData;
+ data = driver_alloc(sizeof(Otp9302Data));
+ if (!data)
+ return ERL_DRV_ERROR_GENERAL;
-static void async_invoke(void *data)
+ data->port = port;
+
+ driver_system_info(&sys_info, sizeof(ErlDrvSysInfo));
+ data->smp = sys_info.smp_support;
+
+ if (!data->smp) {
+ data->msgq.start = NULL;
+ data->msgq.end = NULL;
+ data->msgq.mtx = erl_drv_mutex_create("");
+ if (!data->msgq.mtx) {
+ driver_free(data);
+ return ERL_DRV_ERROR_GENERAL;
+ }
+ }
+
+ return (ErlDrvData) data;
+}
+
+static void send_reply(Otp9302AsyncData *adata)
{
- Otp9302AsyncData *adata = (Otp9302AsyncData *) data;
- char *what = (adata->block
- ? "block"
- : (adata->cancel
- ? "cancel"
- : (adata->eoj
- ? "end_of_jobs"
- : "job")));
ErlDrvTermData spec[] = {
- ERL_DRV_PORT, driver_mk_port(adata->port),
- ERL_DRV_ATOM, driver_mk_atom(what),
+ ERL_DRV_PORT, adata->term_data.port,
+ ERL_DRV_ATOM, adata->term_data.msg,
ERL_DRV_TUPLE, 2
};
- driver_send_term(adata->port, adata->receiver,
+ driver_send_term(adata->port, adata->term_data.receiver,
spec, sizeof(spec)/sizeof(spec[0]));
+}
+
+static void enqueue_reply(Otp9302AsyncData *adata)
+{
+ Otp9302MsgQ *msgq = adata->msgq;
+ adata->next = NULL;
+ adata->refc++;
+ erl_drv_mutex_lock(msgq->mtx);
+ if (msgq->end)
+ msgq->end->next = adata;
+ else
+ msgq->end = msgq->start = adata;
+ msgq->end = adata;
+ erl_drv_mutex_unlock(msgq->mtx);
+}
+
+static void dequeue_replies(Otp9302AsyncData *adata)
+{
+ Otp9302MsgQ *msgq = adata->msgq;
+ erl_drv_mutex_lock(msgq->mtx);
+ if (--adata->refc == 0)
+ driver_free(adata);
+ while (msgq->start) {
+ send_reply(msgq->start);
+ adata = msgq->start;
+ msgq->start = msgq->start->next;
+ if (--adata->refc == 0)
+ driver_free(adata);
+ }
+ msgq->start = msgq->end = NULL;
+ erl_drv_mutex_unlock(msgq->mtx);
+}
+
+static void async_invoke(void *data)
+{
+ Otp9302AsyncData *adata = (Otp9302AsyncData *) data;
if (adata->block) {
#ifdef __WIN32__
Sleep((DWORD) 2000);
@@ -96,14 +179,30 @@ static void async_invoke(void *data)
sleep(2);
#endif
}
+ if (adata->smp)
+ send_reply(adata);
+ else
+ enqueue_reply(adata);
+}
+
+static void ready_async(ErlDrvData drv_data,
+ ErlDrvThreadData thread_data)
+{
+ Otp9302AsyncData *adata = (Otp9302AsyncData *) thread_data;
+ if (adata->smp)
+ driver_free(adata);
+ else
+ dequeue_replies(adata);
}
static void output(ErlDrvData drv_data,
char *buf, int len)
{
- ErlDrvPort port = (ErlDrvPort) drv_data;
- ErlDrvTermData caller = driver_caller(port);
- unsigned int key = (unsigned int) port;
+ Otp9302Data *data = (Otp9302Data *) drv_data;
+ ErlDrvTermData td_port = driver_mk_port(data->port);
+ ErlDrvTermData td_receiver = driver_caller(data->port);
+ ErlDrvTermData td_job = driver_mk_atom("job");
+ unsigned int key = (unsigned int) data->port;
long id[5];
Otp9302AsyncData *ad[5];
int i;
@@ -113,25 +212,21 @@ static void output(ErlDrvData drv_data,
if (!ad[i])
abort();
- ad[i]->port = port;
- ad[i]->receiver = caller;
+ ad[i]->smp = data->smp;
+ ad[i]->port = data->port;
ad[i]->block = 0;
- ad[i]->eoj = 0;
- ad[i]->cancel = 0;
+ ad[i]->refc = 1;
+ ad[i]->term_data.port = td_port;
+ ad[i]->term_data.receiver = td_receiver;
+ ad[i]->term_data.msg = td_job;
+ ad[i]->msgq = &data->msgq;
}
ad[0]->block = 1;
- ad[2]->cancel = 1;
- ad[4]->eoj = 1;
+ ad[0]->term_data.msg = driver_mk_atom("block");
+ ad[2]->term_data.msg = driver_mk_atom("cancel");
+ ad[4]->term_data.msg = driver_mk_atom("end_of_jobs");
for (i = 0; i < sizeof(id)/sizeof(id[0]); i++)
- id[i] = driver_async(port, &key, async_invoke, ad[i], driver_free);
+ id[i] = driver_async(data->port, &key, async_invoke, ad[i], driver_free);
if (id[2] > 0)
driver_async_cancel(id[2]);
}
-
-static void ready_async(ErlDrvData drv_data,
- ErlDrvThreadData thread_data)
-{
- if ((void *) thread_data)
- driver_free((void *) thread_data);
-}
-
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 7795efe57e..559e540016 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -647,17 +647,11 @@ refc_dist_1() ->
%% Fun is passed in an exit signal. Wait until it is gone.
?line wait_until(fun () -> 4 =/= fun_refc(F2) end),
?line 3 = fun_refc(F2),
- erts_debug:set_internal_state(available_internal_state, true),
- ?line F_refc = case erts_debug:get_internal_state(force_heap_frags) of
- false -> 3;
- true -> 2 % GC after bif already decreased it
- end,
- ?line F_refc = fun_refc(F),
- erts_debug:set_internal_state(available_internal_state, false),
+ ?line true = erlang:garbage_collect(),
+ ?line 2 = fun_refc(F),
refc_dist_send(Node, F).
refc_dist_send(Node, F) ->
- ?line true = erlang:garbage_collect(),
?line Pid = spawn_link(Node,
fun() -> receive
{To,Fun} when is_function(Fun) ->
diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl
index 203fa6b48e..82a0aad189 100644
--- a/erts/emulator/test/hibernate_SUITE.erl
+++ b/erts/emulator/test/hibernate_SUITE.erl
@@ -25,16 +25,16 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
basic/1,dynamic_call/1,min_heap_size/1,bad_args/1,
- messages_in_queue/1,undefined_mfa/1, no_heap/1]).
+ messages_in_queue/1,undefined_mfa/1,no_heap/1,wake_up_and_bif_trap/1]).
%% Used by test cases.
--export([basic_hibernator/1,dynamic_call_hibernator/2,messages_in_queue_restart/2, no_heap_loop/0]).
+-export([basic_hibernator/1,dynamic_call_hibernator/2,messages_in_queue_restart/2, no_heap_loop/0,characters_to_list_trap/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[basic, dynamic_call, min_heap_size, bad_args, messages_in_queue,
- undefined_mfa, no_heap].
+ undefined_mfa, no_heap, wake_up_and_bif_trap].
groups() ->
[].
@@ -384,6 +384,31 @@ clean_dict() ->
lists:foreach(fun ({Key, _}) -> erase(Key) end, Dict).
%%
+%% Wake up and then immediatly bif trap with a lengthy computation.
+%%
+
+wake_up_and_bif_trap(doc) -> [];
+wake_up_and_bif_trap(suite) -> [];
+wake_up_and_bif_trap(Config) when is_list(Config) ->
+ ?line Self = self(),
+ ?line Pid = spawn_link(fun() -> erlang:hibernate(?MODULE, characters_to_list_trap, [Self]) end),
+ ?line Pid ! wakeup,
+ ?line receive
+ {ok, Pid0} when Pid0 =:= Pid -> ok
+ after 5000 ->
+ ?line ?t:fail(process_blocked)
+ end,
+ ?line unlink(Pid),
+ ?line exit(Pid, bye).
+
+%% Lengthy computation that traps (in characters_to_list_trap_3).
+characters_to_list_trap(Parent) ->
+ Bin0 = <<"abcdefghijklmnopqrstuvwxz0123456789">>,
+ Bin = binary:copy(Bin0, 1500),
+ unicode:characters_to_list(Bin),
+ Parent ! {ok, self()}.
+
+%%
%% Misc
%%
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 2b21fa58f4..461773114e 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -27,8 +27,9 @@
destructive_in_test_bif/1, guard_exceptions/1,
unary_plus/1, unary_minus/1, moving_labels/1]).
-export([fpe/1]).
+-export([otp_9422/1]).
--export([runner/2]).
+-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]).
@@ -57,7 +58,8 @@ all() ->
trace_control_word, silent, silent_no_ms, ms_trace2,
ms_trace3, boxed_and_small, destructive_in_test_bif,
guard_exceptions, unary_plus, unary_minus, fpe,
- moving_labels];
+ moving_labels,
+ otp_9422];
true -> [not_run]
end.
@@ -208,6 +210,43 @@ test_3(Config) when is_list(Config) ->
?line collect(P1, [{trace, P1, call, {?MODULE, f2, [a, b]}, [true]}]),
?line ok.
+otp_9422(doc) -> [];
+otp_9422(Config) when is_list(Config) ->
+ Laps = 1000,
+ ?line Fun1 = fun() -> otp_9422_tracee() end,
+ ?line P1 = spawn_link(?MODULE, loop_runner, [self(), Fun1, Laps]),
+ io:format("spawned ~p as tracee\n", [P1]),
+
+ ?line erlang:trace(P1, true, [call, silent]),
+
+ ?line Fun2 = fun() -> otp_9422_trace_changer() end,
+ ?line P2 = spawn_link(?MODULE, loop_runner, [self(), Fun2, Laps]),
+ io:format("spawned ~p as trace_changer\n", [P2]),
+
+ start_collect(P1),
+ start_collect(P2),
+
+ %%receive after 10*1000 -> ok end,
+
+ stop_collect(P1),
+ stop_collect(P2),
+ ok.
+
+otp_9422_tracee() ->
+ ?MODULE:f1(a),
+ ?MODULE:f1(b),
+ ?MODULE:f1(c).
+
+otp_9422_trace_changer() ->
+ Pat1 = [{[a], [], [{enable_trace, arity}]}],
+ ?line erlang:trace_pattern({?MODULE, f1, 1}, Pat1),
+ Pat2 = [{[b], [], [{disable_trace, arity}]}],
+ ?line erlang:trace_pattern({?MODULE, f1, 1}, Pat2).
+
+
+
+
+
bad_match_spec_bin(Config) when is_list(Config) ->
{'EXIT',{badarg,_}} = (catch ets:match_spec_run([1], <<>>)),
B0 = <<1,2>>,
@@ -932,6 +971,24 @@ runner(Collector, Fun) ->
Collector ! {gone, self()}
end.
+loop_runner(Collector, Fun, Laps) ->
+ receive
+ {go, Collector} ->
+ go
+ end,
+ loop_runner_cont(Collector, Fun, 0, Laps).
+
+loop_runner_cont(_Collector, _Fun, Laps, Laps) ->
+ receive
+ {done, Collector} ->
+ io:format("loop_runner ~p exit after ~p laps\n", [self(), Laps]),
+ Collector ! {gone, self()}
+ end;
+loop_runner_cont(Collector, Fun, N, Laps) ->
+ Fun(),
+ loop_runner_cont(Collector, Fun, N+1, Laps).
+
+
f1(X) ->
{X}.
diff --git a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
index 818023211c..0e4065c26b 100644
--- a/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
+++ b/erts/emulator/test/mtx_SUITE_data/mtx_SUITE.c
@@ -552,13 +552,19 @@ create_rwlock(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
static ERL_NIF_TERM
rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
- rwlock_resource_t *rwlr;
+ /*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+ union { void* vp; rwlock_resource_t *p; } rwlr;
int blocking, write, wait_locked, wait_unlocked;
if (argc != 5)
goto badarg;
- if (!enif_get_resource(env, argv[0], enif_priv_data(env), (void **) &rwlr))
+ if (!enif_get_resource(env, argv[0], enif_priv_data(env), &rwlr.vp))
goto badarg;
blocking = get_bool(env, argv[1]);
@@ -581,22 +587,22 @@ rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
if (write) {
if (blocking)
- RWMUTEX_WLOCK(rwlr->rwlock);
+ RWMUTEX_WLOCK(rwlr.p->rwlock);
else
- while (EBUSY == RWMUTEX_TRYWLOCK(rwlr->rwlock));
- if (rwlr->lock_check) {
- ASSERT(!ATOMIC_READ(&rwlr->is_locked));
- ATOMIC_SET(&rwlr->is_locked, -1);
+ while (EBUSY == RWMUTEX_TRYWLOCK(rwlr.p->rwlock));
+ if (rwlr.p->lock_check) {
+ ASSERT(!ATOMIC_READ(&rwlr.p->is_locked));
+ ATOMIC_SET(&rwlr.p->is_locked, -1);
}
}
else {
if (blocking)
- RWMUTEX_RLOCK(rwlr->rwlock);
+ RWMUTEX_RLOCK(rwlr.p->rwlock);
else
- while (EBUSY == RWMUTEX_TRYRLOCK(rwlr->rwlock));
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) >= 0);
- ATOMIC_INC(&rwlr->is_locked);
+ while (EBUSY == RWMUTEX_TRYRLOCK(rwlr.p->rwlock));
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) >= 0);
+ ATOMIC_INC(&rwlr.p->is_locked);
}
}
@@ -604,18 +610,18 @@ rwlock_op(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
milli_sleep(wait_locked);
if (write) {
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) == -1);
- ATOMIC_SET(&rwlr->is_locked, 0);
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) == -1);
+ ATOMIC_SET(&rwlr.p->is_locked, 0);
}
- RWMUTEX_WUNLOCK(rwlr->rwlock);
+ RWMUTEX_WUNLOCK(rwlr.p->rwlock);
}
else {
- if (rwlr->lock_check) {
- ASSERT(ATOMIC_READ(&rwlr->is_locked) > 0);
- ATOMIC_DEC(&rwlr->is_locked);
+ if (rwlr.p->lock_check) {
+ ASSERT(ATOMIC_READ(&rwlr.p->is_locked) > 0);
+ ATOMIC_DEC(&rwlr.p->is_locked);
}
- RWMUTEX_RUNLOCK(rwlr->rwlock);
+ RWMUTEX_RUNLOCK(rwlr.p->rwlock);
}
if (wait_unlocked)
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 91d695d979..2867e8e2e4 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -257,10 +257,48 @@ types(Config) when is_list(Config) ->
end,
[{},{ok},{{}},{[],{}},{1,2,3,4,5}]),
Stuff = [[],{},0,0.0,(1 bsl 100),(fun()-> ok end),make_ref(),self()],
- [eq_cmp(A,clone(B)) || A<-Stuff, B<-Stuff],
+ [eq_cmp(A,clone(B)) || A<-Stuff, B<-Stuff],
+
+ {IntSz, LongSz} = type_sizes(),
+ UintMax = (1 bsl (IntSz*8)) - 1,
+ IntMax = UintMax bsr 1,
+ IntMin = -(IntMax+1),
+ UlongMax = (1 bsl (LongSz*8)) - 1,
+ LongMax = UlongMax bsr 1,
+ LongMin = -(LongMax+1),
+ Uint64Max = (1 bsl 64) - 1,
+ Int64Max = Uint64Max bsr 1,
+ Int64Min = -(Int64Max+1),
+ Limits = [{IntMin,IntMax},{0,UintMax},{LongMin,LongMax},{0,UlongMax},{Int64Min,Int64Max},{0,Uint64Max}],
+ io:format("Limits = ~p\n", [Limits]),
+ lists:foreach(fun(I) ->
+ R1 = echo_int(I),
+ %%io:format("echo_int(~p) -> ~p\n", [I, R1]),
+ R2 = my_echo_int(I, Limits),
+ ?line R1 = R2,
+ ?line true = (R1 =:= R2),
+ ?line true = (R1 == R2)
+ end, int_list()),
+
?line verify_tmpmem(TmpMem),
ok.
+int_list() ->
+ Start = 1 bsl 200,
+ int_list([Start], -Start).
+int_list([N | _]=List, End) when N<End ->
+ List;
+int_list([N | _]=List, End) ->
+ int_list([N - (1 + (abs(N) div 3)) | List], End).
+
+my_echo_int(I, Limits) ->
+ lists:map(fun({Min,Max}) ->
+ if I < Min -> false;
+ I > Max -> false;
+ true -> I
+ end
+ end, Limits).
+
clone(X) ->
binary_to_term(term_to_binary(X)).
@@ -1170,9 +1208,10 @@ tmpmem() ->
MemInfo ->
MSBCS = lists:foldl(
fun ({instance, _, L}, Acc) ->
+ {value,{_,SBMBCS}} = lists:keysearch(sbmbcs, 1, L),
{value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
{value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
- [MBCS,SBCS | Acc]
+ [SBMBCS,MBCS,SBCS | Acc]
end,
[],
MemInfo),
@@ -1269,6 +1308,8 @@ send_blob_thread(_,_,_) -> ?nif_stub.
join_send_thread(_) -> ?nif_stub.
copy_blob(_) -> ?nif_stub.
send_term(_,_) -> ?nif_stub.
+echo_int(_) -> ?nif_stub.
+type_sizes() -> ?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 dc047394b5..92f1bab8dd 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2009-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2009-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -28,6 +28,7 @@
static int static_cntA; /* zero by default */
static int static_cntB = NIF_SUITE_LIB_VER * 100;
+static ERL_NIF_TERM atom_false;
static ERL_NIF_TERM atom_self;
static ERL_NIF_TERM atom_ok;
static ERL_NIF_TERM atom_join;
@@ -40,7 +41,18 @@ typedef struct
CallInfo* call_history;
NifModPrivData* nif_mod;
union { ErlNifResourceType* t; long l; } rt_arr[2];
-}PrivData;
+} PrivData;
+
+/*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+typedef union {
+ void* vp;
+ struct make_term_info* p;
+} mti_t;
void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
{
@@ -103,7 +115,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
msgenv_resource_type = enif_open_resource_type(env,NULL,"nif_SUITE.msgenv",
msgenv_dtor,
ERL_NIF_RT_CREATE, NULL);
-
+ atom_false = enif_make_atom(env,"false");
atom_self = enif_make_atom(env,"self");
atom_ok = enif_make_atom(env,"ok");
atom_join = enif_make_atom(env,"join");
@@ -481,6 +493,45 @@ error:
return enif_make_atom(env,"error");
}
+static ERL_NIF_TERM echo_int(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int sint;
+ unsigned uint;
+ long slong;
+ unsigned long ulong;
+ ErlNifSInt64 sint64;
+ ErlNifUInt64 uint64;
+ ERL_NIF_TERM sint_term = atom_false, uint_term = atom_false;
+ ERL_NIF_TERM slong_term = atom_false, ulong_term = atom_false;
+ ERL_NIF_TERM sint64_term = atom_false, uint64_term = atom_false;
+
+ if (enif_get_int(env, argv[0], &sint)) {
+ sint_term = enif_make_int(env, sint);
+ }
+ if (enif_get_uint(env, argv[0], &uint)) {
+ uint_term = enif_make_uint(env, uint);
+ }
+ if (enif_get_long(env, argv[0], &slong)) {
+ slong_term = enif_make_long(env, slong);
+ }
+ if (enif_get_ulong(env, argv[0], &ulong)) {
+ ulong_term = enif_make_ulong(env, ulong);
+ }
+ if (enif_get_int64(env, argv[0], &sint64)) {
+ sint64_term = enif_make_int64(env, sint64);
+ }
+ if (enif_get_uint64(env, argv[0], &uint64)) {
+ uint64_term = enif_make_uint64(env, uint64);
+ }
+ return enif_make_list6(env, sint_term, uint_term, slong_term, ulong_term, sint64_term, uint64_term);
+}
+
+static ERL_NIF_TERM type_sizes(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ return enif_make_tuple2(env, enif_make_int(env, sizeof(int)),
+ enif_make_int(env, sizeof(long)));
+}
+
static ERL_NIF_TERM tuple_2_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int arity = -1;
@@ -667,7 +718,7 @@ static ERL_NIF_TERM get_resource_type(ErlNifEnv* env, int argc, const ERL_NIF_TE
static ERL_NIF_TERM alloc_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { ErlNifResourceType* t; long l;} type;
+ union { ErlNifResourceType* t; long l; } type;
union { void* p; long l;} data;
if (!enif_get_long(env, argv[0], &type.l)
|| !enif_inspect_binary(env, argv[1], &data_bin)
@@ -691,7 +742,7 @@ static ERL_NIF_TERM make_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { ErlNifResourceType* t; long l;} type;
+ union { ErlNifResourceType* t; long l; } type;
void* data;
ERL_NIF_TERM ret;
if (!enif_get_long(env, argv[0], &type.l)
@@ -709,7 +760,7 @@ static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TE
static ERL_NIF_TERM make_new_resource_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary data_bin;
- union { struct binary_resource* p; void* vp; long l;} br;
+ union { struct binary_resource* p; void* vp; long l; } br;
void* buf;
ERL_NIF_TERM ret;
if (!enif_inspect_binary(env, argv[0], &data_bin)
@@ -1229,10 +1280,7 @@ static void msgenv_dtor(ErlNifEnv* env, void* obj)
static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union {
- void* vp;
- struct make_term_info* p;
- }mti;
+ mti_t mti;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
}
@@ -1245,7 +1293,7 @@ static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ERL_NIF_TERM term;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
|| (argc>2 && !enif_get_uint(env,argv[2], &mti.p->n))) {
@@ -1261,7 +1309,7 @@ static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ErlNifPid to;
ERL_NIF_TERM copy;
int res;
@@ -1276,7 +1324,7 @@ static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ErlNifPid to;
ERL_NIF_TERM copy;
int res;
@@ -1294,7 +1342,7 @@ static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
void* threaded_sender(void *arg)
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
mti.vp = arg;
enif_mutex_lock(mti.p->mtx);
@@ -1309,7 +1357,7 @@ void* threaded_sender(void *arg)
static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
ERL_NIF_TERM copy;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
|| !enif_get_local_pid(env,argv[1], &mti.p->to_pid)) {
@@ -1335,7 +1383,7 @@ static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TER
static ERL_NIF_TERM join_send_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
int err;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
@@ -1352,7 +1400,7 @@ static ERL_NIF_TERM join_send_thread(ErlNifEnv* env, int argc, const ERL_NIF_TER
static ERL_NIF_TERM copy_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- union { void* vp; struct make_term_info* p; }mti;
+ mti_t mti;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
return enif_make_badarg(env);
}
@@ -1417,7 +1465,9 @@ static ErlNifFunc nif_funcs[] =
{"send_blob_thread", 3, send_blob_thread},
{"join_send_thread", 1, join_send_thread},
{"copy_blob", 1, copy_blob},
- {"send_term", 2, send_term}
+ {"send_term", 2, send_term},
+ {"echo_int", 1, echo_int},
+ {"type_sizes", 0, type_sizes}
};
ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload)
diff --git a/erts/emulator/test/send_term_SUITE.erl b/erts/emulator/test/send_term_SUITE.erl
index 6615873392..ba0ba804ca 100644
--- a/erts/emulator/test/send_term_SUITE.erl
+++ b/erts/emulator/test/send_term_SUITE.erl
@@ -175,6 +175,10 @@ chk_temp_alloc() ->
%% Verify that we havn't got anything allocated by temp_alloc
lists:foreach(
fun ({instance, _, TI}) ->
+ ?line {value, {sbmbcs, SBMBCInfo}}
+ = lists:keysearch(sbmbcs, 1, TI),
+ ?line {value, {blocks, 0, _, _}}
+ = lists:keysearch(blocks, 1, SBMBCInfo),
?line {value, {mbcs, MBCInfo}}
= lists:keysearch(mbcs, 1, TI),
?line {value, {blocks, 0, _, _}}
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index e7c57142c0..354439b5e3 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -67,6 +67,10 @@ my $max_gen_operands = 8;
# Must be even. The beam_load.c file must be updated, too.
my $max_spec_operands = 6;
+# The maximum number of primitive genop_types.
+
+my $max_genop_types = 16;
+
my %gen_opnum;
my %num_specific;
my %gen_to_spec;
@@ -106,7 +110,7 @@ my @pred_table;
# Operand types for generic instructions.
my $compiler_types = "uiaxyfhz";
-my $loader_types = "nprvlq";
+my $loader_types = "nprvlqo";
my $genop_types = $compiler_types . $loader_types;
#
@@ -142,34 +146,61 @@ my %arg_size = ('r' => 0, # x(0) - x register zero
my %type_bit;
my @tag_type;
+sub define_type_bit {
+ my($tag,$val) = @_;
+ defined $type_bit{$tag} and
+ sanity("the tag '$tag' has already been defined with the value ",
+ $type_bit{$tag});
+ $type_bit{$tag} = $val;
+}
+
{
my($bit) = 1;
my(%bit);
foreach (split('', $genop_types)) {
push(@tag_type, $_);
- $type_bit{$_} = $bit;
+ define_type_bit($_, $bit);
$bit{$_} = $bit;
$bit *= 2;
}
# Composed types.
- $type_bit{'d'} = $type_bit{'x'} | $type_bit{'y'} | $type_bit{'r'};
- $type_bit{'c'} = $type_bit{'i'} | $type_bit{'a'} | $type_bit{'n'} | $type_bit{'q'};
- $type_bit{'s'} = $type_bit{'d'} | $type_bit{'i'} | $type_bit{'a'} | $type_bit{'n'};
- $type_bit{'j'} = $type_bit{'f'} | $type_bit{'p'};
+ define_type_bit('d', $type_bit{'x'} | $type_bit{'y'} | $type_bit{'r'});
+ define_type_bit('c', $type_bit{'i'} | $type_bit{'a'} |
+ $type_bit{'n'} | $type_bit{'q'});
+ define_type_bit('s', $type_bit{'d'} | $type_bit{'i'} |
+ $type_bit{'a'} | $type_bit{'n'});
+ define_type_bit('j', $type_bit{'f'} | $type_bit{'p'});
# Aliases (for matching purposes).
- $type_bit{'I'} = $type_bit{'u'};
- $type_bit{'t'} = $type_bit{'u'};
- $type_bit{'A'} = $type_bit{'u'};
- $type_bit{'L'} = $type_bit{'u'};
- $type_bit{'b'} = $type_bit{'u'};
- $type_bit{'N'} = $type_bit{'u'};
- $type_bit{'U'} = $type_bit{'u'};
- $type_bit{'e'} = $type_bit{'u'};
- $type_bit{'P'} = $type_bit{'u'};
- $type_bit{'Q'} = $type_bit{'u'};
+ define_type_bit('I', $type_bit{'u'});
+ define_type_bit('t', $type_bit{'u'});
+ define_type_bit('A', $type_bit{'u'});
+ define_type_bit('L', $type_bit{'u'});
+ define_type_bit('b', $type_bit{'u'});
+ define_type_bit('N', $type_bit{'u'});
+ define_type_bit('U', $type_bit{'u'});
+ define_type_bit('e', $type_bit{'u'});
+ define_type_bit('P', $type_bit{'u'});
+ define_type_bit('Q', $type_bit{'u'});
+}
+
+#
+# Sanity checks.
+#
+
+{
+ if (@tag_type > $max_genop_types) {
+ sanity("\$max_genop_types is $max_genop_types, ",
+ "but there are ", scalar(@tag_type),
+ " primitive tags defined\n");
+ }
+
+ foreach my $tag (@tag_type) {
+ sanity("tag '$tag': primitive tags must be named with lowercase letters")
+ unless $tag =~ /^[a-z]$/;
+ }
}
#
@@ -436,12 +467,12 @@ sub emulator_output {
#
my(@bits) = (0) x ($max_spec_operands/2);
- my($shift) = 16;
my($i);
for ($i = 0; $i < $max_spec_operands && defined $args[$i]; $i++) {
my $t = $args[$i];
if (defined $type_bit{$t}) {
- $bits[int($i/2)] |= $type_bit{$t} << (16*($i%2));
+ my $shift = $max_genop_types * ($i % 2);
+ $bits[int($i/2)] |= $type_bit{$t} << $shift;
}
}
@@ -753,6 +784,10 @@ sub error {
die $where, @message, "\n";
}
+sub sanity {
+ die "internal error: ", @_, "\n";
+}
+
sub comment {
my($lang, @comments) = @_;
my($prefix);
diff --git a/erts/epmd/src/epmd.c b/erts/epmd/src/epmd.c
index a1f202251c..08576d923f 100644
--- a/erts/epmd/src/epmd.c
+++ b/erts/epmd/src/epmd.c
@@ -2,7 +2,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index 2a0de4df9c..a2d7559f9d 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -240,6 +240,14 @@
#define put_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \
((unsigned char*)(s))[1] = (i) & 0xff;}
+#if defined(__GNUC__)
+# define EPMD_INLINE __inline__
+#elif defined(__WIN32__)
+# define EPMD_INLINE __inline
+#else
+# define EPMD_INLINE
+#endif
+
/* ************************************************************************ */
/* Stuctures used by server */
@@ -295,6 +303,7 @@ typedef struct {
unsigned delay_write;
int max_conn;
int active_conn;
+ int select_fd_top;
char *progname;
Connection *conn;
Nodes nodes;
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 4d9b454f97..5debae26b6 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -80,6 +80,13 @@ static int reply(EpmdVars*,int,char *,int);
static void dbg_print_buf(EpmdVars*,char *,int);
static void print_names(EpmdVars*);
+static EPMD_INLINE void select_fd_set(EpmdVars* g, int fd)
+{
+ FD_SET(fd, &g->orig_read_mask);
+ if (fd >= g->select_fd_top) {
+ g->select_fd_top = fd + 1;
+ }
+}
void run(EpmdVars *g)
{
@@ -171,6 +178,7 @@ void run(EpmdVars *g)
g->max_conn -= num_sockets;
FD_ZERO(&g->orig_read_mask);
+ g->select_fd_top = 0;
for (i = 0; i < num_sockets; i++)
{
@@ -232,14 +240,14 @@ void run(EpmdVars *g)
dbg_perror(g,"failed to listen on socket");
epmd_cleanup_exit(g,1);
}
- FD_SET(listensock[i],&g->orig_read_mask);
+ select_fd_set(g, listensock[i]);
}
dbg_tty_printf(g,2,"entering the main select() loop");
select_again:
while(1)
- {
+ {
fd_set read_mask = g->orig_read_mask;
struct timeval timeout;
int ret;
@@ -251,7 +259,8 @@ void run(EpmdVars *g)
timeout.tv_sec = (g->packet_timeout < IDLE_TIMEOUT) ? 1 : IDLE_TIMEOUT;
timeout.tv_usec = 0;
- if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0) {
+ if ((ret = select(g->select_fd_top,
+ &read_mask, (fd_set *)0,(fd_set *)0,&timeout)) < 0) {
dbg_perror(g,"error in select ");
switch (errno) {
case EAGAIN:
@@ -821,7 +830,7 @@ static int conn_open(EpmdVars *g,int fd)
s = &g->conn[i];
/* From now on we want to know if there are data to be read */
- FD_SET(fd, &g->orig_read_mask);
+ select_fd_set(g, fd);
s->fd = fd;
s->open = EPMD_TRUE;
@@ -886,6 +895,7 @@ int epmd_conn_close(EpmdVars *g,Connection *s)
dbg_tty_printf(g,2,"closing connection on file descriptor %d",s->fd);
FD_CLR(s->fd,&g->orig_read_mask);
+ /* we don't bother lowering g->select_fd_top */
close(s->fd); /* Sometimes already closed but close anyway */
s->open = EPMD_FALSE;
if (s->buf != NULL) { /* Should never be NULL but test anyway */
@@ -1115,7 +1125,7 @@ static Node *node_reg2(EpmdVars *g,
node->extralen = extralen;
memcpy(node->extra,extra,extralen);
strcpy(node->symname,name);
- FD_SET(fd,&g->orig_read_mask);
+ select_fd_set(g, fd);
if (highvsn == 0) {
dbg_tty_printf(g,1,"registering '%s:%d', port %d",
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 90d3be9448..2bd576d8e8 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -64,6 +64,7 @@
static const char plusM_au_allocs[]= {
'u', /* all alloc_util allocators */
'B', /* binary_alloc */
+ 'C', /* sbmbc_alloc */
'D', /* std_alloc */
'E', /* ets_alloc */
'H', /* eheap_alloc */
@@ -93,6 +94,8 @@ static char *plusM_au_alloc_switches[] = {
"rsbcst",
"sbct",
"smbcs",
+ "sbmbcs",
+ "sbmbct",
NULL
};
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index 18ccf974aa..77bfd5e2bc 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/etc/unix/to_erl.c b/erts/etc/unix/to_erl.c
index b7c3c956c6..11fa3ff4cc 100644
--- a/erts/etc/unix/to_erl.c
+++ b/erts/etc/unix/to_erl.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c
index 6e60512f6d..d680b67dd6 100644
--- a/erts/etc/win32/Install.c
+++ b/erts/etc/win32/Install.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2003-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -213,6 +213,9 @@ int main(int argc, char **argv)
fprintf(stderr,"Cannot continue installation, bailing out.\n");
exit(1);
}
+
+ /* OBS!!! If the format of the init file is changed, do not forget
+ to update release_handler:write_ini_file(...) */
ini_file = create_init_file();
ini_section = create_init_section("erlang");
add_init_section(ini_file,ini_section);
diff --git a/erts/etc/win32/erlsrv/erlsrv_service.c b/erts/etc/win32/erlsrv/erlsrv_service.c
index 8891379643..242e2905a9 100644
--- a/erts/etc/win32/erlsrv/erlsrv_service.c
+++ b/erts/etc/win32/erlsrv/erlsrv_service.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/example/matrix_nif.c b/erts/example/matrix_nif.c
index c5e01dade5..43f9526ae3 100644
--- a/erts/example/matrix_nif.c
+++ b/erts/example/matrix_nif.c
@@ -31,7 +31,19 @@ typedef struct
unsigned nrows;
unsigned ncols;
double* data;
-}Matrix;
+} Matrix;
+
+/*
+ * Use a union for pointer type conversion to avoid compiler warnings
+ * about strict-aliasing violations with gcc-4.1. gcc >= 4.2 does not
+ * emit the warning.
+ * TODO: Reconsider use of union once gcc-4.1 is obsolete?
+ */
+typedef union
+{
+ void* vp;
+ Matrix* p;
+} mx_t;
#define POS(MX, ROW, COL) ((MX)->data[(ROW)* (MX)->ncols + (COL)])
@@ -44,8 +56,9 @@ static ErlNifResourceType* resource_type = NULL;
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- ErlNifResourceType* rt = enif_open_resource_type(env, "matrix_nif_example",
- matrix_dtor,
+ ErlNifResourceType* rt = enif_open_resource_type(env, NULL,
+ "matrix_nif_example",
+ matrix_dtor,
ERL_NIF_RT_CREATE, NULL);
if (rt == NULL) {
return -1;
@@ -90,12 +103,12 @@ static ERL_NIF_TERM create(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
ret = enif_make_resource(env, mx);
- enif_release_resource(env, mx);
+ enif_release_resource(mx);
return ret;
badarg:
if (mx != NULL) {
- enif_release_resource(env,mx);
+ enif_release_resource(mx);
}
return enif_make_badarg(env);
}
@@ -104,14 +117,14 @@ badarg:
static ERL_NIF_TERM pos(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
/* pos(Matrix, Row, Column) -> float() */
- Matrix* mx;
+ mx_t mx;
unsigned i, j;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx) ||
- !enif_get_uint(env, argv[1], &i) || (--i >= mx->nrows) ||
- !enif_get_uint(env, argv[2], &j) || (--j >= mx->ncols)) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp) ||
+ !enif_get_uint(env, argv[1], &i) || (--i >= mx.p->nrows) ||
+ !enif_get_uint(env, argv[2], &j) || (--j >= mx.p->ncols)) {
return enif_make_badarg(env);
}
- return enif_make_double(env, POS(mx, i,j));
+ return enif_make_double(env, POS(mx.p, i,j));
}
static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -119,37 +132,38 @@ static ERL_NIF_TERM add(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* add(Matrix_A, Matrix_B) -> Matrix_Sum */
unsigned i, j;
ERL_NIF_TERM ret;
- Matrix* mxA = NULL;
- Matrix* mxB = NULL;
- Matrix* mxS = NULL;
+ mx_t mxA, mxB, mxS;
+ mxA.p = NULL;
+ mxB.p = NULL;
+ mxS.p = NULL;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mxA) ||
- !enif_get_resource(env, argv[1], resource_type, (void**)&mxB) ||
- mxA->nrows != mxB->nrows ||
- mxB->ncols != mxB->ncols) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mxA.vp) ||
+ !enif_get_resource(env, argv[1], resource_type, &mxB.vp) ||
+ mxA.p->nrows != mxB.p->nrows ||
+ mxB.p->ncols != mxB.p->ncols) {
return enif_make_badarg(env);
}
- mxS = alloc_matrix(env, mxA->nrows, mxA->ncols);
- for (i = 0; i < mxA->nrows; i++) {
- for (j = 0; j < mxA->ncols; j++) {
- POS(mxS, i, j) = POS(mxA, i, j) + POS(mxB, i, j);
+ mxS.p = alloc_matrix(env, mxA.p->nrows, mxA.p->ncols);
+ for (i = 0; i < mxA.p->nrows; i++) {
+ for (j = 0; j < mxA.p->ncols; j++) {
+ POS(mxS.p, i, j) = POS(mxA.p, i, j) + POS(mxB.p, i, j);
}
}
- ret = enif_make_resource(env, mxS);
- enif_release_resource(env, mxS);
+ ret = enif_make_resource(env, mxS.p);
+ enif_release_resource(mxS.p);
return ret;
}
static ERL_NIF_TERM size_of(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
/* size(Matrix) -> {Nrows, Ncols} */
- Matrix* mx;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ mx_t mx;
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) {
return enif_make_badarg(env);
}
- return enif_make_tuple2(env, enif_make_uint(env, mx->nrows),
- enif_make_uint(env, mx->ncols));
+ return enif_make_tuple2(env, enif_make_uint(env, mx.p->nrows),
+ enif_make_uint(env, mx.p->ncols));
}
static ERL_NIF_TERM to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -157,16 +171,17 @@ static ERL_NIF_TERM to_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/* to_term(Matrix) -> [[first row], [second row], ...,[last row]] */
unsigned i, j;
ERL_NIF_TERM res;
- Matrix* mx = NULL;
+ mx_t mx;
+ mx.p = NULL;
- if (!enif_get_resource(env, argv[0], resource_type, (void**)&mx)) {
+ if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) {
return enif_make_badarg(env);
}
res = enif_make_list(env, 0);
- for (i = mx->nrows; i-- > 0; ) {
+ for (i = mx.p->nrows; i-- > 0; ) {
ERL_NIF_TERM row = enif_make_list(env, 0);
- for (j = mx->ncols; j-- > 0; ) {
- row = enif_make_list_cell(env, enif_make_double(env, POS(mx,i,j)),
+ for (j = mx.p->ncols; j-- > 0; ) {
+ row = enif_make_list_cell(env, enif_make_double(env, POS(mx.p,i,j)),
row);
}
res = enif_make_list_cell(env, row, res);
@@ -183,17 +198,17 @@ static int get_number(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)
static Matrix* alloc_matrix(ErlNifEnv* env, unsigned nrows, unsigned ncols)
{
- Matrix* mx = enif_alloc_resource(env, resource_type, sizeof(Matrix));
+ Matrix* mx = enif_alloc_resource(resource_type, sizeof(Matrix));
mx->nrows = nrows;
mx->ncols = ncols;
- mx->data = enif_alloc(env, nrows*ncols*sizeof(double));
+ mx->data = enif_alloc(nrows*ncols*sizeof(double));
return mx;
}
static void matrix_dtor(ErlNifEnv* env, void* obj)
{
Matrix* mx = (Matrix*) obj;
- enif_free(env, mx->data);
+ enif_free(mx->data);
mx->data = NULL;
}
diff --git a/erts/example/next_perm.cc b/erts/example/next_perm.cc
index 1427cd3979..d7c8f1ad97 100644
--- a/erts/example/next_perm.cc
+++ b/erts/example/next_perm.cc
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/include/internal/erl_printf_format.h b/erts/include/internal/erl_printf_format.h
index 400cc7dafd..064c4a5c09 100644
--- a/erts/include/internal/erl_printf_format.h
+++ b/erts/include/internal/erl_printf_format.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/include/internal/libatomic_ops/ethr_atomic.h b/erts/include/internal/libatomic_ops/ethr_atomic.h
index 2fc82c99a8..93bc06036f 100644
--- a/erts/include/internal/libatomic_ops/ethr_atomic.h
+++ b/erts/include/internal/libatomic_ops/ethr_atomic.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010. All Rights Reserved.
+ * 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
diff --git a/erts/include/internal/sparc32/atomic.h b/erts/include/internal/sparc32/atomic.h
index 16182f8b01..c297522ab1 100644
--- a/erts/include/internal/sparc32/atomic.h
+++ b/erts/include/internal/sparc32/atomic.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2005-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/include/internal/tile/atomic.h b/erts/include/internal/tile/atomic.h
index 0c7b597a6b..5697afda25 100644
--- a/erts/include/internal/tile/atomic.h
+++ b/erts/include/internal/tile/atomic.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2008-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c
index ec729407bb..35b148990a 100644
--- a/erts/lib_src/common/erl_misc_utils.c
+++ b/erts/lib_src/common/erl_misc_utils.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2006-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2006-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -1511,7 +1511,7 @@ const char* parse_topology_spec_group(erts_cpu_info_t *cpuinfo, const char* xml,
}
}
- if (cacheLevel == 0) {
+ if (parentCacheLevel == 0) {
*core_p = 0;
*processor_p = (*processor_p)++;
} else {
diff --git a/erts/lib_src/common/erl_printf_format.c b/erts/lib_src/common/erl_printf_format.c
index fba3fd723c..473791dce4 100644
--- a/erts/lib_src/common/erl_printf_format.c
+++ b/erts/lib_src/common/erl_printf_format.c
@@ -388,7 +388,7 @@ static int fmt_double(fmtfn_t fn,void*arg,double val,
max_size++;
if (precision)
max_size += precision;
- else if (fmt && FMTF_alt)
+ else if (fmt & FMTF_alt)
max_size++;
break;
case FMTC_E:
@@ -402,7 +402,7 @@ static int fmt_double(fmtfn_t fn,void*arg,double val,
max_size += 4;
if (precision)
max_size += precision;
- else if (fmt && FMTF_alt)
+ else if (fmt & FMTF_alt)
max_size++;
aexp = exp >= 0 ? exp : -exp;
if (aexp < 100)
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index bff3f7f9de..20c82c52bb 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 5d2f187435..9202b5be4f 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 7e492057da..faa2cf573c 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 c443866671..62ebbb9ffe 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index bfb1e48365..00a1cf065a 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 30bbfb0943..9894050cba 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 6681466767..9ee70d59ec 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 593bb8dbed..d400269ed0 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index 024b20eadb..ccfa7978c8 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -102,8 +102,14 @@ debug(#prim_state{debug = Deb}, Term) ->
%%% Interface Functions.
%%% --------------------------------------------------------
--spec start(term(), atom() | string(), host() | [host()]) ->
- {'ok', pid()} | {'error', term()}.
+-spec start(Id, Loader, Hosts) ->
+ {'ok', Pid} | {'error', What} when
+ Id :: term(),
+ Loader :: atom() | string(),
+ Hosts :: Host | [Host],
+ Host :: host(),
+ Pid :: pid(),
+ What :: term().
start(Id, Pgm, Hosts) when is_atom(Hosts) ->
start(Id, Pgm, [Hosts]);
start(Id, Pgm0, Hosts) ->
@@ -123,18 +129,6 @@ start(Id, Pgm0, Hosts) ->
{error,Reason}
end.
-start_it("ose_inet"=Cmd, Id, Pid, Hosts) ->
- %% Setup reserved port for ose_inet driver (only OSE)
- case catch erlang:open_port({spawn,Cmd}, [binary]) of
- {'EXIT',Why} ->
- ?dbg(ose_inet_port_open_fail, Why),
- Why;
- OseInetPort ->
- ?dbg(ose_inet_port, OseInetPort),
- OseInetPort
- end,
- start_it("inet", Id, Pid, Hosts);
-
%% Hosts must be a list on form ['1.2.3.4' ...]
start_it("inet", Id, Pid, Hosts) ->
process_flag(trap_exit, true),
@@ -174,15 +168,20 @@ init_ack(Pid) ->
Pid ! {self(),ok},
ok.
--spec set_path([string()]) -> 'ok'.
+-spec set_path(Path) -> 'ok' when
+ Path :: [Dir :: string()].
set_path(Paths) when is_list(Paths) ->
request({set_path,Paths}).
--spec get_path() -> {'ok', [string()]}.
+-spec get_path() -> {'ok', Path} when
+ Path :: [Dir :: string()].
get_path() ->
request({get_path,[]}).
--spec get_file(atom() | string()) -> {'ok', binary(), string()} | 'error'.
+-spec get_file(Filename) -> {'ok', Bin, FullName} | 'error' when
+ Filename :: atom() | string(),
+ Bin :: binary(),
+ FullName :: string().
get_file(File) when is_atom(File) ->
get_file(atom_to_list(File));
get_file(File) ->
@@ -202,13 +201,15 @@ get_files(ModFiles, Fun) ->
ok
end.
--spec list_dir(string()) -> {'ok', [string()]} | 'error'.
+-spec list_dir(Dir) -> {'ok', Filenames} | 'error' when
+ Dir :: string(),
+ Filenames :: [Filename :: string()].
list_dir(Dir) ->
check_file_result(list_dir, Dir, request({list_dir,Dir})).
-%% -> {ok,Info} | error
--spec read_file_info(string()) -> {'ok', tuple()} | 'error'.
-
+-spec read_file_info(Filename) -> {'ok', FileInfo} | 'error' when
+ Filename :: string(),
+ FileInfo :: file:file_info().
read_file_info(File) ->
check_file_result(read_file_info, File, request({read_file_info,File})).
@@ -1360,9 +1361,7 @@ pathtype(Name) when is_list(Name) ->
absolute;
_ ->
relative
- end;
- {ose,_} ->
- unix_pathtype(Name)
+ end
end.
unix_pathtype(Name) ->
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 4679a916c7..5deb69edab 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -53,22 +53,31 @@
-compile({no_auto_import,[spawn_opt/4]}).
-compile({no_auto_import,[spawn_opt/5]}).
-%%--------------------------------------------------------------------------
+-export_type([timestamp/0]).
--type date() :: {pos_integer(), pos_integer(), pos_integer()}.
--type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
--type date_time() :: {date(), time()}.
+-type timestamp() :: {MegaSecs :: non_neg_integer(),
+ Secs :: non_neg_integer(),
+ MicroSecs :: non_neg_integer()}.
%%--------------------------------------------------------------------------
+-spec apply(Fun, Args) -> term() when
+ Fun :: function(),
+ Args :: [term()].
apply(Fun, Args) ->
erlang:apply(Fun, Args).
+-spec apply(Module, Function, Args) -> term() when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
apply(Mod, Name, Args) ->
erlang:apply(Mod, Name, Args).
%% Spawns with a fun
+-spec spawn(Fun) -> pid() when
+ Fun :: function().
spawn(F) when is_function(F) ->
spawn(erlang, apply, [F, []]);
spawn({M,F}=MF) when is_atom(M), is_atom(F) ->
@@ -76,6 +85,9 @@ spawn({M,F}=MF) when is_atom(M), is_atom(F) ->
spawn(F) ->
erlang:error(badarg, [F]).
+-spec spawn(Node, Fun) -> pid() when
+ Node :: node(),
+ Fun :: function().
spawn(N, F) when N =:= node() ->
spawn(F);
spawn(N, F) when is_function(F) ->
@@ -85,6 +97,8 @@ spawn(N, {M,F}=MF) when is_atom(M), is_atom(F) ->
spawn(N, F) ->
erlang:error(badarg, [N, F]).
+-spec spawn_link(Fun) -> pid() when
+ Fun :: function().
spawn_link(F) when is_function(F) ->
spawn_link(erlang, apply, [F, []]);
spawn_link({M,F}=MF) when is_atom(M), is_atom(F) ->
@@ -92,6 +106,9 @@ spawn_link({M,F}=MF) when is_atom(M), is_atom(F) ->
spawn_link(F) ->
erlang:error(badarg, [F]).
+-spec spawn_link(Node, Fun) -> pid() when
+ Node :: node(),
+ Fun :: function().
spawn_link(N, F) when N =:= node() ->
spawn_link(F);
spawn_link(N, F) when is_function(F) ->
@@ -103,16 +120,30 @@ spawn_link(N, F) ->
%% Spawn and atomically set up a monitor.
+-spec spawn_monitor(Fun) -> {pid(), reference()} when
+ Fun :: function().
spawn_monitor(F) when is_function(F, 0) ->
erlang:spawn_opt({erlang,apply,[F,[]],[monitor]});
spawn_monitor(F) ->
erlang:error(badarg, [F]).
+-spec spawn_monitor(Module, Function, Args) -> {pid(), reference()} when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn_monitor(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
erlang:spawn_opt({M,F,A,[monitor]});
spawn_monitor(M, F, A) ->
erlang:error(badarg, [M,F,A]).
+-spec spawn_opt(Fun, Options) -> pid() | {pid(), reference()} when
+ Fun :: function(),
+ Options :: [Option],
+ Option :: link | monitor | {priority, Level}
+ | {fullsweep_after, Number :: non_neg_integer()}
+ | {min_heap_size, Size :: non_neg_integer()}
+ | {min_bin_vheap_size, VSize :: non_neg_integer()},
+ Level :: low | normal | high.
spawn_opt(F, O) when is_function(F) ->
spawn_opt(erlang, apply, [F, []], O);
spawn_opt({M,F}=MF, O) when is_atom(M), is_atom(F) ->
@@ -122,6 +153,15 @@ spawn_opt({M,F,A}, O) -> % For (undocumented) backward compatibility
spawn_opt(F, O) ->
erlang:error(badarg, [F, O]).
+-spec spawn_opt(Node, Fun, Options) -> pid() | {pid(), reference()} when
+ Node :: node(),
+ Fun :: function(),
+ Options :: [Option],
+ Option :: link | monitor | {priority, Level}
+ | {fullsweep_after, Number :: non_neg_integer()}
+ | {min_heap_size, Size :: non_neg_integer()}
+ | {min_bin_vheap_size, VSize :: non_neg_integer()},
+ Level :: low | normal | high.
spawn_opt(N, F, O) when N =:= node() ->
spawn_opt(F, O);
spawn_opt(N, F, O) when is_function(F) ->
@@ -133,6 +173,11 @@ spawn_opt(N, F, O) ->
%% Spawns with MFA
+-spec spawn(Node, Module, Function, Args) -> pid() when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn(N,M,F,A) when N =:= node(), is_atom(M), is_atom(F), is_list(A) ->
spawn(M,F,A);
spawn(N,M,F,A) when is_atom(N), is_atom(M), is_atom(F) ->
@@ -158,6 +203,11 @@ spawn(N,M,F,A) when is_atom(N), is_atom(M), is_atom(F) ->
spawn(N,M,F,A) ->
erlang:error(badarg, [N, M, F, A]).
+-spec spawn_link(Node, Module, Function, Args) -> pid() when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()].
spawn_link(N,M,F,A) when N =:= node(), is_atom(M), is_atom(F), is_list(A) ->
spawn_link(M,F,A);
spawn_link(N,M,F,A) when is_atom(N), is_atom(M), is_atom(F) ->
@@ -183,6 +233,17 @@ spawn_link(N,M,F,A) when is_atom(N), is_atom(M), is_atom(F) ->
spawn_link(N,M,F,A) ->
erlang:error(badarg, [N, M, F, A]).
+-spec spawn_opt(Module, Function, Args, Options) ->
+ pid() | {pid(), reference()} when
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Options :: [Option],
+ Option :: link | monitor | {priority, Level}
+ | {fullsweep_after, Number :: non_neg_integer()}
+ | {min_heap_size, Size :: non_neg_integer()}
+ | {min_bin_vheap_size, VSize :: non_neg_integer()},
+ Level :: low | normal | high.
spawn_opt(M, F, A, Opts) ->
case catch erlang:spawn_opt({M,F,A,Opts}) of
{'EXIT',{Reason,_}} ->
@@ -191,6 +252,18 @@ spawn_opt(M, F, A, Opts) ->
Res
end.
+-spec spawn_opt(Node, Module, Function, Args, Options) ->
+ pid() | {pid(), reference()} when
+ Node :: node(),
+ Module :: module(),
+ Function :: atom(),
+ Args :: [term()],
+ Options :: [Option],
+ Option :: link | monitor | {priority, Level}
+ | {fullsweep_after, Number :: non_neg_integer()}
+ | {min_heap_size, Size :: non_neg_integer()}
+ | {min_bin_vheap_size, VSize :: non_neg_integer()},
+ Level :: low | normal | high.
spawn_opt(N, M, F, A, O) when N =:= node(),
is_atom(M), is_atom(F), is_list(A),
is_list(O) ->
@@ -260,18 +333,25 @@ crasher(Node,Mod,Fun,Args,Opts,Reason) ->
[Mod,Fun,Args,Opts,Node]),
exit(Reason).
--spec yield() -> 'true'.
+-spec erlang:yield() -> 'true'.
yield() ->
erlang:yield().
--spec nodes() -> [node()].
+-spec nodes() -> Nodes when
+ Nodes :: [node()].
nodes() ->
erlang:nodes(visible).
--spec disconnect_node(node()) -> boolean().
+-spec disconnect_node(Node) -> boolean() | ignored when
+ Node :: node().
disconnect_node(Node) ->
net_kernel:disconnect(Node).
+-spec erlang:fun_info(Fun) -> [{Item, Info}] when
+ Fun :: function(),
+ Item :: arity | env | index | name
+ | module | new_index | new_uniq | pid | type | uniq,
+ Info :: term().
fun_info(Fun) when is_function(Fun) ->
Keys = [type,env,arity,name,uniq,index,new_uniq,new_index,module,pid],
fun_info_1(Keys, Fun, []).
@@ -283,24 +363,37 @@ fun_info_1([K|Ks], Fun, A) ->
end;
fun_info_1([], _, A) -> A.
--type dst() :: pid() | port() | atom() | {atom(), node()}.
+-type dst() :: pid()
+ | port()
+ | (RegName :: atom())
+ | {RegName :: atom(), Node :: node()}.
--spec send_nosuspend(dst(), term()) -> boolean().
+-spec erlang:send_nosuspend(Dest, Msg) -> boolean() when
+ Dest :: dst(),
+ Msg :: term().
send_nosuspend(Pid, Msg) ->
send_nosuspend(Pid, Msg, []).
--spec send_nosuspend(dst(), term(), ['noconnect' | 'nosuspend']) -> boolean().
+-spec erlang:send_nosuspend(Dest, Msg, Options) -> boolean() when
+ Dest :: dst(),
+ Msg :: term(),
+ Options :: [noconnect].
send_nosuspend(Pid, Msg, Opts) ->
case erlang:send(Pid, Msg, [nosuspend|Opts]) of
ok -> true;
_ -> false
end.
--spec localtime_to_universaltime(date_time()) -> date_time().
+-spec erlang:localtime_to_universaltime({Date1, Time1}) -> {Date2, Time2} when
+ Date1 :: calendar:date(),
+ Date2 :: calendar:date(),
+ Time1 :: calendar:time(),
+ Time2 :: calendar:time().
localtime_to_universaltime(Localtime) ->
erlang:localtime_to_universaltime(Localtime, undefined).
--spec suspend_process(pid()) -> 'true'.
+-spec erlang:suspend_process(Suspendee) -> 'true' when
+ Suspendee :: pid().
suspend_process(P) ->
case catch erlang:suspend_process(P, []) of
{'EXIT', {Reason, _}} -> erlang:error(Reason, [P]);
@@ -426,6 +519,9 @@ delay_trap(Result, Timeout) -> receive after Timeout -> Result end.
%% Messages to us use our cookie. IF we change our cookie, other nodes
%% have to reflect that, which we cannot forsee.
%%
+-spec erlang:set_cookie(Node, Cookie) -> true when
+ Node :: node(),
+ Cookie :: atom().
set_cookie(Node, C) when Node =/= nonode@nohost, is_atom(Node) ->
case is_atom(C) of
true ->
@@ -434,14 +530,19 @@ set_cookie(Node, C) when Node =/= nonode@nohost, is_atom(Node) ->
error(badarg)
end.
--spec get_cookie() -> atom().
+-spec erlang:get_cookie() -> Cookie | nocookie when
+ Cookie :: atom().
get_cookie() ->
auth:get_cookie().
+-spec concat_binary(ListOfBinaries) -> binary() when
+ ListOfBinaries :: iolist().
concat_binary(List) ->
list_to_binary(List).
--spec integer_to_list(integer(), 1..255) -> string().
+-spec integer_to_list(Integer, Base) -> string() when
+ Integer :: integer(),
+ Base :: 2..36.
integer_to_list(I, 10) ->
erlang:integer_to_list(I);
integer_to_list(I, Base)
@@ -469,6 +570,9 @@ integer_to_list(I0, Base, R0) ->
end.
+-spec list_to_integer(String, Base) -> integer() when
+ String :: string(),
+ Base :: 2..36.
list_to_integer(L, 10) ->
erlang:list_to_integer(L);
list_to_integer(L, Base)
@@ -689,10 +793,16 @@ await_proc_exit(Proc, Op, Data) ->
end
end.
--spec min(term(), term()) -> term().
+-spec min(Term1, Term2) -> Minimum when
+ Term1 :: term(),
+ Term2 :: term(),
+ Minimum :: term().
min(A, B) when A > B -> B;
min(A, _) -> A.
--spec max(term(), term()) -> term().
+-spec max(Term1, Term2) -> Maximum when
+ Term1 :: term(),
+ Term2 :: term(),
+ Maximum :: term().
max(A, B) when A < B -> B;
max(A, _) -> A.
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index 24430a3d40..e52c813029 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,10 +28,10 @@
%% : $Var in the boot script is expanded to
%% Value.
%% -loader LoaderMethod
-%% : efile, inet, ose_inet
+%% : efile, inet
%% (Optional - default efile)
%% -hosts [Node] : List of hosts from which we can boot.
-%% (Mandatory if -loader inet or ose_inet)
+%% (Mandatory if -loader inet)
%% -mode embedded : Load all modules at startup, no automatic loading
%% -mode interactive : Auto load modules (default system behaviour).
%% -path : Override path in bootfile.
@@ -79,19 +79,24 @@
debug(false, _) -> ok;
debug(_, T) -> erlang:display(T).
--spec get_arguments() -> [{atom(), [string()]}].
+-spec get_arguments() -> Flags when
+ Flags :: [{Flag :: atom(), Values :: [string()]}].
get_arguments() ->
request(get_arguments).
--spec get_plain_arguments() -> [string()].
+-spec get_plain_arguments() -> [Arg] when
+ Arg :: string().
get_plain_arguments() ->
bs2ss(request(get_plain_arguments)).
--spec get_argument(atom()) -> 'error' | {'ok', [[string()]]}.
+-spec get_argument(Flag) -> {'ok', Arg} | 'error' when
+ Flag :: atom(),
+ Arg :: [Values :: [string()]].
get_argument(Arg) ->
request({get_argument, Arg}).
--spec script_id() -> term().
+-spec script_id() -> Id when
+ Id :: term().
script_id() ->
request(script_id).
@@ -105,7 +110,9 @@ bs2ss(L0) when is_list(L0) ->
bs2ss(L) ->
L.
--spec get_status() -> {internal_status(), term()}.
+-spec get_status() -> {InternalStatus, ProvidedStatus} when
+ InternalStatus :: internal_status(),
+ ProvidedStatus :: term().
get_status() ->
request(get_status).
@@ -150,10 +157,12 @@ reboot() -> init ! {stop,reboot}, ok.
-spec stop() -> 'ok'.
stop() -> init ! {stop,stop}, ok.
--spec stop(non_neg_integer() | string()) -> 'ok'.
+-spec stop(Status) -> 'ok' when
+ Status :: non_neg_integer() | string().
stop(Status) -> init ! {stop,{stop,Status}}, ok.
--spec boot([binary()]) -> no_return().
+-spec boot(BootArgs) -> no_return() when
+ BootArgs :: [binary()].
boot(BootArgs) ->
register(init, self()),
process_flag(trap_exit, true),
@@ -1024,7 +1033,7 @@ start_it({eval,Bin}) ->
TsR -> reverse([{dot,1} | TsR])
end,
{ok,Expr} = erl_parse:parse_exprs(Ts1),
- erl_eval:exprs(Expr, []),
+ erl_eval:exprs(Expr, erl_eval:new_bindings()),
ok;
start_it([_|_]=MFA) ->
Ref = make_ref(),
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 13e8e8fb5b..ac7570582e 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -63,7 +63,7 @@
-include("file.hrl").
--define(DRV, efile).
+-define(DRV, "efile").
-define(FD_DRV, "efile").
-define(LARGEFILESIZE, (1 bsl 63)).
@@ -549,7 +549,7 @@ write_file(_, _) ->
%% Returns {ok, Port}, the Port should be used as first argument in all
%% the following functions. Returns {error, Reason} upon failure.
start() ->
- try erlang:open_port({spawn, atom_to_list(?DRV)}, [binary]) of
+ try erlang:open_port({spawn, ?DRV}, [binary]) of
Port ->
{ok, Port}
catch
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index 51d6cd0a0b..6cc7b27114 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -124,7 +124,6 @@
-type zwindowbits() :: -15..-9 | 9..47.
-type zmemlevel() :: 1..9.
-type zstrategy() :: 'default' | 'filtered' | 'huffman_only'.
--type zflush() :: 'none' | 'sync' | 'full' | 'finish'.
%%------------------------------------------------------------------------
@@ -134,7 +133,8 @@ open() ->
open_port({spawn, "zlib_drv"}, [binary]).
%% close and release z_stream
--spec close(zstream()) -> 'ok'.
+-spec close(Z) -> 'ok' when
+ Z :: zstream().
close(Z) ->
try
true = port_close(Z),
@@ -145,16 +145,25 @@ close(Z) ->
catch _:_ -> erlang:error(badarg)
end.
--spec deflateInit(zstream()) -> 'ok'.
+-spec deflateInit(Z) -> 'ok' when
+ Z :: zstream().
deflateInit(Z) ->
call(Z, ?DEFLATE_INIT, <<?Z_DEFAULT_COMPRESSION:32>>).
--spec deflateInit(zstream(), zlevel()) -> 'ok'.
+-spec deflateInit(Z, Level) -> 'ok' when
+ Z :: zstream(),
+ Level :: zlevel().
deflateInit(Z, Level) ->
call(Z, ?DEFLATE_INIT, <<(arg_level(Level)):32>>).
--spec deflateInit(zstream(), zlevel(), zmethod(),
- zwindowbits(), zmemlevel(), zstrategy()) -> 'ok'.
+-spec deflateInit(Z, Level, Method,
+ WindowBits, MemLevel, Strategy) -> 'ok' when
+ Z :: zstream(),
+ Level :: zlevel(),
+ Method :: zmethod(),
+ WindowBits :: zwindowbits(),
+ MemLevel :: zmemlevel(),
+ Strategy :: zstrategy().
deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) ->
call(Z, ?DEFLATE_INIT2, <<(arg_level(Level)):32,
(arg_method(Method)):32,
@@ -162,24 +171,38 @@ deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) ->
(arg_mem(MemLevel)):32,
(arg_strategy(Strategy)):32>>).
--spec deflateSetDictionary(zstream(), binary()) -> integer().
+-spec deflateSetDictionary(Z, Dictionary) -> Adler32 when
+ Z :: zstream(),
+ Dictionary :: binary(),
+ Adler32 :: integer().
deflateSetDictionary(Z, Dictionary) ->
call(Z, ?DEFLATE_SETDICT, Dictionary).
--spec deflateReset(zstream()) -> 'ok'.
+-spec deflateReset(Z) -> 'ok' when
+ Z :: zstream().
deflateReset(Z) ->
call(Z, ?DEFLATE_RESET, []).
--spec deflateParams(zstream(), zlevel(), zstrategy()) -> 'ok'.
+-spec deflateParams(Z, Level, Strategy) -> ok when
+ Z :: zstream(),
+ Level :: zlevel(),
+ Strategy :: zstrategy().
deflateParams(Z, Level, Strategy) ->
call(Z, ?DEFLATE_PARAMS, <<(arg_level(Level)):32,
(arg_strategy(Strategy)):32>>).
--spec deflate(zstream(), iodata()) -> iolist().
+-spec deflate(Z, Data) -> Compressed when
+ Z :: zstream(),
+ Data :: iodata(),
+ Compressed :: iolist().
deflate(Z, Data) ->
deflate(Z, Data, none).
--spec deflate(zstream(), iodata(), zflush()) -> iolist().
+-spec deflate(Z, Data, Flush) -> Compressed when
+ Z :: zstream(),
+ Data :: iodata(),
+ Flush :: none | sync | full | finish,
+ Compressed :: iolist().
deflate(Z, Data, Flush) ->
try port_command(Z, Data) of
true ->
@@ -191,19 +214,25 @@ deflate(Z, Data, Flush) ->
erlang:error(badarg)
end.
--spec deflateEnd(zstream()) -> 'ok'.
+-spec deflateEnd(Z) -> 'ok' when
+ Z :: zstream().
deflateEnd(Z) ->
call(Z, ?DEFLATE_END, []).
--spec inflateInit(zstream()) -> 'ok'.
+-spec inflateInit(Z) -> 'ok' when
+ Z :: zstream().
inflateInit(Z) ->
call(Z, ?INFLATE_INIT, []).
--spec inflateInit(zstream(), zwindowbits()) -> 'ok'.
+-spec inflateInit(Z, WindowBits) -> 'ok' when
+ Z :: zstream(),
+ WindowBits :: zwindowbits().
inflateInit(Z, WindowBits) ->
call(Z, ?INFLATE_INIT2, <<(arg_bitsz(WindowBits)):32>>).
--spec inflateSetDictionary(zstream(), binary()) -> 'ok'.
+-spec inflateSetDictionary(Z, Dictionary) -> 'ok' when
+ Z :: zstream(),
+ Dictionary :: binary().
inflateSetDictionary(Z, Dictionary) ->
call(Z, ?INFLATE_SETDICT, Dictionary).
@@ -211,11 +240,15 @@ inflateSetDictionary(Z, Dictionary) ->
inflateSync(Z) ->
call(Z, ?INFLATE_SYNC, []).
--spec inflateReset(zstream()) -> 'ok'.
+-spec inflateReset(Z) -> 'ok' when
+ Z :: zstream().
inflateReset(Z) ->
call(Z, ?INFLATE_RESET, []).
--spec inflate(zstream(), iodata()) -> iolist().
+-spec inflate(Z, Data) -> Decompressed when
+ Z :: zstream(),
+ Data :: iodata(),
+ Decompressed :: iolist().
inflate(Z, Data) ->
try port_command(Z, Data) of
true ->
@@ -227,50 +260,81 @@ inflate(Z, Data) ->
erlang:error(badarg)
end.
--spec inflateEnd(zstream()) -> 'ok'.
+-spec inflateEnd(Z) -> 'ok' when
+ Z :: zstream().
inflateEnd(Z) ->
call(Z, ?INFLATE_END, []).
--spec setBufSize(zstream(), non_neg_integer()) -> 'ok'.
+-spec setBufSize(Z, Size) -> 'ok' when
+ Z :: zstream(),
+ Size :: non_neg_integer().
setBufSize(Z, Size) ->
call(Z, ?SET_BUFSZ, <<Size:32>>).
--spec getBufSize(zstream()) -> non_neg_integer().
+-spec getBufSize(Z) -> Size when
+ Z :: zstream(),
+ Size :: non_neg_integer().
getBufSize(Z) ->
call(Z, ?GET_BUFSZ, []).
--spec crc32(zstream()) -> integer().
+-spec crc32(Z) -> CRC when
+ Z :: zstream(),
+ CRC :: integer().
crc32(Z) ->
call(Z, ?CRC32_0, []).
--spec crc32(zstream(), binary()) -> integer().
+-spec crc32(Z, Binary) -> CRC when
+ Z :: zstream(),
+ Binary :: binary(),
+ CRC :: integer().
crc32(Z, Binary) ->
call(Z, ?CRC32_1, Binary).
--spec crc32(zstream(), integer(), binary()) -> integer().
+-spec crc32(Z, PrevCRC, Binary) -> CRC when
+ Z :: zstream(),
+ PrevCRC :: integer(),
+ Binary :: binary(),
+ CRC :: integer().
crc32(Z, CRC, Binary) when is_binary(Binary), is_integer(CRC) ->
call(Z, ?CRC32_2, <<CRC:32, Binary/binary>>);
crc32(_Z, _CRC, _Binary) ->
erlang:error(badarg).
--spec adler32(zstream(), binary()) -> integer().
+-spec adler32(Z, Binary) -> CheckSum when
+ Z :: zstream(),
+ Binary :: binary(),
+ CheckSum :: integer().
adler32(Z, Binary) ->
call(Z, ?ADLER32_1, Binary).
--spec adler32(zstream(), integer(), binary()) -> integer().
+-spec adler32(Z, PrevAdler, Binary) -> CheckSum when
+ Z :: zstream(),
+ PrevAdler :: integer(),
+ Binary :: binary(),
+ CheckSum :: integer().
adler32(Z, Adler, Binary) when is_binary(Binary), is_integer(Adler) ->
call(Z, ?ADLER32_2, <<Adler:32, Binary/binary>>);
adler32(_Z, _Adler, _Binary) ->
erlang:error(badarg).
--spec crc32_combine(zstream(), integer(), integer(), integer()) -> integer().
+-spec crc32_combine(Z, CRC1, CRC2, Size2) -> CRC when
+ Z :: zstream(),
+ CRC :: integer(),
+ CRC1 :: integer(),
+ CRC2 :: integer(),
+ Size2 :: integer().
crc32_combine(Z, CRC1, CRC2, Len2)
when is_integer(CRC1), is_integer(CRC2), is_integer(Len2) ->
call(Z, ?CRC32_COMBINE, <<CRC1:32, CRC2:32, Len2:32>>);
crc32_combine(_Z, _CRC1, _CRC2, _Len2) ->
erlang:error(badarg).
--spec adler32_combine(zstream(), integer(), integer(), integer()) -> integer().
+-spec adler32_combine(Z, Adler1, Adler2, Size2) -> Adler when
+ Z :: zstream(),
+ Adler :: integer(),
+ Adler1 :: integer(),
+ Adler2 :: integer(),
+ Size2 :: integer().
adler32_combine(Z, Adler1, Adler2, Len2)
when is_integer(Adler1), is_integer(Adler2), is_integer(Len2) ->
call(Z, ?ADLER32_COMBINE, <<Adler1:32, Adler2:32, Len2:32>>);
@@ -282,7 +346,9 @@ getQSize(Z) ->
call(Z, ?GET_QSIZE, []).
%% compress/uncompress zlib with header
--spec compress(binary()) -> binary().
+-spec compress(Binary) -> Compressed when
+ Binary :: binary(),
+ Compressed :: binary().
compress(Binary) ->
Z = open(),
deflateInit(Z, default),
@@ -291,7 +357,9 @@ compress(Binary) ->
close(Z),
list_to_binary(Bs).
--spec uncompress(binary()) -> binary().
+-spec uncompress(Binary) -> Decompressed when
+ Binary :: binary(),
+ Decompressed :: binary().
uncompress(Binary) when byte_size(Binary) >= 8 ->
Z = open(),
inflateInit(Z),
@@ -303,7 +371,9 @@ uncompress(Binary) when is_binary(Binary) -> erlang:error(data_error);
uncompress(_) -> erlang:error(badarg).
%% unzip/zip zlib without header (zip members)
--spec zip(binary()) -> binary().
+-spec zip(Binary) -> Compressed when
+ Binary :: binary(),
+ Compressed :: binary().
zip(Binary) ->
Z = open(),
deflateInit(Z, default, deflated, -?MAX_WBITS, 8, default),
@@ -312,7 +382,9 @@ zip(Binary) ->
close(Z),
list_to_binary(Bs).
--spec unzip(binary()) -> binary().
+-spec unzip(Binary) -> Decompressed when
+ Binary :: binary(),
+ Decompressed :: binary().
unzip(Binary) ->
Z = open(),
inflateInit(Z, -?MAX_WBITS),
@@ -321,7 +393,9 @@ unzip(Binary) ->
close(Z),
list_to_binary(Bs).
--spec gzip(iodata()) -> binary().
+-spec gzip(Data) -> Compressed when
+ Data :: iodata(),
+ Compressed :: binary().
gzip(Data) when is_binary(Data); is_list(Data) ->
Z = open(),
deflateInit(Z, default, deflated, 16+?MAX_WBITS, 8, default),
@@ -331,7 +405,9 @@ gzip(Data) when is_binary(Data); is_list(Data) ->
iolist_to_binary(Bs);
gzip(_) -> erlang:error(badarg).
--spec gunzip(iodata()) -> binary().
+-spec gunzip(Binary) -> Decompressed when
+ Binary :: binary(),
+ Decompressed :: binary().
gunzip(Data) when is_binary(Data); is_list(Data) ->
Z = open(),
inflateInit(Z, 16+?MAX_WBITS),
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 193a914a70..18799d2fba 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,8 +17,8 @@
# %CopyrightEnd%
#
-VSN = 5.8.4
-SYSTEM_VSN = R14B03
+VSN = 5.8.5
+SYSTEM_VSN = R14B04
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff --git a/lib/asn1/c_src/asn1_erl_driver.c b/lib/asn1/c_src/asn1_erl_driver.c
index 9dd3a0fd7d..18d4157941 100644
--- a/lib/asn1/c_src/asn1_erl_driver.c
+++ b/lib/asn1/c_src/asn1_erl_driver.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -101,6 +101,8 @@ int insert_bits_as_bits(int, int, unsigned char **, unsigned char **, int *);
int insert_octets_unaligned(int, unsigned char **, unsigned char **, int);
+int realloc_decode_buf(ErlDrvBinary **,int);
+
int realloc_memory(ErlDrvBinary **,int,unsigned char **,unsigned char **);
int decode_begin(ErlDrvBinary **,unsigned char *, int, unsigned int *);
@@ -123,6 +125,8 @@ int skip_length_and_value(unsigned char *,int *,int);
int get_tag(unsigned char *,int *,int);
+int get_length(unsigned char *,int *,int *,int);
+
int get_value(char *,unsigned char *,int *,int);
static ErlDrvEntry asn1_drv_entry = {
@@ -185,12 +189,12 @@ static void asn1_drv_stop(ErlDrvData handle)
int asn1_drv_control(ErlDrvData handle,
unsigned int command,
- char *buf,
+ char *buf,
int buf_len,
char **res_buf,
int res_buf_len)
{
- char *complete_buf;
+ unsigned char *complete_buf;
int complete_len, decode_len;
ErlDrvBinary *drv_binary;
ErlDrvBinary **drv_bin_ptr;
@@ -216,8 +220,8 @@ int asn1_drv_control(ErlDrvData handle,
set_port_control_flags(a_data->port, 0);
return ASN1_MEMORY_ERROR;
}
- complete_buf = drv_binary->orig_bytes;
- if ((complete_len = complete(&drv_binary,complete_buf,buf,buf_len)) == ASN1_ERROR)
+ complete_buf = (unsigned char*) drv_binary->orig_bytes;
+ if ((complete_len = complete(&drv_binary,complete_buf,(unsigned char*) buf,buf_len)) == ASN1_ERROR)
{
/* error handling due to failure in complete */
/* printf("error when running complete\n\r"); */
@@ -252,7 +256,7 @@ int asn1_drv_control(ErlDrvData handle,
return ASN1_MEMORY_ERROR;
}
drv_bin_ptr = &drv_binary;
- if ((decode_len = decode_begin(drv_bin_ptr,buf,buf_len,&err_pos)) <= ASN1_ERROR)
+ if ((decode_len = decode_begin(drv_bin_ptr,(unsigned char*)buf,buf_len,&err_pos)) <= ASN1_ERROR)
{
/* error handling due to failure in decode */
char tmp_res_buf[5];
@@ -301,7 +305,7 @@ int asn1_drv_control(ErlDrvData handle,
return ASN1_MEMORY_ERROR;
}
drv_bin_ptr = &drv_binary;
- if ((decode_len = decode_partial(drv_bin_ptr,buf,buf_len))
+ if ((decode_len = decode_partial(drv_bin_ptr,(unsigned char*)buf,buf_len))
<= ASN1_ERROR) {
/* error handling due to failure in decode */
driver_free_binary(*drv_bin_ptr);
@@ -723,7 +727,7 @@ int realloc_memory(ErlDrvBinary **drv_binary,
}else {
i = *ptr - *complete_buf;
*drv_binary=tmp_bin;
- *complete_buf = (*drv_binary)->orig_bytes;
+ *complete_buf = (unsigned char*)(*drv_binary)->orig_bytes;
*ptr = *complete_buf + i;
}
return ASN1_OK;
@@ -1164,7 +1168,7 @@ int decode(ErlDrvBinary **drv_binary,int *ei_index,unsigned char *in_buf,
if (ei_encode_tuple_header(decode_buf,ei_index,2) == ASN1_ERROR)
return ASN1_ERROR; /* 2 bytes */
#ifdef ASN1_DEBUG
- printf("decode 3:orig_size=%d, ei_index=%d, ib_index=%d\n\r",(*drv_binary)->orig_size,*ei_index,*ib_index);
+ printf("decode 3:orig_size=%ld, ei_index=%d, ib_index=%d\n\r",(*drv_binary)->orig_size,*ei_index,*ib_index);
#endif
/*buffer must hold at least two bytes*/
@@ -1275,7 +1279,8 @@ int decode_value(int *ei_index,unsigned char *in_buf,
{
int maybe_ret;
char *decode_buf = (*drv_binary)->orig_bytes;
- int len, lenoflen;
+ unsigned int len = 0;
+ unsigned int lenoflen = 0;
int indef = 0;
#ifdef ASN1_DEBUG
@@ -1283,8 +1288,6 @@ int decode_value(int *ei_index,unsigned char *in_buf,
#endif
if (((in_buf[*ib_index]) & 0x80) == ASN1_SHORT_DEFINITE_LENGTH) {
len = in_buf[*ib_index];
- if (len > (in_buf_len - (*ib_index + 1)))
- return ASN1_LEN_ERROR;
}
else if (in_buf[*ib_index] == ASN1_INDEFINITE_LENGTH)
indef = 1;
@@ -1293,17 +1296,21 @@ int decode_value(int *ei_index,unsigned char *in_buf,
#ifdef ASN1_DEBUG
printf("decode_value,lenoflen:%d\r\n",lenoflen);
#endif
- len = 0;
- while (lenoflen-- && (*ib_index <= in_buf_len)) {
- (*ib_index)++;
+ if (lenoflen > (in_buf_len - (*ib_index+1)))
+ return ASN1_LEN_ERROR;
+ len = 0;
+ while (lenoflen-- ) {
+ (*ib_index)++;
#ifdef ASN1_DEBUG
- printf("decode_value1:ii=%d.\r\n",*ib_index);
+ printf("decode_value1:*ib_index=%d, byte = %d.\r\n",*ib_index,in_buf[*ib_index]);
#endif
- len = (len << 8) + in_buf[*ib_index];
- }
- if (len > (in_buf_len - (*ib_index + 1)))
- return ASN1_LEN_ERROR;
+ if (!(len < (1 << (sizeof(len)-1)*8)))
+ return ASN1_LEN_ERROR; /* length does not fit in 32 bits */
+ len = (len << 8) + in_buf[*ib_index];
+ }
}
+ if (len > (in_buf_len - (*ib_index + 1)))
+ return ASN1_VALUE_ERROR;
(*ib_index)++;
#ifdef ASN1_DEBUG
printf("decode_value2:ii=%d.\r\n",*ib_index);
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index ccff9892c6..5e221c03e9 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -31,6 +31,30 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 1.6.17</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Test cases which started failing when timer:tc was
+ changed to not catch are corrected.</p>
+ <p>
+ Own Id: OTP-9286</p>
+ </item>
+ <item>
+ <p>
+ The bounds checking in the asn1_erl_driver when the
+ length value of a TLV is a Long Definite Length is
+ corrected. Thanks to Vance Shipley.</p>
+ <p>
+ Own Id: OTP-9303</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 1.6.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index d6f23aca06..c1b6aa5713 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -255,7 +255,7 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) ->
_ -> false
end
end,
- case lists:any(F,CompList) of
+ case lists:any(F,flat_complist(CompList)) of
true -> % when component relation constraint establish
%% relation from a component to another components
%% subtype component
@@ -1493,6 +1493,11 @@ emit_extaddgroupTerms(VarSeries,[_|Rest]) ->
emit_extaddgroupTerms(VarSeries,Rest);
emit_extaddgroupTerms(_,[]) ->
ok.
+
+flat_complist({Rl1,El,Rl2}) -> Rl1 ++ El ++ Rl2;
+flat_complist({Rl,El}) -> Rl ++ El;
+flat_complist(CompList) -> CompList.
+
wrap_compList({Root1,Ext,Root2}) ->
{Root1,wrap_extensionAdditionGroups(Ext),Root2};
wrap_compList({Root1,Ext}) ->
diff --git a/lib/asn1/src/asn1ct_value.erl b/lib/asn1/src/asn1ct_value.erl
index d9a7e5374a..693e039a13 100644
--- a/lib/asn1/src/asn1ct_value.erl
+++ b/lib/asn1/src/asn1ct_value.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -443,7 +443,7 @@ open_type_value(ber_bin_v2) ->
open_type_value(per) ->
"\n\topen_type"; %octet string value "open_type"
open_type_value(per_bin) ->
- "\n\topen_type";
+ <<"\n\topen_type">>;
% <<10,9,111,112,101,110,95,116,121,112,101>>;
open_type_value(_) ->
[4,9,111,112,101,110,95,116,121,112,101].
diff --git a/lib/asn1/src/asn1rt_check.erl b/lib/asn1/src/asn1rt_check.erl
index 59a74a7078..24a2a3802d 100644
--- a/lib/asn1/src/asn1rt_check.erl
+++ b/lib/asn1/src/asn1rt_check.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -311,7 +311,7 @@ transform_to_EXTERNAL1990([Data_val_desc,Data_value],Acc) when is_list(Data_valu
Data_val_desc|Acc]));
transform_to_EXTERNAL1990([Data_val_desc,Data_value],Acc)
when is_binary(Data_value)->
- list_to_tuple(lists:reverse([{'octet-aligned',binary_to_list(Data_value)},
+ list_to_tuple(lists:reverse([{'single-ASN1-type',Data_value},
Data_val_desc|Acc]));
transform_to_EXTERNAL1990([Data_value],Acc) when is_list(Data_value)->
list_to_tuple(lists:reverse([{'octet-aligned',Data_value}|Acc])).
diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl
deleted file mode 100644
index d050d8c84b..0000000000
--- a/lib/asn1/test/asn1_SUITE.erl
+++ /dev/null
@@ -1,2489 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%% Purpose : Test suite for the ASN.1 application
-
--module(asn1_SUITE).
--define(PER,'per').
--define(BER,'ber').
--define(ber_driver(Erule,Func),
- case Erule of
- ber_bin_v2 ->
- Func;
- _ -> ok
- end).
--define(per_optimize(Erule),
- case Erule of
- ber_bin_v2 ->[optimize];
- _ -> []
- end).
--define(per_bit_opt(FuncCall),
- case ?BER of
- ber_bin_v2 -> FuncCall;
-% _ -> {skip,"only for bit optimized per_bin"}
- _ -> ok
- end).
--define(uper_bin(FuncCall),
- case ?PER of
- per -> FuncCall;
- _ -> ok
- end).
-
--compile(export_all).
-%%-export([Function/Arity, ...]).
-
--include_lib("test_server/include/test_server.hrl").
-
-%% records used by test-case default
--record('Def1',{ bool0,
- bool1 = asn1_DEFAULT,
- bool2 = asn1_DEFAULT,
- bool3 = asn1_DEFAULT}).
-
-%-record('Def2',{
-%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
-
-%-record('Def3',{
-%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [{group, compile}, parse, default_per, default_ber,
- default_per_opt, per, {group, ber}, testPrim,
- testPrimStrings, testPrimExternal, testChoPrim,
- testChoExtension, testChoExternal, testChoOptional,
- testChoOptionalImplicitTag, testChoRecursive,
- testChoTypeRefCho, testChoTypeRefPrim,
- testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
- testSeqDefault, testSeqExtension, testSeqExternal,
- testSeqOptional, testSeqPrim, testSeqTag,
- testSeqTypeRefCho, testSeqTypeRefPrim,
- testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
- testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
- testSetDefault, testSetExtension,
- testExtensionAdditionGroup, testSetExternal,
- testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
- testSetTypeRefCho, testSetTypeRefPrim,
- testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
- testSetOfCho, testSetOfExternal, testSetOfTag,
- testEnumExt, value_test, testSeq2738, constructed,
- ber_decode_error, h323test, testSeqIndefinite,
- testSetIndefinite, testChoiceIndefinite,
- per_GeneralString, per_open_type, testInfObjectClass,
- testParameterizedInfObj, testMergeCompile, testobj,
- testDeepTConstr, testConstraints, testInvokeMod,
- testExport, testImport, testCompactBitString,
- testMegaco, testParamBasic, testMvrasn6,
- testContextSwitchingTypes, testTypeValueNotation,
- testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
- testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
- special_decode_performance, test_driver_load,
- test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier, testSelectionType,
- testSSLspecs, testNortel, test_undecoded_rest,
- test_inline, testTcapsystem, testNBAPsystem,
- test_compile_options, testDoubleEllipses,
- test_modified_x420, testX420, test_x691, ticket_6143,
- testExtensionAdditionGroup] ++ common() ++ particular().
-
-groups() ->
- [{option_tests, [],
- [test_compile_options, ticket_6143]},
- {infobj, [],
- [testInfObjectClass, testParameterizedInfObj,
- testMergeCompile, testobj, testDeepTConstr]},
- {performance, [],
- [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
- testTimer_per_opt, testTimer_uper_bin]},
- {bugs, [],
- [test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier]},
- {compile, [],
- [c_syntax, c_string_per, c_string_ber,
- c_implicit_before_choice]},
- {ber, [],
- [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
- ber_other]},
- {app_test, [], [{asn1_app_test, all}]},
- {appup_test, [], [{asn1_appup_test, all}]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
-
-
-init_per_testcase(Func,Config) ->
- %%?line test_server:format("Func: ~p~n",[Func]),
- ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
- ?line code:add_patha(?config(priv_dir,Config)),
- Dog=
- case Func of
- testX420 ->
- test_server:timetrap({minutes,60}); % 60 minutes
- _ ->
- test_server:timetrap({minutes,30}) % 60 minutes
- end,
-%% Dog=test_server:timetrap(1800000), % 30 minutes
- [{watchdog, Dog}|Config].
-
-end_per_testcase(_Func,Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog).
-
-
-testPrim(suite) -> [];
-testPrim(Config) ->
- ?line testPrim:compile(Config,?BER,[]),
- ?line testPrim_cases(?BER),
- ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrim_cases(?BER)),
- ?line testPrim:compile(Config,?PER,[]),
- ?line testPrim_cases(?PER),
- ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrim_cases(?PER)),
- ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrim_cases(uper_bin)),
- ?line testPrim:compile(Config,?PER,[optimize]),
- ?line testPrim_cases(?PER).
-
-testPrim_cases(Rules) ->
- ?line testPrim:bool(Rules),
- ?line testPrim:int(Rules),
- ?line testPrim:enum(Rules),
- ?line testPrim:obj_id(Rules),
- ?line testPrim:rel_oid(Rules),
- ?line testPrim:null(Rules),
- ?line testPrim:real(Rules).
-
-
-testCompactBitString(suite) -> [];
-testCompactBitString(Config) ->
-
- ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?BER),
-
- ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
- ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
-
- ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
- [compact_bit_string,optimize])),
- ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
- ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
- ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
-
- ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
- [compact_bit_string])),
- ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
- ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
-
- ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line testCompactBitString:otp_4869(?PER).
-
-
-testPrimStrings(suite) -> [];
-testPrimStrings(Config) ->
-
- ?line testPrimStrings:compile(Config,?BER,[]),
- ?line testPrimStrings_cases(?BER),
- ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
- ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
- ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
-
- ?line testPrimStrings:compile(Config,?PER,[]),
- ?line testPrimStrings_cases(?PER),
-
- ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
-
- ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
-
- ?line testPrimStrings:compile(Config,?PER,[optimize]),
- ?line testPrimStrings_cases(?PER).
-
-testPrimStrings_cases(Rules) ->
- ?line testPrimStrings:bit_string(Rules),
- ?line testPrimStrings:bit_string_unnamed(Rules),
- ?line testPrimStrings:octet_string(Rules),
- ?line testPrimStrings:numeric_string(Rules),
- ?line testPrimStrings:other_strings(Rules),
- ?line testPrimStrings:universal_string(Rules),
- ?line testPrimStrings:bmp_string(Rules),
- ?line testPrimStrings:times(Rules),
- ?line testPrimStrings:utf8_string(Rules).
-
-
-
-testPrimExternal(suite) -> [];
-testPrimExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testPrimExternal:compile(Config,?BER,[]),
- ?line testPrimExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testPrimExternal:compile(Config,?PER,[]),
- ?line testPrimExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal_cases(?PER).
-
-testPrimExternal_cases(Rules) ->
- ?line testPrimExternal:external(Rules).
-
-
-
-
-testChoPrim(suite) -> [];
-testChoPrim(Config) ->
-
- ?line testChoPrim:compile(Config,?BER,[]),
- ?line testChoPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
-
- ?line testChoPrim:compile(Config,?PER,[]),
- ?line testChoPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoPrim_cases(uper_bin)),
-
- ?line testChoPrim:compile(Config,?PER,[optimize]),
- ?line testChoPrim_cases(?PER).
-
-testChoPrim_cases(Rules) ->
- ?line testChoPrim:bool(Rules),
- ?line testChoPrim:int(Rules).
-
-
-
-testChoExtension(suite) -> [];
-testChoExtension(Config) ->
-
- ?line testChoExtension:compile(Config,?BER,[]),
- ?line testChoExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
-
- ?line testChoExtension:compile(Config,?PER,[]),
- ?line testChoExtension_cases(?PER),
-
- ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExtension_cases(?PER)),
-
- ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExtension_cases(uper_bin)),
-
- ?line testChoExtension:compile(Config,?PER,[optimize]),
- ?line testChoExtension_cases(?PER).
-
-testChoExtension_cases(Rules) ->
- ?line testChoExtension:extension(Rules).
-
-
-
-testChoExternal(suite) -> [];
-testChoExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testChoExternal:compile(Config,?BER,[]),
- ?line testChoExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testChoExternal:compile(Config,?PER,[]),
- ?line testChoExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal_cases(?PER).
-
-
-testChoExternal_cases(Rules) ->
- ?line testChoExternal:external(Rules).
-
-
-
-testChoOptional(suite) -> [];
-testChoOptional(Config) ->
-
- ?line testChoOptional:compile(Config,?BER,[]),
- ?line testChoOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
-
- ?line testChoOptional:compile(Config,?PER,[]),
- ?line testChoOptional_cases(?PER),
-
- ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoOptional_cases(?PER)),
-
- ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoOptional_cases(uper_bin)),
-
- ?line testChoOptional:compile(Config,?PER,[optimize]),
- ?line testChoOptional_cases(?PER).
-
-testChoOptional_cases(Rules) ->
- ?line testChoOptional:optional(Rules).
-
-testChoOptionalImplicitTag(suite) -> [];
-testChoOptionalImplicitTag(Config) ->
- %% Only meaningful for ?BER
- ?line testChoOptionalImplicitTag:compile(Config,?BER),
- ?line testChoOptionalImplicitTag:optional(?BER).
-
-
-testChoRecursive(suite) -> [];
-testChoRecursive(Config) ->
-
- ?line testChoRecursive:compile(Config,?BER,[]),
- ?line testChoRecursive_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
-
- ?line testChoRecursive:compile(Config,?PER,[]),
- ?line testChoRecursive_cases(?PER),
-
- ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
-
- ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
-
- ?line testChoRecursive:compile(Config,?PER,[optimize]),
- ?line testChoRecursive_cases(?PER).
-
-testChoRecursive_cases(Rules) ->
- ?line testChoRecursive:recursive(Rules).
-
-
-
-testChoTypeRefCho(suite) -> [];
-testChoTypeRefCho(Config) ->
-
- ?line testChoTypeRefCho:compile(Config,?BER,[]),
- ?line testChoTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[]),
- ?line testChoTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefCho_cases(?PER).
-
-testChoTypeRefCho_cases(Rules) ->
- ?line testChoTypeRefCho:choice(Rules).
-
-
-
-testChoTypeRefPrim(suite) -> [];
-testChoTypeRefPrim(Config) ->
-
- ?line testChoTypeRefPrim:compile(Config,?BER,[]),
- ?line testChoTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[]),
- ?line testChoTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefPrim_cases(?PER).
-
-testChoTypeRefPrim_cases(Rules) ->
- ?line testChoTypeRefPrim:prim(Rules).
-
-
-
-testChoTypeRefSeq(suite) -> [];
-testChoTypeRefSeq(Config) ->
-
- ?line testChoTypeRefSeq:compile(Config,?BER,[]),
- ?line testChoTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[]),
- ?line testChoTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSeq_cases(?PER).
-
-testChoTypeRefSeq_cases(Rules) ->
- ?line testChoTypeRefSeq:seq(Rules).
-
-
-
-testChoTypeRefSet(suite) -> [];
-testChoTypeRefSet(Config) ->
-
- ?line testChoTypeRefSet:compile(Config,?BER,[]),
- ?line testChoTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[]),
- ?line testChoTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSet_cases(?PER).
-
-testChoTypeRefSet_cases(Rules) ->
- ?line testChoTypeRefSet:set(Rules).
-
-
-
-testDef(suite) -> [];
-testDef(Config) ->
-
- ?line testDef:compile(Config,?BER,[]),
- ?line testDef_cases(?BER),
-
- ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDef_cases(?BER)),
-
- ?line testDef:compile(Config,?PER,[]),
- ?line testDef_cases(?PER),
-
- ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDef_cases(?PER)),
-
- ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDef_cases(uper_bin)),
-
- ?line testDef:compile(Config,?PER,[optimize]),
- ?line testDef_cases(?PER).
-
-testDef_cases(Rules) ->
- ?line testDef:main(Rules).
-
-
-
-testOpt(suite) -> [];
-testOpt(Config) ->
-
- ?line testOpt:compile(Config,?BER),
- ?line testOpt_cases(?BER),
-
- ?line testOpt:compile(Config,?PER),
- ?line testOpt_cases(?PER).
-
-testOpt_cases(Rules) ->
- ?line testOpt:main(Rules).
-
-
-testEnumExt(suite) -> [];
-testEnumExt(Config) ->
-
- ?line testEnumExt:compile(Config,?BER,[]),
- ?line testEnumExt:main(?BER),
-
- ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
-
- ?line testEnumExt:compile(Config,?PER,[]),
- ?line testEnumExt:main(?PER),
-
- ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testEnumExt:main(?PER)),
-
- ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testEnumExt:main(uper_bin)),
-
- ?line testEnumExt:compile(Config,?PER,[optimize]),
- ?line testEnumExt:main(?PER).
-
-testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
-testSeqDefault(suite) -> [];
-testSeqDefault(Config) ->
-
- ?line testSeqDefault:compile(Config,?BER,[]),
- ?line testSeqDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
-
- ?line testSeqDefault:compile(Config,?PER,[]),
- ?line testSeqDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
-
- ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
-
- ?line testSeqDefault:compile(Config,?PER,[optimize]),
- ?line testSeqDefault_cases(?PER).
-
-testSeqDefault_cases(Rules) ->
- ?line testSeqDefault:main(Rules).
-
-
-
-testSeqExtension(suite) -> [];
-testSeqExtension(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExtension:compile(Config,?BER,[]),
- ?line testSeqExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
-
-testSeqExtension_cases(Rules) ->
- ?line testSeqExtension:main(Rules).
-
-
-
-testSeqExternal(suite) -> [];
-testSeqExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExternal:compile(Config,?BER,[]),
- ?line testSeqExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
-
-testSeqExternal_cases(Rules) ->
- ?line testSeqExternal:main(Rules).
-
-
-testSeqOptional(suite) -> [];
-testSeqOptional(Config) ->
-
- ?line testSeqOptional:compile(Config,?BER,[]),
- ?line testSeqOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
-
- ?line testSeqOptional:compile(Config,?PER,[]),
- ?line testSeqOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
-
- ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
-
- ?line testSeqOptional:compile(Config,?PER,[optimize]),
- ?line testSeqOptional_cases(?PER).
-
-testSeqOptional_cases(Rules) ->
- ?line testSeqOptional:main(Rules).
-
-
-
-testSeqPrim(suite) -> [];
-testSeqPrim(Config) ->
-
- ?line testSeqPrim:compile(Config,?BER,[]),
- ?line testSeqPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
-
- ?line testSeqPrim:compile(Config,?PER,[]),
- ?line testSeqPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
-
- ?line testSeqPrim:compile(Config,?PER,[optimize]),
- ?line testSeqPrim_cases(?PER).
-
-testSeqPrim_cases(Rules) ->
- ?line testSeqPrim:main(Rules).
-
-
-testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
-testSeq2738(suite) -> [];
-testSeq2738(Config) ->
-
- ?line testSeq2738:compile(Config,?BER,[]),
- ?line testSeq2738_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
-
- ?line testSeq2738:compile(Config,?PER,[]),
- ?line testSeq2738_cases(?PER),
-
- ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeq2738_cases(?PER)),
-
- ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeq2738_cases(uper_bin)),
-
- ?line testSeq2738:compile(Config,?PER,[optimize]),
- ?line testSeq2738_cases(?PER).
-
-testSeq2738_cases(Rules) ->
- ?line testSeq2738:main(Rules).
-
-
-testSeqTag(suite) -> [];
-testSeqTag(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqTag:compile(Config,?BER,[]),
- ?line testSeqTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqTag:compile(Config,?PER,[]),
- ?line testSeqTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqTag:compile(Config,?PER,[optimize]),
- ?line testSeqTag_cases(?PER).
-
-testSeqTag_cases(Rules) ->
- ?line testSeqTag:main(Rules).
-
-
-
-
-testSeqTypeRefCho(suite) -> [];
-testSeqTypeRefCho(Config) ->
-
- ?line testSeqTypeRefCho:compile(Config,?BER,[]),
- ?line testSeqTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[]),
- ?line testSeqTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefCho_cases(?PER).
-
-testSeqTypeRefCho_cases(Rules) ->
- ?line testSeqTypeRefCho:main(Rules).
-
-
-
-testSeqTypeRefPrim(suite) -> [];
-testSeqTypeRefPrim(Config) ->
-
- ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
- ?line testSeqTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
- ?line testSeqTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefPrim_cases(?PER).
-
-testSeqTypeRefPrim_cases(Rules) ->
- ?line testSeqTypeRefPrim:main(Rules).
-
-
-
-testSeqTypeRefSeq(suite) -> [];
-testSeqTypeRefSeq(Config) ->
-
- ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
- ?line testSeqTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
- ?line testSeqTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSeq_cases(?PER).
-
-testSeqTypeRefSeq_cases(Rules) ->
- ?line testSeqTypeRefSeq:main(Rules).
-
-
-
-testSeqTypeRefSet(suite) -> [];
-testSeqTypeRefSet(Config) ->
-
- ?line testSeqTypeRefSet:compile(Config,?BER,[]),
- ?line testSeqTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[]),
- ?line testSeqTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSet_cases(?PER).
-
-testSeqTypeRefSet_cases(Rules) ->
- ?line testSeqTypeRefSet:main(Rules).
-
-
-
-
-testSeqOf(suite) -> [];
-testSeqOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOf:compile(Config,?BER,[]),
- ?line testSeqOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
-
- ?line testSeqOf:compile(Config,?PER,[]),
- ?line testSeqOf_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOf_cases(?PER)),
-
- ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOf_cases(uper_bin)),
-
- ?line testSeqOf:compile(Config,?PER,[optimize]),
- ?line testSeqOf_cases(?PER).
-
-testSeqOf_cases(Rules) ->
- ?line testSeqOf:main(Rules).
-
-
-
-
-testSeqOfCho(suite) -> [];
-testSeqOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfCho:compile(Config,?BER,[]),
- ?line testSeqOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
-
- ?line testSeqOfCho:compile(Config,?PER,[]),
- ?line testSeqOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
-
- ?line testSeqOfCho:compile(Config,?PER,[optimize]),
- ?line testSeqOfCho_cases(?PER).
-
-testSeqOfIndefinite(suite) -> [];
-testSeqOfIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfIndefinite:compile(Config,?BER,[]),
- ?line testSeqOfIndefinite:main(),
-
- ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
-
-testSeqOfCho_cases(Rules) ->
- ?line testSeqOfCho:main(Rules).
-
-
-testSeqOfExternal(suite) -> [];
-testSeqOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal_cases(?PER).
-
-testSeqOfExternal_cases(Rules) ->
- ?line testSeqOfExternal:main(Rules).
-
-
-
-testSeqOfTag(suite) -> [];
-testSeqOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfTag:compile(Config,?BER,[]),
- ?line testSeqOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfTag:compile(Config,?PER,[]),
- ?line testSeqOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag_cases(?PER).
-
-testSeqOfTag_cases(Rules) ->
- ?line testSeqOfTag:main(Rules).
-
-
-
-
-testSetDefault(suite) -> [];
-testSetDefault(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetDefault:compile(Config,?BER,[]),
- ?line testSetDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
-
- ?line testSetDefault:compile(Config,?PER,[]),
- ?line testSetDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetDefault_cases(?PER)),
-
- ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetDefault_cases(uper_bin)),
-
- ?line testSetDefault:compile(Config,?PER,[optimize]),
- ?line testSetDefault_cases(?PER).
-
-testSetDefault_cases(Rules) ->
- ?line testSetDefault:main(Rules).
-
-
-testParamBasic(suite) -> [];
-testParamBasic(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParamBasic:compile(Config,?BER,[]),
- ?line testParamBasic_cases(?BER),
-
- ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
-
- ?line testParamBasic:compile(Config,?PER,[]),
- ?line testParamBasic_cases(?PER),
-
- ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParamBasic_cases(?PER)),
-
- ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParamBasic_cases(uper_bin)),
-
- ?line testParamBasic:compile(Config,?PER,[optimize]),
- ?line testParamBasic_cases(?PER).
-
-
-testParamBasic_cases(Rules) ->
- ?line testParamBasic:main(Rules).
-
-testSetExtension(suite) -> [];
-testSetExtension(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExtension:compile(Config,?BER,[]),
- ?line testSetExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
-
-testSetExtension_cases(Rules) ->
- ?line testSetExtension:main(Rules).
-
-
-testSetExternal(suite) -> [];
-testSetExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExternal:compile(Config,?BER,[]),
- ?line testSetExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
-
-testSetExternal_cases(Rules) ->
- ?line testSetExternal:main(Rules).
-
-
-testSetOptional(suite) -> [];
-testSetOptional(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOptional:compile(Config,?BER,[]),
- ?line testSetOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
-
- ?line testSetOptional:compile(Config,?PER,[]),
- ?line testSetOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOptional_cases(?PER)),
-
- ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOptional_cases(uper_bin)),
-
- ?line testSetOptional:compile(Config,?PER,[optimize]),
- ?line testSetOptional_cases(?PER).
-
-testSetOptional_cases(Rules) ->
- ?line ok = testSetOptional:ticket_7533(Rules),
- ?line ok = testSetOptional:main(Rules).
-
-
-
-
-testSetPrim(suite) -> [];
-testSetPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetPrim:compile(Config,?BER,[]),
- ?line testSetPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
-
- ?line testSetPrim:compile(Config,?PER,[]),
- ?line testSetPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetPrim_cases(uper_bin)),
-
- ?line testSetPrim:compile(Config,?PER,[optimize]),
- ?line testSetPrim_cases(?PER).
-
-testSetPrim_cases(Rules) ->
- ?line testSetPrim:main(Rules).
-
-
-
-testSetTag(suite) -> [];
-testSetTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetTag:compile(Config,?BER,[]),
- ?line testSetTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetTag:compile(Config,?PER,[]),
- ?line testSetTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetTag:compile(Config,?PER,[optimize]),
- ?line testSetTag_cases(?PER).
-
-testSetTag_cases(Rules) ->
- ?line testSetTag:main(Rules).
-
-
-
-testSetTypeRefCho(suite) -> [];
-testSetTypeRefCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefCho:compile(Config,?BER,[]),
- ?line testSetTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[]),
- ?line testSetTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefCho_cases(?PER).
-
-testSetTypeRefCho_cases(Rules) ->
- ?line testSetTypeRefCho:main(Rules).
-
-
-
-testSetTypeRefPrim(suite) -> [];
-testSetTypeRefPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefPrim:compile(Config,?BER,[]),
- ?line testSetTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[]),
- ?line testSetTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefPrim_cases(?PER).
-
-testSetTypeRefPrim_cases(Rules) ->
- ?line testSetTypeRefPrim:main(Rules).
-
-
-
-testSetTypeRefSeq(suite) -> [];
-testSetTypeRefSeq(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSeq:compile(Config,?BER,[]),
- ?line testSetTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[]),
- ?line testSetTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSeq_cases(?PER).
-
-testSetTypeRefSeq_cases(Rules) ->
- ?line testSetTypeRefSeq:main(Rules).
-
-
-
-testSetTypeRefSet(suite) -> [];
-testSetTypeRefSet(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSet:compile(Config,?BER,[]),
- ?line testSetTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[]),
- ?line testSetTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSet_cases(?PER).
-
-testSetTypeRefSet_cases(Rules) ->
- ?line testSetTypeRefSet:main(Rules).
-
-
-
-testSetOf(suite) -> [];
-testSetOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOf:compile(Config,?BER,[]),
- ?line testSetOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
-
- ?line testSetOf:compile(Config,?PER,[]),
- ?line testSetOf_cases(?PER),
-
- ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOf_cases(?PER)),
-
- ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOf_cases(uper_bin)),
-
- ?line testSetOf:compile(Config,?PER,[optimize]),
- ?line testSetOf_cases(?PER).
-
-testSetOf_cases(Rules) ->
- ?line testSetOf:main(Rules).
-
-
-
-testSetOfCho(suite) -> [];
-testSetOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOfCho:compile(Config,?BER,[]),
- ?line testSetOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
-
- ?line testSetOfCho:compile(Config,?PER,[]),
- ?line testSetOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
-
- ?line testSetOfCho:compile(Config,?PER,[optimize]),
- ?line testSetOfCho_cases(?PER).
-
-testSetOfCho_cases(Rules) ->
- ?line testSetOfCho:main(Rules).
-
-
-testSetOfExternal(suite) -> [];
-testSetOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal_cases(?PER).
-
-testSetOfExternal_cases(Rules) ->
- ?line testSetOfExternal:main(Rules).
-
-
-
-
-testSetOfTag(suite) -> [];
-testSetOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfTag:compile(Config,?BER,[]),
- ?line testSetOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfTag:compile(Config,?PER,[]),
- ?line testSetOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfTag:compile(Config,?PER,[optimize]),
- ?line testSetOfTag_cases(?PER).
-
-testSetOfTag_cases(Rules) ->
- ?line testSetOfTag:main(Rules).
-
-
-c_syntax(suite) -> [];
-c_syntax(Config) ->
- ?line DataDir% ?line testExternal:compile(Config,?PER),
-% ?line testPrimExternal:compile(Config,?PER),
-% ?line testPrimExternal_cases(?PER).
- = ?config(data_dir,Config),
- ?line _TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
- ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment1")),
- ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment2")),
- ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
- "BadValueSet")),
- ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
- "ChoiceBadExtension")),
- ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
- "EnumerationBadExtension")),
- ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
- "Example")),
- ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
- "Export1")),
- ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
- "MissingEnd")),
- ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComma")),
- ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentName")),
- ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentType")),
- ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
- "SeqBadComma")).
-
-
-c_string_per(suite) -> [];
-c_string_per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
-
-c_string_ber(suite) -> [];
-c_string_ber(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
-
-
-c_implicit_before_choice(suite) -> [];
-c_implicit_before_choice(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
-
-parse(suite) -> [];
-parse(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- M1 = test_modules(),
-% M2 = parse_modules(),
- ?line ok = parse1(M1,DataDir,OutDir).
-
-parse1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
- parse1(T,DataDir,OutDir);
-parse1([],_,_) ->
- ok.
-
-per(suite) -> [];
-per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = per1(per_modules(),DataDir,OutDir),
- ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
- ?line ok = per1_opt(per_modules(),DataDir,OutDir).
-
-
-per1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1(T,DataDir,OutDir);
-per1([],_,_) ->
- ok.
-
-per1_bit_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_bit_opt(T,DataDir,OutDir);
-per1_bit_opt([],_,_) ->
- ok.
-
-per1_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_opt(T,DataDir,OutDir);
-per1_opt([],_,_) ->
- ok.
-
-
-ber_choiceinseq(suite) ->[];
-ber_choiceinseq(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
-
-ber_optional(suite) ->[];
-ber_optional(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
- ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(V,element(2,V2)).
-
-ber_optional_keyed_list(suite) ->[];
-ber_optional_keyed_list(Config) ->
- case ?BER of
- ber_bin_v2 -> ok;
- _ ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
- [?BER,keyed_list,{outdir,OutDir}]),
- ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line V = [ {a,[{scriptKey,10}]},
- {b,[]},
- {c,[{callingPartysCategory,111}]} ],
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(Vrecord,element(2,V2))
- end.
-
-
-eq(V,V) ->
- ok.
-
-
-ber_other(suite) ->[];
-ber_other(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = ber1(ber_modules(),DataDir,OutDir).
-
-
-ber1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- ber1(T,DataDir,OutDir);
-ber1([],_,_) ->
- ok.
-
-default_per(suite) ->[];
-default_per(Config) ->
- default1(?PER,Config,[]).
-
-default_per_opt(suite) -> [];
-default_per_opt(Config) ->
- ?per_bit_opt(default1(?PER,Config,[optimize])),
- default1(?PER,Config,[optimize]).
-
-default_ber(suite) ->[];
-default_ber(Config) ->
- default1(?BER,Config,[]).
-
-default1(Rule,Config,Options) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
- ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
- bool1 = true,
- bool2 = true,
- bool3 = true}),
- ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
-
- ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
-
-
-value_test(suite) ->[];
-value_test(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = test_bad_values:tests(Config),
- ok.
-
-
-constructed(suite) ->
- [];
-constructed(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
- ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
- ?line [40,3,1,1,0] = lists:flatten(B),
- ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
- ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
- ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
- ?line [136,1,10] = lists:flatten(B2),
- ok.
-
-ber_decode_error(suite) -> [];
-ber_decode_error(Config) ->
- ?line ok = ber_decode_error:compile(Config,?BER,[]),
- ?line ok = ber_decode_error:run([]),
-
- ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
- ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
- ok.
-
-h323test(suite) ->
- [];
-h323test(Config) ->
- ?line ok = h323test:compile(Config,?PER,[]),
- ?line ok = h323test:run(?PER),
- ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(h323test:run(?PER)),
- ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
- ?line ?uper_bin(h323test:run(uper_bin)),
- ?line ok = h323test:compile(Config,?PER,[optimize]),
- ?line ok = h323test:run(?PER),
- ok.
-
-per_GeneralString(suite) ->
- [];
-per_GeneralString(Config) ->
- case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
- true ->
- ok;
- false ->
- h323test:compile(Config,?PER,[])
- end,
- UI = [109,64,1,57],
- ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
- 'MultimediaSystemControlMessage',UI).
-
-per_open_type(suite) ->
- [];
-per_open_type(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
- Stype = {'Stype',10,true},
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
-
- ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}])),
- ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
- [uper_bin,{outdir,OutDir}])),
- ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}]),
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
-
-testConstraints(suite) ->
- [];
-testConstraints(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testConstraints:compile(Config,?BER,[]),
- ?line testConstraints:int_constraints(?BER),
-
- ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
-
- ?line testConstraints:compile(Config,?PER,[]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER),
-
- ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
- ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
-
- ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
- ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
-
- ?line testConstraints:compile(Config,?PER,[optimize]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER).
-
-testSeqIndefinite(suite) -> [];
-testSeqIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqIndefinite:compile(Config,?BER,[]),
- ?line testSeqIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
-
-testSetIndefinite(suite) -> [];
-testSetIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetIndefinite:compile(Config,?BER,[]),
- ?line testSetIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
-
-testChoiceIndefinite(suite) -> [];
-testChoiceIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testChoiceIndefinite:compile(Config,?BER,[]),
- ?line testChoiceIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
-
-testInfObjectClass(suite) ->
- [];
-testInfObjectClass(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testInfObjectClass:compile(Config,?PER,[]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[]),
- ?line testInfObj:main(?PER),
-
- ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
- ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObj:main(?PER)),
-
- ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
- ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObj:main(uper_bin)),
-
- ?line testInfObjectClass:compile(Config,?PER,[optimize]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[optimize]),
- ?line testInfObj:main(?PER),
-
- ?line testInfObjectClass:compile(Config,?BER,[]),
- ?line testInfObjectClass:main(?BER),
- ?line testInfObj:compile(Config,?BER,[]),
- ?line testInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
- ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObj:main(?BER)),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
-
- ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
-
- ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
-
- ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
-
-testParameterizedInfObj(suite) ->
- [];
-testParameterizedInfObj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
-
- ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line testParameterizedInfObj:compile(Config,?BER,[]),
- ?line testParameterizedInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
-
-testMergeCompile(suite) ->
- [];
-testMergeCompile(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMergeCompile:compile(Config,?PER,[]),
- ?line testMergeCompile:main(?PER),
- ?line testMergeCompile:mvrasn(?PER),
-
- ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testMergeCompile:main(?PER)),
- ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
-
- ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testMergeCompile:main(uper_bin)),
- ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
-
- ?line testMergeCompile:compile(Config,?BER,[]),
- ?line testMergeCompile:main(?BER),
- ?line testMergeCompile:mvrasn(?BER),
-
- ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
- ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
-
-testobj(suite) ->
- [];
-testobj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = testRANAP:compile(Config,?PER,[]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
- ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
-
- ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
- ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
-
- ?line ok = testRANAP:compile(Config,?PER,[optimize]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ok = testRANAP:compile(Config,?BER,[]),
- ?line ok = testRANAP:testobj(?BER),
- ?line ok = testParameterizedInfObj:ranap(?BER),
-
- ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
- ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
-
-
-testDeepTConstr(suite) ->
- [];
-testDeepTConstr(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDeepTConstr:compile(Config,?PER,[]),
- ?line testDeepTConstr:main(?PER),
-
- ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
-
- ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
-
- ?line testDeepTConstr:compile(Config,?PER,[optimize]),
- ?line testDeepTConstr:main(?PER),
-
- ?line testDeepTConstr:compile(Config,?BER,[]),
- ?line testDeepTConstr:main(?BER),
-
- ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
-
-testInvokeMod(suite) ->
- [];
-testInvokeMod(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
- ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
- ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
-
-testExport(suite) ->
- [];
-testExport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
-
-testImport(suite) ->
- [];
-testImport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line _OutDir = ?config(priv_dir,Config),
- ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
- ok.
-
-testMegaco(suite) ->
- [];
-testMegaco(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
- io:format("Config: ~p~n",[Config]),
- ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
- ?line ok = testMegaco:main(ModuleName1,Config),
- ?line ok = testMegaco:main(ModuleName2,Config),
-
- case ?BER of
- ber_bin_v2 ->
- ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
- ?line ok = testMegaco:main(ModuleName3,Config),
- ?line ok = testMegaco:main(ModuleName4,Config);
- _-> ok
- end,
-
- ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
- ?line ok = testMegaco:main(ModuleName5,Config),
- ?line ok = testMegaco:main(ModuleName6,Config),
-
- ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
- ?line ok = testMegaco:main(ModuleName7,Config),
- ?line ok = testMegaco:main(ModuleName8,Config).
-
-
-testMvrasn6(suite) -> [];
-testMvrasn6(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMvrasn6:compile(Config,?BER),
- ?line testMvrasn6:main().
-
-testContextSwitchingTypes(suite) -> [];
-testContextSwitchingTypes(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testContextSwitchingTypes:compile(Config,?BER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testContextSwitchingTypes:test()),
-
- ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
- ?line testContextSwitchingTypes:test().
-
-testTypeValueNotation(suite) -> [];
-testTypeValueNotation(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- case ?BER of
- Ber when Ber == ber; Ber == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?BER,[]),
- ?line testTypeValueNotation:main(?BER,dummy);
- _ ->
- ok
- end,
-
- ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
-
- case ?BER of
- Ber2 when Ber2 == ber; Ber2 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[]),
- ?line testTypeValueNotation:main(?PER,dummy);
- _ ->
- ok
- end,
-
- ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
-
- ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
- case ?BER of
- Ber3 when Ber3 == ber; Ber3 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
- ?line testTypeValueNotation:main(?PER,optimize);
- _ ->
- ok
- end.
-
-testOpenTypeImplicitTag(suite) -> [];
-testOpenTypeImplicitTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
- ?line testOpenTypeImplicitTag:main(?BER),
-
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
- ?line testOpenTypeImplicitTag:main(?PER),
-
- ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
-
- ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
- ?line testOpenTypeImplicitTag:main(?PER).
-
-duplicate_tags(suite) -> [];
-duplicate_tags(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
- asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
- ok.
-
-rtUI(suite) -> [];
-rtUI(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:unload_driver().
-
-testROSE(suite) -> [];
-testROSE(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testROSE:compile(Config,?BER,[]),
-
- ?line testROSE:compile(Config,?PER,[]),
- ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
- ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
- ?line testROSE:compile(Config,?PER,[optimize]).
-
-testINSTANCE_OF(suite) -> [];
-testINSTANCE_OF(Config) ->
- ?line testINSTANCE_OF:compile(Config,?BER,[]),
- ?line testINSTANCE_OF:main(?BER),
-
- ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[]),
- ?line testINSTANCE_OF:main(?PER),
-
- ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
-
- ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
- ?line testINSTANCE_OF:main(?PER).
-
-testTCAP(suite) -> [];
-testTCAP(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testTCAP:compile(Config,?BER,[]),
- ?line testTCAP:test(?BER,Config),
-
- ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
-
- ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
- ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
-
-testDER(suite) ->[];
-testDER(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDER:compile(Config,?BER,[]),
- ?line testDER:test(),
-
- ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDER:test()),
-
- ?line testParamBasic:compile_der(Config,?BER),
- ?line testParamBasic_cases(der),
-
-
- ?line testSeqSetDefaultVal:compile(Config,?BER),
- ?line testSeqSetDefaultVal_cases(?BER).
-
-testSeqSetDefaultVal_cases(?BER) ->
- ?line testSeqSetDefaultVal:main(?BER).
-
-
-specialized_decodes(suite) -> [];
-specialized_decodes(Config) ->
- ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
- ?line test_partial_incomplete_decode:test(?BER,Config),
- ?line test_selective_decode:test(?BER,Config).
-
-special_decode_performance(suite) ->[];
-special_decode_performance(Config) ->
- ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
- ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
-
-
-test_driver_load(suite) -> [];
-test_driver_load(Config) ->
- ?line test_driver_load:compile(Config,?PER),
- ?line test_driver_load:test(?PER,5).
-
-test_ParamTypeInfObj(suite) -> [];
-test_ParamTypeInfObj(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
-
-test_WS_ParamClass(suite) -> [];
-test_WS_ParamClass(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
- [ber_bin]).
-
-test_Defed_ObjectIdentifier(suite) -> [];
-test_Defed_ObjectIdentifier(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
- [ber_bin]).
-
-testSelectionType(suite) -> [];
-testSelectionType(Config) ->
-
- ?line ok = testSelectionTypes:compile(Config,?BER,[]),
- ?line {ok,_} = testSelectionTypes:test(),
-
- ?line ok = testSelectionTypes:compile(Config,?PER,[]),
- ?line {ok,_} = testSelectionTypes:test().
-
-testSSLspecs(suite) -> [];
-testSSLspecs(Config) ->
-
- ?line ok = testSSLspecs:compile(Config,?BER,
- [optimize,compact_bit_string,der]),
- ?line testSSLspecs:run(?BER),
-
- case code:which(asn1ct) of
- cover_compiled ->
- ok;
- _ ->
- ?line ok = testSSLspecs:compile_inline(Config,?BER),
- ?line ok = testSSLspecs:run_inline(?BER)
- end.
-
-testNortel(suite) -> [];
-testNortel(Config) ->
- ?line DataDir = ?config(data_dir,Config),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize,driver]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
- ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize])),
- ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize]).
-test_undecoded_rest(suite) -> [];
-test_undecoded_rest(Config) ->
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
- ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
- ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest).
-
-test_inline(suite) -> [];
-test_inline(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok=test_inline:compile(Config,?BER,[]),
- ?line test_inline:main(?BER),
- ?line test_inline:inline1(Config,?BER,[]),
- ?line test_inline:performance2()
- end.
-
-%test_inline_prf(suite) -> [];
-%test_inline_prf(Config) ->
-% ?line test_inline:performance(Config).
-
-testTcapsystem(suite) -> [];
-testTcapsystem(Config) ->
- ?line ok=testTcapsystem:compile(Config,?BER,[]).
-
-testNBAPsystem(suite) -> [];
-testNBAPsystem(Config) ->
- ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
- ?line ok=testNBAPsystem:test(?PER,Config).
-
-test_compile_options(suite) -> [];
-test_compile_options(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok = test_compile_options:wrong_path(Config),
- ?line ok = test_compile_options:path(Config),
- ?line ok = test_compile_options:noobj(Config),
- ?line ok = test_compile_options:record_name_prefix(Config),
- ?line ok = test_compile_options:verbose(Config)
- end.
-testDoubleEllipses(suite) -> [];
-testDoubleEllipses(Config) ->
- ?line testDoubleEllipses:compile(Config,?BER,[]),
- ?line testDoubleEllipses:main(?BER),
- ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
- ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
- ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
- ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
- ?line testDoubleEllipses:main(?PER).
-
-test_modified_x420(suite) -> [];
-test_modified_x420(Config) ->
- ?line test_modified_x420:compile(Config),
- ?line test_modified_x420:test_io(Config).
-
-testX420(suite) -> [];
-testX420(Config) ->
- ?line testX420:compile(?BER,[der],Config),
- ?line ok = testX420:ticket7759(?BER,Config),
- ?line testX420:compile(?PER,[],Config).
-
-test_x691(suite) -> [];
-test_x691(Config) ->
- case ?PER of
- per ->
- ?line ok = test_x691:compile(Config,uper_bin,[]),
- ?line true = test_x691:cases(uper_bin,unaligned),
- ?line ok = test_x691:compile(Config,?PER,[]),
- ?line true = test_x691:cases(?PER,aligned),
-%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
- ?line ok = asn1_test_lib:ticket_7708(Config,[]),
- ?line ok = asn1_test_lib:ticket_7763(Config);
- _ ->
- ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
- ?line true = test_x691:cases(?PER,aligned)
- end.
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
-
-
-ticket_6143(suite) -> [];
-ticket_6143(Config) ->
- ?line ok = test_compile_options:ticket_6143(Config).
-
-testExtensionAdditionGroup(suite) -> [];
-testExtensionAdditionGroup(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line PrivDir = ?config(priv_dir,Config),
- ?line Path = code:get_path(),
- ?line code:add_patha(PrivDir),
- DoIt = fun(Erule) ->
- ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
- ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
- ?line ok = extensionAdditionGroup:run(Erule)
- end,
- ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
- ?line code:set_path(Path).
-
-
-
-% parse_modules() ->
-% ["ImportsFrom"].
-
-per_modules() ->
- [X || X <- test_modules()].
-ber_modules() ->
- [X || X <- test_modules(),
- X =/= "CommonDataTypes",
- X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- X =/= "H323-MESSAGES",
- X =/= "H235-SECURITY-MESSAGES",
- X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
-test_modules() ->
- _Modules = [
- "BitStr",
- "CommonDataTypes",
- "Constraints",
- "ContextSwitchingTypes",
- "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- "Enum",
- "From",
- "H235-SECURITY-MESSAGES",
- "H323-MESSAGES",
- %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
- "Import",
- "Int",
- "MAP-commonDataTypes",
-% ambigous tags "MAP-insertSubscriberData-def",
- "Null",
- "Octetstr",
- "One",
- "P-Record",
- "P",
-% "PDUs",
- "Person",
- "PrimStrings",
- "Real",
- "XSeq",
- "XSeqOf",
- "XSet",
- "XSetOf",
- "String",
- "SwCDR",
-% "Syntax",
- "Time"
-% ANY "Tst",
-% "Two",
-% errors that should be detected "UndefType"
-] ++
- [
- "SeqSetLib", % must be compiled before Seq and Set
- "Seq",
- "Set",
- "SetOf",
- "SeqOf",
- "Prim",
- "Cho",
- "Def",
- "Opt",
- "ELDAPv3",
- "LDAP"
- ].
-
-
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-
-common() ->
-[{group, app_test}, {group, appup_test}, testTimer_ber,
- testTimer_ber_bin, testTimer_ber_bin_opt,
- testTimer_ber_bin_opt_driver, testTimer_per,
- testTimer_per_bin, testTimer_per_bin_opt,
- testTimer_uper_bin, testComment, testName2Number].
-
-
-
-testTimer_ber(suite) -> [];
-testTimer_ber(Config) ->
- ?line testTimer:compile(Config,ber,[]),
- ?line testTimer:go(Config,ber).
-
-testTimer_ber_bin(suite) -> [];
-testTimer_ber_bin(Config) ->
- ?line testTimer:compile(Config,ber_bin,[]),
- ?line testTimer:go(Config,ber_bin).
-
-testTimer_ber_bin_opt(suite) -> [];
-testTimer_ber_bin_opt(Config) ->
- ?line testTimer:compile(Config,ber_bin,[optimize]),
- ?line testTimer:go(Config,ber_bin).
-
-testTimer_ber_bin_opt_driver(suite) -> [];
-testTimer_ber_bin_opt_driver(Config) ->
- ?line testTimer:compile(Config,ber_bin,[optimize,driver]),
- ?line testTimer:go(Config,ber_bin).
-
-testTimer_per(suite) -> [];
-testTimer_per(Config) ->
- ?line testTimer:compile(Config,per,[]),
- ?line testTimer:go(Config,per).
-
-testTimer_per_bin(suite) -> [];
-testTimer_per_bin(Config) ->
- ?line testTimer:compile(Config,per_bin,[]),
- ?line testTimer:go(Config,per_bin).
-
-testTimer_per_bin_opt(suite) -> [];
-testTimer_per_bin_opt(Config) ->
- ?line testTimer:compile(Config,per_bin,[optimize]),
- ?line testTimer:go(Config,per_bin).
-
-
-testTimer_uper_bin(suite) -> [];
-testTimer_uper_bin(Config) ->
- ?line ok=testTimer:compile(Config,uper_bin,[]),
- ?line {comment,_} = testTimer:go(Config,uper_bin).
-
-%% Test of multiple-line comment, OTP-8043
-testComment(suite) -> [];
-testComment(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
-
- ?line ok = asn1ct:compile(DataDir ++ "Comment",[{outdir,OutDir}]),
-
- ?line {ok,Enc} = asn1_wrapper:encode('Comment','Seq',{'Seq',12,true}),
- ?line {ok,{'Seq',12,true}} = asn1_wrapper:decode('Comment','Seq',Enc),
- ok.
-
-testName2Number(suite) -> [];
-testName2Number(Config) ->
- DataDir = ?config(data_dir,Config),
- OutDir = ?config(priv_dir,Config),
- N2NOptions = [{n2n,Type}|| Type <-
- ['CauseMisc','CauseProtocol',
- %% 'CauseNetwork',
- 'CauseRadioNetwork',
- 'CauseTransport','CauseNas']],
- ?line ok = asn1ct:compile(DataDir ++ "S1AP-IEs",[{outdir,OutDir}]++N2NOptions),
- ?line true = code:add_patha(OutDir),
-
- ?line 0 = 'S1AP-IEs':name2num_CauseMisc('control-processing-overload'),
- ?line 'unknown-PLMN' = 'S1AP-IEs':num2name_CauseMisc(5),
- ok.
-
-
-particular() ->
- [ticket_7407].
-
-ticket_7407(suite) -> [];
-ticket_7407(Config) ->
- ?line ok = asn1_test_lib:ticket_7407_compile(Config,[]),
- ?line ok = asn1_test_lib:ticket_7407_code(true),
-
- ?line ok = asn1_test_lib:ticket_7407_compile(Config,[no_final_padding]),
- ?line ok = asn1_test_lib:ticket_7407_code(false).
diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src
index 7201365ea3..582ccd877c 100644
--- a/lib/asn1/test/asn1_SUITE.erl.src
+++ b/lib/asn1/test/asn1_SUITE.erl.src
@@ -60,10 +60,10 @@ bool0, bool1 = asn1_DEFAULT, bool2 = asn1_DEFAULT, bool3 = asn1_DEFAULT}).
%-record('Def3',{
%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
+suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all(suite) -> [compile,parse,default_per,default_ber,default_per_opt,per,
- ber,testPrim,
+all() -> [{group,compile},parse,default_per,default_ber,default_per_opt,per,
+ {group,ber},testPrim,
testPrimStrings, testPrimExternal, testChoPrim,
testChoExtension, testChoExternal, testChoOptional,
testChoOptionalImplicitTag, testChoRecursive,
@@ -99,21 +99,34 @@ all(suite) -> [compile,parse,default_per,default_ber,default_per_opt,per,
testX420, test_x691,ticket_6143, testExtensionAdditionGroup
] ++ common() ++ particular().
-%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+groups() ->
+ [
+ {compile, [],
+ [c_syntax, c_string_per, c_string_ber,
+ c_implicit_before_choice]},
+ {ber, [],
+ [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
+ ber_other]},
+ {app_test, [], [{asn1_app_test, all}]},
+ {appup_test, [], [{asn1_appup_test, all}]}
+ ].
+
+init_per_suite(Config) ->
+ io:format("code:lib_dir(asn1) = ~p~n",[code:lib_dir(asn1)]),
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
-option_tests(suite) ->
- [test_compile_options,ticket_6143].
+init_per_group(_GroupName, Config) ->
+ Config.
-infobj(suite) ->
- [testInfObjectClass, testParameterizedInfObj, testMergeCompile,
- testobj, testDeepTConstr].
+end_per_group(_GroupName, Config) ->
+ Config.
-performance(suite) ->
- [testTimer_ber, testTimer_ber_opt_driver,
- testTimer_per, testTimer_per_opt, testTimer_uper_bin].
-bugs(suite) ->
- [test_ParamTypeInfObj, test_WS_ParamClass,test_Defed_ObjectIdentifier].
+%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
+
init_per_testcase(Func,Config) ->
%%?line test_server:format("Func: ~p~n",[Func]),
@@ -129,7 +142,7 @@ init_per_testcase(Func,Config) ->
%% Dog=test_server:timetrap(1800000), % 30 minutes
[{watchdog, Dog}|Config].
-fin_per_testcase(_Func,Config) ->
+end_per_testcase(_Func,Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog).
@@ -1371,22 +1384,6 @@ testSetOfTag_cases(Rules) ->
sequence(suite) -> [{sequence,all}].
-compile(suite) -> [c_syntax,c_string_per,c_string_ber,c_implicit_before_choice];
-compile(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line True = lists:member(TempDir,code:get_path()),
- ?line test_server:format("~p~n",[True]),
- ?line test_server:format("~p~n",[code:get_path()]),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]),
- test_server:format("first String ok~n"),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]),
- ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER,{outdir,TempDir}]),
- ok.
-
c_syntax(suite) -> [];
c_syntax(Config) ->
?line DataDir% ?line testExternal:compile(Config,?PER),
@@ -1490,8 +1487,6 @@ per1_opt([M|T],DataDir,OutDir) ->
per1_opt([],_,_) ->
ok.
-ber(suite) -> [ber_choiceinseq,ber_optional,ber_optional_keyed_list,ber_other].
-
ber_choiceinseq(suite) ->[];
ber_choiceinseq(Config) ->
?line DataDir = ?config(data_dir,Config),
diff --git a/lib/asn1/test/asn1_bin_SUITE.erl b/lib/asn1/test/asn1_bin_SUITE.erl
deleted file mode 100644
index a924aee0db..0000000000
--- a/lib/asn1/test/asn1_bin_SUITE.erl
+++ /dev/null
@@ -1,2382 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%% Purpose : Test suite for the ASN.1 application
-
--module(asn1_bin_SUITE).
--define(PER,'per_bin').
--define(BER,'ber_bin').
--define(ber_driver(Erule,Func),
- case Erule of
- ber_bin_v2 ->
- Func;
- _ -> ok
- end).
--define(per_optimize(Erule),
- case Erule of
- ber_bin_v2 ->[optimize];
- _ -> []
- end).
--define(per_bit_opt(FuncCall),
- case ?BER of
- ber_bin_v2 -> FuncCall;
-% _ -> {skip,"only for bit optimized per_bin"}
- _ -> ok
- end).
--define(uper_bin(FuncCall),
- case ?PER of
- per -> FuncCall;
- _ -> ok
- end).
-
--compile(export_all).
-%%-export([Function/Arity, ...]).
-
--include_lib("test_server/include/test_server.hrl").
-
-%% records used by test-case default
--record('Def1',{bool0, bool1 = asn1_DEFAULT,
- bool2 = asn1_DEFAULT,
- bool3 = asn1_DEFAULT}).
-
-%-record('Def2',{
-%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
-
-%-record('Def3',{
-%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
-
-
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [{group, compile}, parse, default_per, default_ber,
- default_per_opt, per, {group, ber}, testPrim,
- testPrimStrings, testPrimExternal, testChoPrim,
- testChoExtension, testChoExternal, testChoOptional,
- testChoOptionalImplicitTag, testChoRecursive,
- testChoTypeRefCho, testChoTypeRefPrim,
- testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
- testSeqDefault, testSeqExtension, testSeqExternal,
- testSeqOptional, testSeqPrim, testSeqTag,
- testSeqTypeRefCho, testSeqTypeRefPrim,
- testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
- testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
- testSetDefault, testSetExtension,
- testExtensionAdditionGroup, testSetExternal,
- testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
- testSetTypeRefCho, testSetTypeRefPrim,
- testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
- testSetOfCho, testSetOfExternal, testSetOfTag,
- testEnumExt, value_test, testSeq2738, constructed,
- ber_decode_error, h323test, testSeqIndefinite,
- testSetIndefinite, testChoiceIndefinite,
- per_GeneralString, per_open_type, testInfObjectClass,
- testParameterizedInfObj, testMergeCompile, testobj,
- testDeepTConstr, testConstraints, testInvokeMod,
- testExport, testImport, testCompactBitString,
- testMegaco, testParamBasic, testMvrasn6,
- testContextSwitchingTypes, testTypeValueNotation,
- testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
- testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
- special_decode_performance, test_driver_load,
- test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier, testSelectionType,
- testSSLspecs, testNortel, test_undecoded_rest,
- test_inline, testTcapsystem, testNBAPsystem,
- test_compile_options, testDoubleEllipses,
- test_modified_x420, testX420, test_x691, ticket_6143,
- testExtensionAdditionGroup] ++ common() ++ particular().
-
-groups() ->
- [{option_tests, [],
- [test_compile_options, ticket_6143]},
- {infobj, [],
- [testInfObjectClass, testParameterizedInfObj,
- testMergeCompile, testobj, testDeepTConstr]},
- {performance, [],
- [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
- testTimer_per_opt, testTimer_uper_bin]},
- {bugs, [],
- [test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier]},
- {compile, [],
- [c_syntax, c_string_per, c_string_ber,
- c_implicit_before_choice]},
- {ber, [],
- [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
- ber_other]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
-
-init_per_testcase(Func,Config) ->
- %%?line test_server:format("Func: ~p~n",[Func]),
- ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
- ?line code:add_patha(?config(priv_dir,Config)),
- Dog=
- case Func of
- testX420 ->
- test_server:timetrap({minutes,60}); % 60 minutes
- _ ->
- test_server:timetrap({minutes,30}) % 60 minutes
- end,
-%% Dog=test_server:timetrap(1800000), % 30 minutes
- [{watchdog, Dog}|Config].
-
-end_per_testcase(_Func,Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog).
-
-
-testPrim(suite) -> [];
-testPrim(Config) ->
- ?line testPrim:compile(Config,?BER,[]),
- ?line testPrim_cases(?BER),
- ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrim_cases(?BER)),
- ?line testPrim:compile(Config,?PER,[]),
- ?line testPrim_cases(?PER),
- ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrim_cases(?PER)),
- ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrim_cases(uper_bin)),
- ?line testPrim:compile(Config,?PER,[optimize]),
- ?line testPrim_cases(?PER).
-
-testPrim_cases(Rules) ->
- ?line testPrim:bool(Rules),
- ?line testPrim:int(Rules),
- ?line testPrim:enum(Rules),
- ?line testPrim:obj_id(Rules),
- ?line testPrim:rel_oid(Rules),
- ?line testPrim:null(Rules),
- ?line testPrim:real(Rules).
-
-
-testCompactBitString(suite) -> [];
-testCompactBitString(Config) ->
-
- ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?BER),
-
- ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
- ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
-
- ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
- [compact_bit_string,optimize])),
- ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
- ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
- ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
-
- ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
- [compact_bit_string])),
- ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
- ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
-
- ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line testCompactBitString:otp_4869(?PER).
-
-
-testPrimStrings(suite) -> [];
-testPrimStrings(Config) ->
-
- ?line testPrimStrings:compile(Config,?BER,[]),
- ?line testPrimStrings_cases(?BER),
- ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
- ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
- ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
-
- ?line testPrimStrings:compile(Config,?PER,[]),
- ?line testPrimStrings_cases(?PER),
-
- ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
-
- ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
-
- ?line testPrimStrings:compile(Config,?PER,[optimize]),
- ?line testPrimStrings_cases(?PER).
-
-testPrimStrings_cases(Rules) ->
- ?line testPrimStrings:bit_string(Rules),
- ?line testPrimStrings:bit_string_unnamed(Rules),
- ?line testPrimStrings:octet_string(Rules),
- ?line testPrimStrings:numeric_string(Rules),
- ?line testPrimStrings:other_strings(Rules),
- ?line testPrimStrings:universal_string(Rules),
- ?line testPrimStrings:bmp_string(Rules),
- ?line testPrimStrings:times(Rules),
- ?line testPrimStrings:utf8_string(Rules).
-
-
-
-testPrimExternal(suite) -> [];
-testPrimExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testPrimExternal:compile(Config,?BER,[]),
- ?line testPrimExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testPrimExternal:compile(Config,?PER,[]),
- ?line testPrimExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal_cases(?PER).
-
-testPrimExternal_cases(Rules) ->
- ?line testPrimExternal:external(Rules).
-
-
-
-
-testChoPrim(suite) -> [];
-testChoPrim(Config) ->
-
- ?line testChoPrim:compile(Config,?BER,[]),
- ?line testChoPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
-
- ?line testChoPrim:compile(Config,?PER,[]),
- ?line testChoPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoPrim_cases(uper_bin)),
-
- ?line testChoPrim:compile(Config,?PER,[optimize]),
- ?line testChoPrim_cases(?PER).
-
-testChoPrim_cases(Rules) ->
- ?line testChoPrim:bool(Rules),
- ?line testChoPrim:int(Rules).
-
-
-
-testChoExtension(suite) -> [];
-testChoExtension(Config) ->
-
- ?line testChoExtension:compile(Config,?BER,[]),
- ?line testChoExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
-
- ?line testChoExtension:compile(Config,?PER,[]),
- ?line testChoExtension_cases(?PER),
-
- ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExtension_cases(?PER)),
-
- ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExtension_cases(uper_bin)),
-
- ?line testChoExtension:compile(Config,?PER,[optimize]),
- ?line testChoExtension_cases(?PER).
-
-testChoExtension_cases(Rules) ->
- ?line testChoExtension:extension(Rules).
-
-
-
-testChoExternal(suite) -> [];
-testChoExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testChoExternal:compile(Config,?BER,[]),
- ?line testChoExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testChoExternal:compile(Config,?PER,[]),
- ?line testChoExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal_cases(?PER).
-
-
-testChoExternal_cases(Rules) ->
- ?line testChoExternal:external(Rules).
-
-
-
-testChoOptional(suite) -> [];
-testChoOptional(Config) ->
-
- ?line testChoOptional:compile(Config,?BER,[]),
- ?line testChoOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
-
- ?line testChoOptional:compile(Config,?PER,[]),
- ?line testChoOptional_cases(?PER),
-
- ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoOptional_cases(?PER)),
-
- ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoOptional_cases(uper_bin)),
-
- ?line testChoOptional:compile(Config,?PER,[optimize]),
- ?line testChoOptional_cases(?PER).
-
-testChoOptional_cases(Rules) ->
- ?line testChoOptional:optional(Rules).
-
-testChoOptionalImplicitTag(suite) -> [];
-testChoOptionalImplicitTag(Config) ->
- %% Only meaningful for ?BER
- ?line testChoOptionalImplicitTag:compile(Config,?BER),
- ?line testChoOptionalImplicitTag:optional(?BER).
-
-
-testChoRecursive(suite) -> [];
-testChoRecursive(Config) ->
-
- ?line testChoRecursive:compile(Config,?BER,[]),
- ?line testChoRecursive_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
-
- ?line testChoRecursive:compile(Config,?PER,[]),
- ?line testChoRecursive_cases(?PER),
-
- ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
-
- ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
-
- ?line testChoRecursive:compile(Config,?PER,[optimize]),
- ?line testChoRecursive_cases(?PER).
-
-testChoRecursive_cases(Rules) ->
- ?line testChoRecursive:recursive(Rules).
-
-
-
-testChoTypeRefCho(suite) -> [];
-testChoTypeRefCho(Config) ->
-
- ?line testChoTypeRefCho:compile(Config,?BER,[]),
- ?line testChoTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[]),
- ?line testChoTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefCho_cases(?PER).
-
-testChoTypeRefCho_cases(Rules) ->
- ?line testChoTypeRefCho:choice(Rules).
-
-
-
-testChoTypeRefPrim(suite) -> [];
-testChoTypeRefPrim(Config) ->
-
- ?line testChoTypeRefPrim:compile(Config,?BER,[]),
- ?line testChoTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[]),
- ?line testChoTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefPrim_cases(?PER).
-
-testChoTypeRefPrim_cases(Rules) ->
- ?line testChoTypeRefPrim:prim(Rules).
-
-
-
-testChoTypeRefSeq(suite) -> [];
-testChoTypeRefSeq(Config) ->
-
- ?line testChoTypeRefSeq:compile(Config,?BER,[]),
- ?line testChoTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[]),
- ?line testChoTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSeq_cases(?PER).
-
-testChoTypeRefSeq_cases(Rules) ->
- ?line testChoTypeRefSeq:seq(Rules).
-
-
-
-testChoTypeRefSet(suite) -> [];
-testChoTypeRefSet(Config) ->
-
- ?line testChoTypeRefSet:compile(Config,?BER,[]),
- ?line testChoTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[]),
- ?line testChoTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSet_cases(?PER).
-
-testChoTypeRefSet_cases(Rules) ->
- ?line testChoTypeRefSet:set(Rules).
-
-
-
-testDef(suite) -> [];
-testDef(Config) ->
-
- ?line testDef:compile(Config,?BER,[]),
- ?line testDef_cases(?BER),
-
- ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDef_cases(?BER)),
-
- ?line testDef:compile(Config,?PER,[]),
- ?line testDef_cases(?PER),
-
- ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDef_cases(?PER)),
-
- ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDef_cases(uper_bin)),
-
- ?line testDef:compile(Config,?PER,[optimize]),
- ?line testDef_cases(?PER).
-
-testDef_cases(Rules) ->
- ?line testDef:main(Rules).
-
-
-
-testOpt(suite) -> [];
-testOpt(Config) ->
-
- ?line testOpt:compile(Config,?BER),
- ?line testOpt_cases(?BER),
-
- ?line testOpt:compile(Config,?PER),
- ?line testOpt_cases(?PER).
-
-testOpt_cases(Rules) ->
- ?line testOpt:main(Rules).
-
-
-testEnumExt(suite) -> [];
-testEnumExt(Config) ->
-
- ?line testEnumExt:compile(Config,?BER,[]),
- ?line testEnumExt:main(?BER),
-
- ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
-
- ?line testEnumExt:compile(Config,?PER,[]),
- ?line testEnumExt:main(?PER),
-
- ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testEnumExt:main(?PER)),
-
- ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testEnumExt:main(uper_bin)),
-
- ?line testEnumExt:compile(Config,?PER,[optimize]),
- ?line testEnumExt:main(?PER).
-
-testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
-testSeqDefault(suite) -> [];
-testSeqDefault(Config) ->
-
- ?line testSeqDefault:compile(Config,?BER,[]),
- ?line testSeqDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
-
- ?line testSeqDefault:compile(Config,?PER,[]),
- ?line testSeqDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
-
- ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
-
- ?line testSeqDefault:compile(Config,?PER,[optimize]),
- ?line testSeqDefault_cases(?PER).
-
-testSeqDefault_cases(Rules) ->
- ?line testSeqDefault:main(Rules).
-
-
-
-testSeqExtension(suite) -> [];
-testSeqExtension(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExtension:compile(Config,?BER,[]),
- ?line testSeqExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
-
-testSeqExtension_cases(Rules) ->
- ?line testSeqExtension:main(Rules).
-
-
-
-testSeqExternal(suite) -> [];
-testSeqExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExternal:compile(Config,?BER,[]),
- ?line testSeqExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
-
-testSeqExternal_cases(Rules) ->
- ?line testSeqExternal:main(Rules).
-
-
-testSeqOptional(suite) -> [];
-testSeqOptional(Config) ->
-
- ?line testSeqOptional:compile(Config,?BER,[]),
- ?line testSeqOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
-
- ?line testSeqOptional:compile(Config,?PER,[]),
- ?line testSeqOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
-
- ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
-
- ?line testSeqOptional:compile(Config,?PER,[optimize]),
- ?line testSeqOptional_cases(?PER).
-
-testSeqOptional_cases(Rules) ->
- ?line testSeqOptional:main(Rules).
-
-
-
-testSeqPrim(suite) -> [];
-testSeqPrim(Config) ->
-
- ?line testSeqPrim:compile(Config,?BER,[]),
- ?line testSeqPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
-
- ?line testSeqPrim:compile(Config,?PER,[]),
- ?line testSeqPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
-
- ?line testSeqPrim:compile(Config,?PER,[optimize]),
- ?line testSeqPrim_cases(?PER).
-
-testSeqPrim_cases(Rules) ->
- ?line testSeqPrim:main(Rules).
-
-
-testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
-testSeq2738(suite) -> [];
-testSeq2738(Config) ->
-
- ?line testSeq2738:compile(Config,?BER,[]),
- ?line testSeq2738_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
-
- ?line testSeq2738:compile(Config,?PER,[]),
- ?line testSeq2738_cases(?PER),
-
- ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeq2738_cases(?PER)),
-
- ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeq2738_cases(uper_bin)),
-
- ?line testSeq2738:compile(Config,?PER,[optimize]),
- ?line testSeq2738_cases(?PER).
-
-testSeq2738_cases(Rules) ->
- ?line testSeq2738:main(Rules).
-
-
-testSeqTag(suite) -> [];
-testSeqTag(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqTag:compile(Config,?BER,[]),
- ?line testSeqTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqTag:compile(Config,?PER,[]),
- ?line testSeqTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqTag:compile(Config,?PER,[optimize]),
- ?line testSeqTag_cases(?PER).
-
-testSeqTag_cases(Rules) ->
- ?line testSeqTag:main(Rules).
-
-
-
-
-testSeqTypeRefCho(suite) -> [];
-testSeqTypeRefCho(Config) ->
-
- ?line testSeqTypeRefCho:compile(Config,?BER,[]),
- ?line testSeqTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[]),
- ?line testSeqTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefCho_cases(?PER).
-
-testSeqTypeRefCho_cases(Rules) ->
- ?line testSeqTypeRefCho:main(Rules).
-
-
-
-testSeqTypeRefPrim(suite) -> [];
-testSeqTypeRefPrim(Config) ->
-
- ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
- ?line testSeqTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
- ?line testSeqTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefPrim_cases(?PER).
-
-testSeqTypeRefPrim_cases(Rules) ->
- ?line testSeqTypeRefPrim:main(Rules).
-
-
-
-testSeqTypeRefSeq(suite) -> [];
-testSeqTypeRefSeq(Config) ->
-
- ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
- ?line testSeqTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
- ?line testSeqTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSeq_cases(?PER).
-
-testSeqTypeRefSeq_cases(Rules) ->
- ?line testSeqTypeRefSeq:main(Rules).
-
-
-
-testSeqTypeRefSet(suite) -> [];
-testSeqTypeRefSet(Config) ->
-
- ?line testSeqTypeRefSet:compile(Config,?BER,[]),
- ?line testSeqTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[]),
- ?line testSeqTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSet_cases(?PER).
-
-testSeqTypeRefSet_cases(Rules) ->
- ?line testSeqTypeRefSet:main(Rules).
-
-
-
-
-testSeqOf(suite) -> [];
-testSeqOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOf:compile(Config,?BER,[]),
- ?line testSeqOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
-
- ?line testSeqOf:compile(Config,?PER,[]),
- ?line testSeqOf_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOf_cases(?PER)),
-
- ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOf_cases(uper_bin)),
-
- ?line testSeqOf:compile(Config,?PER,[optimize]),
- ?line testSeqOf_cases(?PER).
-
-testSeqOf_cases(Rules) ->
- ?line testSeqOf:main(Rules).
-
-
-
-
-testSeqOfCho(suite) -> [];
-testSeqOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfCho:compile(Config,?BER,[]),
- ?line testSeqOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
-
- ?line testSeqOfCho:compile(Config,?PER,[]),
- ?line testSeqOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
-
- ?line testSeqOfCho:compile(Config,?PER,[optimize]),
- ?line testSeqOfCho_cases(?PER).
-
-testSeqOfIndefinite(suite) -> [];
-testSeqOfIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfIndefinite:compile(Config,?BER,[]),
- ?line testSeqOfIndefinite:main(),
-
- ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
-
-testSeqOfCho_cases(Rules) ->
- ?line testSeqOfCho:main(Rules).
-
-
-testSeqOfExternal(suite) -> [];
-testSeqOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal_cases(?PER).
-
-testSeqOfExternal_cases(Rules) ->
- ?line testSeqOfExternal:main(Rules).
-
-
-
-testSeqOfTag(suite) -> [];
-testSeqOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfTag:compile(Config,?BER,[]),
- ?line testSeqOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfTag:compile(Config,?PER,[]),
- ?line testSeqOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag_cases(?PER).
-
-testSeqOfTag_cases(Rules) ->
- ?line testSeqOfTag:main(Rules).
-
-
-
-
-testSetDefault(suite) -> [];
-testSetDefault(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetDefault:compile(Config,?BER,[]),
- ?line testSetDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
-
- ?line testSetDefault:compile(Config,?PER,[]),
- ?line testSetDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetDefault_cases(?PER)),
-
- ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetDefault_cases(uper_bin)),
-
- ?line testSetDefault:compile(Config,?PER,[optimize]),
- ?line testSetDefault_cases(?PER).
-
-testSetDefault_cases(Rules) ->
- ?line testSetDefault:main(Rules).
-
-
-testParamBasic(suite) -> [];
-testParamBasic(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParamBasic:compile(Config,?BER,[]),
- ?line testParamBasic_cases(?BER),
-
- ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
-
- ?line testParamBasic:compile(Config,?PER,[]),
- ?line testParamBasic_cases(?PER),
-
- ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParamBasic_cases(?PER)),
-
- ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParamBasic_cases(uper_bin)),
-
- ?line testParamBasic:compile(Config,?PER,[optimize]),
- ?line testParamBasic_cases(?PER).
-
-
-testParamBasic_cases(Rules) ->
- ?line testParamBasic:main(Rules).
-
-testSetExtension(suite) -> [];
-testSetExtension(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExtension:compile(Config,?BER,[]),
- ?line testSetExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
-
-testSetExtension_cases(Rules) ->
- ?line testSetExtension:main(Rules).
-
-
-testSetExternal(suite) -> [];
-testSetExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExternal:compile(Config,?BER,[]),
- ?line testSetExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
-
-testSetExternal_cases(Rules) ->
- ?line testSetExternal:main(Rules).
-
-
-testSetOptional(suite) -> [];
-testSetOptional(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOptional:compile(Config,?BER,[]),
- ?line testSetOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
-
- ?line testSetOptional:compile(Config,?PER,[]),
- ?line testSetOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOptional_cases(?PER)),
-
- ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOptional_cases(uper_bin)),
-
- ?line testSetOptional:compile(Config,?PER,[optimize]),
- ?line testSetOptional_cases(?PER).
-
-testSetOptional_cases(Rules) ->
- ?line ok = testSetOptional:ticket_7533(Rules),
- ?line ok = testSetOptional:main(Rules).
-
-
-
-
-testSetPrim(suite) -> [];
-testSetPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetPrim:compile(Config,?BER,[]),
- ?line testSetPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
-
- ?line testSetPrim:compile(Config,?PER,[]),
- ?line testSetPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetPrim_cases(uper_bin)),
-
- ?line testSetPrim:compile(Config,?PER,[optimize]),
- ?line testSetPrim_cases(?PER).
-
-testSetPrim_cases(Rules) ->
- ?line testSetPrim:main(Rules).
-
-
-
-testSetTag(suite) -> [];
-testSetTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetTag:compile(Config,?BER,[]),
- ?line testSetTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetTag:compile(Config,?PER,[]),
- ?line testSetTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetTag:compile(Config,?PER,[optimize]),
- ?line testSetTag_cases(?PER).
-
-testSetTag_cases(Rules) ->
- ?line testSetTag:main(Rules).
-
-
-
-testSetTypeRefCho(suite) -> [];
-testSetTypeRefCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefCho:compile(Config,?BER,[]),
- ?line testSetTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[]),
- ?line testSetTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefCho_cases(?PER).
-
-testSetTypeRefCho_cases(Rules) ->
- ?line testSetTypeRefCho:main(Rules).
-
-
-
-testSetTypeRefPrim(suite) -> [];
-testSetTypeRefPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefPrim:compile(Config,?BER,[]),
- ?line testSetTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[]),
- ?line testSetTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefPrim_cases(?PER).
-
-testSetTypeRefPrim_cases(Rules) ->
- ?line testSetTypeRefPrim:main(Rules).
-
-
-
-testSetTypeRefSeq(suite) -> [];
-testSetTypeRefSeq(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSeq:compile(Config,?BER,[]),
- ?line testSetTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[]),
- ?line testSetTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSeq_cases(?PER).
-
-testSetTypeRefSeq_cases(Rules) ->
- ?line testSetTypeRefSeq:main(Rules).
-
-
-
-testSetTypeRefSet(suite) -> [];
-testSetTypeRefSet(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSet:compile(Config,?BER,[]),
- ?line testSetTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[]),
- ?line testSetTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSet_cases(?PER).
-
-testSetTypeRefSet_cases(Rules) ->
- ?line testSetTypeRefSet:main(Rules).
-
-
-
-testSetOf(suite) -> [];
-testSetOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOf:compile(Config,?BER,[]),
- ?line testSetOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
-
- ?line testSetOf:compile(Config,?PER,[]),
- ?line testSetOf_cases(?PER),
-
- ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOf_cases(?PER)),
-
- ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOf_cases(uper_bin)),
-
- ?line testSetOf:compile(Config,?PER,[optimize]),
- ?line testSetOf_cases(?PER).
-
-testSetOf_cases(Rules) ->
- ?line testSetOf:main(Rules).
-
-
-
-testSetOfCho(suite) -> [];
-testSetOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOfCho:compile(Config,?BER,[]),
- ?line testSetOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
-
- ?line testSetOfCho:compile(Config,?PER,[]),
- ?line testSetOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
-
- ?line testSetOfCho:compile(Config,?PER,[optimize]),
- ?line testSetOfCho_cases(?PER).
-
-testSetOfCho_cases(Rules) ->
- ?line testSetOfCho:main(Rules).
-
-
-testSetOfExternal(suite) -> [];
-testSetOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal_cases(?PER).
-
-testSetOfExternal_cases(Rules) ->
- ?line testSetOfExternal:main(Rules).
-
-
-
-
-testSetOfTag(suite) -> [];
-testSetOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfTag:compile(Config,?BER,[]),
- ?line testSetOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfTag:compile(Config,?PER,[]),
- ?line testSetOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfTag:compile(Config,?PER,[optimize]),
- ?line testSetOfTag_cases(?PER).
-
-testSetOfTag_cases(Rules) ->
- ?line testSetOfTag:main(Rules).
-
-
-c_syntax(suite) -> [];
-c_syntax(Config) ->
- ?line DataDir% ?line testExternal:compile(Config,?PER),
-% ?line testPrimExternal:compile(Config,?PER),
-% ?line testPrimExternal_cases(?PER).
- = ?config(data_dir,Config),
- ?line _TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
- ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment1")),
- ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment2")),
- ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
- "BadValueSet")),
- ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
- "ChoiceBadExtension")),
- ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
- "EnumerationBadExtension")),
- ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
- "Example")),
- ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
- "Export1")),
- ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
- "MissingEnd")),
- ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComma")),
- ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentName")),
- ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentType")),
- ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
- "SeqBadComma")).
-
-
-c_string_per(suite) -> [];
-c_string_per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
-
-c_string_ber(suite) -> [];
-c_string_ber(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
-
-
-c_implicit_before_choice(suite) -> [];
-c_implicit_before_choice(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
-
-parse(suite) -> [];
-parse(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- M1 = test_modules(),
-% M2 = parse_modules(),
- ?line ok = parse1(M1,DataDir,OutDir).
-
-parse1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
- parse1(T,DataDir,OutDir);
-parse1([],_,_) ->
- ok.
-
-per(suite) -> [];
-per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = per1(per_modules(),DataDir,OutDir),
- ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
- ?line ok = per1_opt(per_modules(),DataDir,OutDir).
-
-
-per1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1(T,DataDir,OutDir);
-per1([],_,_) ->
- ok.
-
-per1_bit_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_bit_opt(T,DataDir,OutDir);
-per1_bit_opt([],_,_) ->
- ok.
-
-per1_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_opt(T,DataDir,OutDir);
-per1_opt([],_,_) ->
- ok.
-
-
-ber_choiceinseq(suite) ->[];
-ber_choiceinseq(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
-
-ber_optional(suite) ->[];
-ber_optional(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
- ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(V,element(2,V2)).
-
-ber_optional_keyed_list(suite) ->[];
-ber_optional_keyed_list(Config) ->
- case ?BER of
- ber_bin_v2 -> ok;
- _ ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
- [?BER,keyed_list,{outdir,OutDir}]),
- ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line V = [ {a,[{scriptKey,10}]},
- {b,[]},
- {c,[{callingPartysCategory,111}]} ],
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(Vrecord,element(2,V2))
- end.
-
-
-eq(V,V) ->
- ok.
-
-
-ber_other(suite) ->[];
-ber_other(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = ber1(ber_modules(),DataDir,OutDir).
-
-
-ber1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- ber1(T,DataDir,OutDir);
-ber1([],_,_) ->
- ok.
-
-default_per(suite) ->[];
-default_per(Config) ->
- default1(?PER,Config,[]).
-
-default_per_opt(suite) -> [];
-default_per_opt(Config) ->
- ?per_bit_opt(default1(?PER,Config,[optimize])),
- default1(?PER,Config,[optimize]).
-
-default_ber(suite) ->[];
-default_ber(Config) ->
- default1(?BER,Config,[]).
-
-default1(Rule,Config,Options) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
- ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
- bool1 = true,
- bool2 = true,
- bool3 = true}),
- ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
-
- ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
-
-
-value_test(suite) ->[];
-value_test(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = test_bad_values:tests(Config),
- ok.
-
-
-constructed(suite) ->
- [];
-constructed(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
- ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
- ?line [40,3,1,1,0] = lists:flatten(B),
- ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
- ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
- ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
- ?line [136,1,10] = lists:flatten(B2),
- ok.
-
-ber_decode_error(suite) -> [];
-ber_decode_error(Config) ->
- ?line ok = ber_decode_error:compile(Config,?BER,[]),
- ?line ok = ber_decode_error:run([]),
-
- ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
- ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
- ok.
-
-h323test(suite) ->
- [];
-h323test(Config) ->
- ?line ok = h323test:compile(Config,?PER,[]),
- ?line ok = h323test:run(?PER),
- ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(h323test:run(?PER)),
- ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
- ?line ?uper_bin(h323test:run(uper_bin)),
- ?line ok = h323test:compile(Config,?PER,[optimize]),
- ?line ok = h323test:run(?PER),
- ok.
-
-per_GeneralString(suite) ->
- [];
-per_GeneralString(Config) ->
- case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
- true ->
- ok;
- false ->
- h323test:compile(Config,?PER,[])
- end,
- UI = [109,64,1,57],
- ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
- 'MultimediaSystemControlMessage',UI).
-
-per_open_type(suite) ->
- [];
-per_open_type(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
- Stype = {'Stype',10,true},
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
-
- ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}])),
- ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
- [uper_bin,{outdir,OutDir}])),
- ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}]),
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
-
-testConstraints(suite) ->
- [];
-testConstraints(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testConstraints:compile(Config,?BER,[]),
- ?line testConstraints:int_constraints(?BER),
-
- ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
-
- ?line testConstraints:compile(Config,?PER,[]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER),
-
- ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
- ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
-
- ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
- ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
-
- ?line testConstraints:compile(Config,?PER,[optimize]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER).
-
-testSeqIndefinite(suite) -> [];
-testSeqIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqIndefinite:compile(Config,?BER,[]),
- ?line testSeqIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
-
-testSetIndefinite(suite) -> [];
-testSetIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetIndefinite:compile(Config,?BER,[]),
- ?line testSetIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
-
-testChoiceIndefinite(suite) -> [];
-testChoiceIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testChoiceIndefinite:compile(Config,?BER,[]),
- ?line testChoiceIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
-
-testInfObjectClass(suite) ->
- [];
-testInfObjectClass(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testInfObjectClass:compile(Config,?PER,[]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[]),
- ?line testInfObj:main(?PER),
-
- ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
- ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObj:main(?PER)),
-
- ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
- ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObj:main(uper_bin)),
-
- ?line testInfObjectClass:compile(Config,?PER,[optimize]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[optimize]),
- ?line testInfObj:main(?PER),
-
- ?line testInfObjectClass:compile(Config,?BER,[]),
- ?line testInfObjectClass:main(?BER),
- ?line testInfObj:compile(Config,?BER,[]),
- ?line testInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
- ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObj:main(?BER)),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
-
- ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
-
- ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
-
- ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
-
-testParameterizedInfObj(suite) ->
- [];
-testParameterizedInfObj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
-
- ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line testParameterizedInfObj:compile(Config,?BER,[]),
- ?line testParameterizedInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
-
-testMergeCompile(suite) ->
- [];
-testMergeCompile(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMergeCompile:compile(Config,?PER,[]),
- ?line testMergeCompile:main(?PER),
- ?line testMergeCompile:mvrasn(?PER),
-
- ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testMergeCompile:main(?PER)),
- ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
-
- ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testMergeCompile:main(uper_bin)),
- ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
-
- ?line testMergeCompile:compile(Config,?BER,[]),
- ?line testMergeCompile:main(?BER),
- ?line testMergeCompile:mvrasn(?BER),
-
- ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
- ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
-
-testobj(suite) ->
- [];
-testobj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = testRANAP:compile(Config,?PER,[]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
- ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
-
- ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
- ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
-
- ?line ok = testRANAP:compile(Config,?PER,[optimize]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ok = testRANAP:compile(Config,?BER,[]),
- ?line ok = testRANAP:testobj(?BER),
- ?line ok = testParameterizedInfObj:ranap(?BER),
-
- ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
- ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
-
-
-testDeepTConstr(suite) ->
- [];
-testDeepTConstr(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDeepTConstr:compile(Config,?PER,[]),
- ?line testDeepTConstr:main(?PER),
-
- ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
-
- ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
-
- ?line testDeepTConstr:compile(Config,?PER,[optimize]),
- ?line testDeepTConstr:main(?PER),
-
- ?line testDeepTConstr:compile(Config,?BER,[]),
- ?line testDeepTConstr:main(?BER),
-
- ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
-
-testInvokeMod(suite) ->
- [];
-testInvokeMod(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
- ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
- ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
-
-testExport(suite) ->
- [];
-testExport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
-
-testImport(suite) ->
- [];
-testImport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line _OutDir = ?config(priv_dir,Config),
- ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
- ok.
-
-testMegaco(suite) ->
- [];
-testMegaco(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
- io:format("Config: ~p~n",[Config]),
- ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
- ?line ok = testMegaco:main(ModuleName1,Config),
- ?line ok = testMegaco:main(ModuleName2,Config),
-
- case ?BER of
- ber_bin_v2 ->
- ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
- ?line ok = testMegaco:main(ModuleName3,Config),
- ?line ok = testMegaco:main(ModuleName4,Config);
- _-> ok
- end,
-
- ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
- ?line ok = testMegaco:main(ModuleName5,Config),
- ?line ok = testMegaco:main(ModuleName6,Config),
-
- ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
- ?line ok = testMegaco:main(ModuleName7,Config),
- ?line ok = testMegaco:main(ModuleName8,Config).
-
-
-testMvrasn6(suite) -> [];
-testMvrasn6(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMvrasn6:compile(Config,?BER),
- ?line testMvrasn6:main().
-
-testContextSwitchingTypes(suite) -> [];
-testContextSwitchingTypes(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testContextSwitchingTypes:compile(Config,?BER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testContextSwitchingTypes:test()),
-
- ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
- ?line testContextSwitchingTypes:test().
-
-testTypeValueNotation(suite) -> [];
-testTypeValueNotation(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- case ?BER of
- Ber when Ber == ber; Ber == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?BER,[]),
- ?line testTypeValueNotation:main(?BER,dummy);
- _ ->
- ok
- end,
-
- ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
-
- case ?BER of
- Ber2 when Ber2 == ber; Ber2 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[]),
- ?line testTypeValueNotation:main(?PER,dummy);
- _ ->
- ok
- end,
-
- ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
-
- ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
- case ?BER of
- Ber3 when Ber3 == ber; Ber3 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
- ?line testTypeValueNotation:main(?PER,optimize);
- _ ->
- ok
- end.
-
-testOpenTypeImplicitTag(suite) -> [];
-testOpenTypeImplicitTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
- ?line testOpenTypeImplicitTag:main(?BER),
-
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
- ?line testOpenTypeImplicitTag:main(?PER),
-
- ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
-
- ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
- ?line testOpenTypeImplicitTag:main(?PER).
-
-duplicate_tags(suite) -> [];
-duplicate_tags(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
- asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
- ok.
-
-rtUI(suite) -> [];
-rtUI(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:unload_driver().
-
-testROSE(suite) -> [];
-testROSE(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testROSE:compile(Config,?BER,[]),
-
- ?line testROSE:compile(Config,?PER,[]),
- ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
- ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
- ?line testROSE:compile(Config,?PER,[optimize]).
-
-testINSTANCE_OF(suite) -> [];
-testINSTANCE_OF(Config) ->
- ?line testINSTANCE_OF:compile(Config,?BER,[]),
- ?line testINSTANCE_OF:main(?BER),
-
- ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[]),
- ?line testINSTANCE_OF:main(?PER),
-
- ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
-
- ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
- ?line testINSTANCE_OF:main(?PER).
-
-testTCAP(suite) -> [];
-testTCAP(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testTCAP:compile(Config,?BER,[]),
- ?line testTCAP:test(?BER,Config),
-
- ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
-
- ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
- ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
-
-testDER(suite) ->[];
-testDER(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDER:compile(Config,?BER,[]),
- ?line testDER:test(),
-
- ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDER:test()),
-
- ?line testParamBasic:compile_der(Config,?BER),
- ?line testParamBasic_cases(der),
-
-
- ?line testSeqSetDefaultVal:compile(Config,?BER),
- ?line testSeqSetDefaultVal_cases(?BER).
-
-testSeqSetDefaultVal_cases(?BER) ->
- ?line testSeqSetDefaultVal:main(?BER).
-
-
-specialized_decodes(suite) -> [];
-specialized_decodes(Config) ->
- ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
- ?line test_partial_incomplete_decode:test(?BER,Config),
- ?line test_selective_decode:test(?BER,Config).
-
-special_decode_performance(suite) ->[];
-special_decode_performance(Config) ->
- ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
- ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
-
-
-test_driver_load(suite) -> [];
-test_driver_load(Config) ->
- ?line test_driver_load:compile(Config,?PER),
- ?line test_driver_load:test(?PER,5).
-
-test_ParamTypeInfObj(suite) -> [];
-test_ParamTypeInfObj(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
-
-test_WS_ParamClass(suite) -> [];
-test_WS_ParamClass(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
- [ber_bin]).
-
-test_Defed_ObjectIdentifier(suite) -> [];
-test_Defed_ObjectIdentifier(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
- [ber_bin]).
-
-testSelectionType(suite) -> [];
-testSelectionType(Config) ->
-
- ?line ok = testSelectionTypes:compile(Config,?BER,[]),
- ?line {ok,_} = testSelectionTypes:test(),
-
- ?line ok = testSelectionTypes:compile(Config,?PER,[]),
- ?line {ok,_} = testSelectionTypes:test().
-
-testSSLspecs(suite) -> [];
-testSSLspecs(Config) ->
-
- ?line ok = testSSLspecs:compile(Config,?BER,
- [optimize,compact_bit_string,der]),
- ?line testSSLspecs:run(?BER),
-
- case code:which(asn1ct) of
- cover_compiled ->
- ok;
- _ ->
- ?line ok = testSSLspecs:compile_inline(Config,?BER),
- ?line ok = testSSLspecs:run_inline(?BER)
- end.
-
-testNortel(suite) -> [];
-testNortel(Config) ->
- ?line DataDir = ?config(data_dir,Config),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize,driver]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
- ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize])),
- ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize]).
-test_undecoded_rest(suite) -> [];
-test_undecoded_rest(Config) ->
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
- ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
- ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest).
-
-test_inline(suite) -> [];
-test_inline(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok=test_inline:compile(Config,?BER,[]),
- ?line test_inline:main(?BER),
- ?line test_inline:inline1(Config,?BER,[]),
- ?line test_inline:performance2()
- end.
-
-%test_inline_prf(suite) -> [];
-%test_inline_prf(Config) ->
-% ?line test_inline:performance(Config).
-
-testTcapsystem(suite) -> [];
-testTcapsystem(Config) ->
- ?line ok=testTcapsystem:compile(Config,?BER,[]).
-
-testNBAPsystem(suite) -> [];
-testNBAPsystem(Config) ->
- ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
- ?line ok=testNBAPsystem:test(?PER,Config).
-
-test_compile_options(suite) -> [];
-test_compile_options(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok = test_compile_options:wrong_path(Config),
- ?line ok = test_compile_options:path(Config),
- ?line ok = test_compile_options:noobj(Config),
- ?line ok = test_compile_options:record_name_prefix(Config),
- ?line ok = test_compile_options:verbose(Config)
- end.
-testDoubleEllipses(suite) -> [];
-testDoubleEllipses(Config) ->
- ?line testDoubleEllipses:compile(Config,?BER,[]),
- ?line testDoubleEllipses:main(?BER),
- ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
- ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
- ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
- ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
- ?line testDoubleEllipses:main(?PER).
-
-test_modified_x420(suite) -> [];
-test_modified_x420(Config) ->
- ?line test_modified_x420:compile(Config),
- ?line test_modified_x420:test_io(Config).
-
-testX420(suite) -> [];
-testX420(Config) ->
- ?line testX420:compile(?BER,[der],Config),
- ?line ok = testX420:ticket7759(?BER,Config),
- ?line testX420:compile(?PER,[],Config).
-
-test_x691(suite) -> [];
-test_x691(Config) ->
- case ?PER of
- per ->
- ?line ok = test_x691:compile(Config,uper_bin,[]),
- ?line true = test_x691:cases(uper_bin,unaligned),
- ?line ok = test_x691:compile(Config,?PER,[]),
- ?line true = test_x691:cases(?PER,aligned),
-%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
- ?line ok = asn1_test_lib:ticket_7708(Config,[]),
- ?line ok = asn1_test_lib:ticket_7763(Config);
- _ ->
- ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
- ?line true = test_x691:cases(?PER,aligned)
- end.
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
-
-
-ticket_6143(suite) -> [];
-ticket_6143(Config) ->
- ?line ok = test_compile_options:ticket_6143(Config).
-
-testExtensionAdditionGroup(suite) -> [];
-testExtensionAdditionGroup(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line PrivDir = ?config(priv_dir,Config),
- ?line Path = code:get_path(),
- ?line code:add_patha(PrivDir),
- DoIt = fun(Erule) ->
- ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
- ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
- ?line ok = extensionAdditionGroup:run(Erule)
- end,
- ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
- ?line code:set_path(Path).
-
-
-
-% parse_modules() ->
-% ["ImportsFrom"].
-
-per_modules() ->
- [X || X <- test_modules()].
-ber_modules() ->
- [X || X <- test_modules(),
- X =/= "CommonDataTypes",
- X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- X =/= "H323-MESSAGES",
- X =/= "H235-SECURITY-MESSAGES",
- X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
-test_modules() ->
- _Modules = [
- "BitStr",
- "CommonDataTypes",
- "Constraints",
- "ContextSwitchingTypes",
- "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- "Enum",
- "From",
- "H235-SECURITY-MESSAGES",
- "H323-MESSAGES",
- %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
- "Import",
- "Int",
- "MAP-commonDataTypes",
-% ambigous tags "MAP-insertSubscriberData-def",
- "Null",
- "Octetstr",
- "One",
- "P-Record",
- "P",
-% "PDUs",
- "Person",
- "PrimStrings",
- "Real",
- "XSeq",
- "XSeqOf",
- "XSet",
- "XSetOf",
- "String",
- "SwCDR",
-% "Syntax",
- "Time"
-% ANY "Tst",
-% "Two",
-% errors that should be detected "UndefType"
-] ++
- [
- "SeqSetLib", % must be compiled before Seq and Set
- "Seq",
- "Set",
- "SetOf",
- "SeqOf",
- "Prim",
- "Cho",
- "Def",
- "Opt",
- "ELDAPv3",
- "LDAP"
- ].
-
-
-common() ->
-[].
-
-particular() ->
-[].
diff --git a/lib/asn1/test/asn1_bin_v2_SUITE.erl b/lib/asn1/test/asn1_bin_v2_SUITE.erl
deleted file mode 100644
index 2273ca9918..0000000000
--- a/lib/asn1/test/asn1_bin_v2_SUITE.erl
+++ /dev/null
@@ -1,2474 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%% Purpose : Test suite for the ASN.1 application
-
--module(asn1_bin_v2_SUITE).
--define(PER,'per_bin').
--define(BER,'ber_bin_v2').
--define(ber_driver(Erule,Func),
- case Erule of
- ber_bin_v2 ->
- Func;
- _ -> ok
- end).
--define(per_optimize(Erule),
- case Erule of
- ber_bin_v2 ->[optimize];
- _ -> []
- end).
--define(per_bit_opt(FuncCall),
- case ?BER of
- ber_bin_v2 -> FuncCall;
-% _ -> {skip,"only for bit optimized per_bin"}
- _ -> ok
- end).
--define(uper_bin(FuncCall),
- case ?PER of
- per -> FuncCall;
- _ -> ok
- end).
-
--compile(export_all).
-%%-export([Function/Arity, ...]).
-
--include_lib("test_server/include/test_server.hrl").
-
-%% records used by test-case default
--record('Def1',{
-bool0, bool1 = asn1_DEFAULT, bool2 = asn1_DEFAULT, bool3 = asn1_DEFAULT}).
-
-%-record('Def2',{
-%bool10, bool11 = asn1_DEFAULT, bool12 = asn1_DEFAULT, bool13}).
-
-%-record('Def3',{
-%bool30 = asn1_DEFAULT, bool31 = asn1_DEFAULT, bool32 = asn1_DEFAULT, bool33 = asn1_DEFAULT}).
-
-
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- [{group, compile}, parse, default_per, default_ber,
- default_per_opt, per, {group, ber}, testPrim,
- testPrimStrings, testPrimExternal, testChoPrim,
- testChoExtension, testChoExternal, testChoOptional,
- testChoOptionalImplicitTag, testChoRecursive,
- testChoTypeRefCho, testChoTypeRefPrim,
- testChoTypeRefSeq, testChoTypeRefSet, testDef, testOpt,
- testSeqDefault, testSeqExtension, testSeqExternal,
- testSeqOptional, testSeqPrim, testSeqTag,
- testSeqTypeRefCho, testSeqTypeRefPrim,
- testSeqTypeRefSeq, testSeqTypeRefSet, testSeqOf,
- testSeqOfIndefinite, testSeqOfCho, testSeqOfExternal,
- testSetDefault, testSetExtension,
- testExtensionAdditionGroup, testSetExternal,
- testSeqOfTag, testSetOptional, testSetPrim, testSetTag,
- testSetTypeRefCho, testSetTypeRefPrim,
- testSetTypeRefSeq, testSetTypeRefSet, testSetOf,
- testSetOfCho, testSetOfExternal, testSetOfTag,
- testEnumExt, value_test, testSeq2738, constructed,
- ber_decode_error, h323test, testSeqIndefinite,
- testSetIndefinite, testChoiceIndefinite,
- per_GeneralString, per_open_type, testInfObjectClass,
- testParameterizedInfObj, testMergeCompile, testobj,
- testDeepTConstr, testConstraints, testInvokeMod,
- testExport, testImport, testCompactBitString,
- testMegaco, testParamBasic, testMvrasn6,
- testContextSwitchingTypes, testTypeValueNotation,
- testOpenTypeImplicitTag, duplicate_tags, rtUI, testROSE,
- testINSTANCE_OF, testTCAP, testDER, specialized_decodes,
- special_decode_performance, test_driver_load,
- test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier, testSelectionType,
- testSSLspecs, testNortel, test_undecoded_rest,
- test_inline, testTcapsystem, testNBAPsystem,
- test_compile_options, testDoubleEllipses,
- test_modified_x420, testX420, test_x691, ticket_6143,
- testExtensionAdditionGroup] ++ common() ++ particular().
-
-groups() ->
- [{option_tests, [],
- [test_compile_options, ticket_6143]},
- {infobj, [],
- [testInfObjectClass, testParameterizedInfObj,
- testMergeCompile, testobj, testDeepTConstr]},
- {performance, [],
- [testTimer_ber, testTimer_ber_opt_driver, testTimer_per,
- testTimer_per_opt, testTimer_uper_bin]},
- {bugs, [],
- [test_ParamTypeInfObj, test_WS_ParamClass,
- test_Defed_ObjectIdentifier]},
- {compile, [],
- [c_syntax, c_string_per, c_string_ber,
- c_implicit_before_choice]},
- {ber, [],
- [ber_choiceinseq, ber_optional, ber_optional_keyed_list,
- ber_other]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-%all(suite) -> [test_inline,testNBAPsystem,test_compile_options,ticket_6143].
-
-init_per_testcase(Func,Config) ->
- %%?line test_server:format("Func: ~p~n",[Func]),
- ?line {ok, _} = file:read_file_info(filename:join([?config(priv_dir,Config)])),
- ?line code:add_patha(?config(priv_dir,Config)),
- Dog=
- case Func of
- testX420 ->
- test_server:timetrap({minutes,60}); % 60 minutes
- _ ->
- test_server:timetrap({minutes,30}) % 60 minutes
- end,
- %% Dog=test_server:timetrap(1800000), % 30 minutes
- [{watchdog, Dog}|Config].
-
-end_per_testcase(_Func,Config) ->
- Dog=?config(watchdog, Config),
- test_server:timetrap_cancel(Dog).
-
-
-testPrim(suite) -> [];
-testPrim(Config) ->
- ?line testPrim:compile(Config,?BER,[]),
- ?line testPrim_cases(?BER),
- ?line ?ber_driver(?BER,testPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrim_cases(?BER)),
- ?line testPrim:compile(Config,?PER,[]),
- ?line testPrim_cases(?PER),
- ?line ?per_bit_opt(testPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrim_cases(?PER)),
- ?line ?uper_bin(testPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrim_cases(uper_bin)),
- ?line testPrim:compile(Config,?PER,[optimize]),
- ?line testPrim_cases(?PER).
-
-testPrim_cases(Rules) ->
- ?line testPrim:bool(Rules),
- ?line testPrim:int(Rules),
- ?line testPrim:enum(Rules),
- ?line testPrim:obj_id(Rules),
- ?line testPrim:rel_oid(Rules),
- ?line testPrim:null(Rules),
- ?line testPrim:real(Rules).
-
-
-testCompactBitString(suite) -> [];
-testCompactBitString(Config) ->
-
- ?line testCompactBitString:compile(Config,?BER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?BER),
-
- ?line ?ber_driver(?BER,testCompactBitString:compile(Config,?BER,[compact_bit_string,driver])),
- ?line ?ber_driver(?BER,testCompactBitString:compact_bit_string(?BER)),
-
- ?line testCompactBitString:compile(Config,?PER,[compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line ?per_bit_opt(testCompactBitString:compile(Config,?PER,
- [compact_bit_string,optimize])),
- ?line ?per_bit_opt(testCompactBitString:compact_bit_string(?PER)),
- ?line ?per_bit_opt(testCompactBitString:bit_string_unnamed(?PER)),
- ?line ?per_bit_opt(testCompactBitString:ticket_7734(?PER)),
-
- ?line ?uper_bin(testCompactBitString:compile(Config,uper_bin,
- [compact_bit_string])),
- ?line ?uper_bin(testCompactBitString:compact_bit_string(uper_bin)),
- ?line ?uper_bin(testCompactBitString:bit_string_unnamed(uper_bin)),
-
- ?line testCompactBitString:compile(Config,?PER,[optimize,compact_bit_string]),
- ?line testCompactBitString:compact_bit_string(?PER),
- ?line testCompactBitString:bit_string_unnamed(?PER),
-
- ?line testCompactBitString:otp_4869(?PER).
-
-
-testPrimStrings(suite) -> [];
-testPrimStrings(Config) ->
-
- ?line testPrimStrings:compile(Config,?BER,[]),
- ?line testPrimStrings_cases(?BER),
- ?line testPrimStrings:more_strings(?BER), %% these are not implemented in per yet
- ?line ?ber_driver(?BER,testPrimStrings:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimStrings_cases(?BER)),
- ?line ?ber_driver(?BER,testPrimStrings:more_strings(?BER)),
-
- ?line testPrimStrings:compile(Config,?PER,[]),
- ?line testPrimStrings_cases(?PER),
-
- ?line ?per_bit_opt(testPrimStrings:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimStrings_cases(?PER)),
-
- ?line ?uper_bin(testPrimStrings:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimStrings_cases(uper_bin)),
-
- ?line testPrimStrings:compile(Config,?PER,[optimize]),
- ?line testPrimStrings_cases(?PER).
-
-testPrimStrings_cases(Rules) ->
- ?line testPrimStrings:bit_string(Rules),
- ?line testPrimStrings:bit_string_unnamed(Rules),
- ?line testPrimStrings:octet_string(Rules),
- ?line testPrimStrings:numeric_string(Rules),
- ?line testPrimStrings:other_strings(Rules),
- ?line testPrimStrings:universal_string(Rules),
- ?line testPrimStrings:bmp_string(Rules),
- ?line testPrimStrings:times(Rules),
- ?line testPrimStrings:utf8_string(Rules).
-
-
-
-testPrimExternal(suite) -> [];
-testPrimExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testPrimExternal:compile(Config,?BER,[]),
- ?line testPrimExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testPrimExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testPrimExternal:compile(Config,?PER,[]),
- ?line testPrimExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testPrimExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testPrimExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal:compile(Config,?PER,[optimize]),
- ?line testPrimExternal_cases(?PER).
-
-testPrimExternal_cases(Rules) ->
- ?line testPrimExternal:external(Rules).
-
-
-
-
-testChoPrim(suite) -> [];
-testChoPrim(Config) ->
-
- ?line testChoPrim:compile(Config,?BER,[]),
- ?line testChoPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoPrim_cases(?BER)),
-
- ?line testChoPrim:compile(Config,?PER,[]),
- ?line testChoPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoPrim_cases(uper_bin)),
-
- ?line testChoPrim:compile(Config,?PER,[optimize]),
- ?line testChoPrim_cases(?PER).
-
-testChoPrim_cases(Rules) ->
- ?line testChoPrim:bool(Rules),
- ?line testChoPrim:int(Rules).
-
-
-
-testChoExtension(suite) -> [];
-testChoExtension(Config) ->
-
- ?line testChoExtension:compile(Config,?BER,[]),
- ?line testChoExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExtension_cases(?BER)),
-
- ?line testChoExtension:compile(Config,?PER,[]),
- ?line testChoExtension_cases(?PER),
-
- ?line ?per_bit_opt(testChoExtension:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExtension_cases(?PER)),
-
- ?line ?uper_bin(testChoExtension:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExtension_cases(uper_bin)),
-
- ?line testChoExtension:compile(Config,?PER,[optimize]),
- ?line testChoExtension_cases(?PER).
-
-testChoExtension_cases(Rules) ->
- ?line testChoExtension:extension(Rules).
-
-
-
-testChoExternal(suite) -> [];
-testChoExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testChoExternal:compile(Config,?BER,[]),
- ?line testChoExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testChoExternal:compile(Config,?PER,[]),
- ?line testChoExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal:compile(Config,?PER,[optimize]),
- ?line testChoExternal_cases(?PER).
-
-
-testChoExternal_cases(Rules) ->
- ?line testChoExternal:external(Rules).
-
-
-
-testChoOptional(suite) -> [];
-testChoOptional(Config) ->
-
- ?line testChoOptional:compile(Config,?BER,[]),
- ?line testChoOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoOptional_cases(?BER)),
-
- ?line testChoOptional:compile(Config,?PER,[]),
- ?line testChoOptional_cases(?PER),
-
- ?line ?per_bit_opt(testChoOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoOptional_cases(?PER)),
-
- ?line ?uper_bin(testChoOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoOptional_cases(uper_bin)),
-
- ?line testChoOptional:compile(Config,?PER,[optimize]),
- ?line testChoOptional_cases(?PER).
-
-testChoOptional_cases(Rules) ->
- ?line testChoOptional:optional(Rules).
-
-testChoOptionalImplicitTag(suite) -> [];
-testChoOptionalImplicitTag(Config) ->
- %% Only meaningful for ?BER
- ?line testChoOptionalImplicitTag:compile(Config,?BER),
- ?line testChoOptionalImplicitTag:optional(?BER).
-
-
-testChoRecursive(suite) -> [];
-testChoRecursive(Config) ->
-
- ?line testChoRecursive:compile(Config,?BER,[]),
- ?line testChoRecursive_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoRecursive:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoRecursive_cases(?BER)),
-
- ?line testChoRecursive:compile(Config,?PER,[]),
- ?line testChoRecursive_cases(?PER),
-
- ?line ?per_bit_opt(testChoRecursive:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoRecursive_cases(?PER)),
-
- ?line ?uper_bin(testChoRecursive:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoRecursive_cases(uper_bin)),
-
- ?line testChoRecursive:compile(Config,?PER,[optimize]),
- ?line testChoRecursive_cases(?PER).
-
-testChoRecursive_cases(Rules) ->
- ?line testChoRecursive:recursive(Rules).
-
-
-
-testChoTypeRefCho(suite) -> [];
-testChoTypeRefCho(Config) ->
-
- ?line testChoTypeRefCho:compile(Config,?BER,[]),
- ?line testChoTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefCho_cases(?BER)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[]),
- ?line testChoTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefCho_cases(uper_bin)),
-
- ?line testChoTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefCho_cases(?PER).
-
-testChoTypeRefCho_cases(Rules) ->
- ?line testChoTypeRefCho:choice(Rules).
-
-
-
-testChoTypeRefPrim(suite) -> [];
-testChoTypeRefPrim(Config) ->
-
- ?line testChoTypeRefPrim:compile(Config,?BER,[]),
- ?line testChoTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefPrim_cases(?BER)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[]),
- ?line testChoTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefPrim_cases(uper_bin)),
-
- ?line testChoTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefPrim_cases(?PER).
-
-testChoTypeRefPrim_cases(Rules) ->
- ?line testChoTypeRefPrim:prim(Rules).
-
-
-
-testChoTypeRefSeq(suite) -> [];
-testChoTypeRefSeq(Config) ->
-
- ?line testChoTypeRefSeq:compile(Config,?BER,[]),
- ?line testChoTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSeq_cases(?BER)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[]),
- ?line testChoTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSeq_cases(uper_bin)),
-
- ?line testChoTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSeq_cases(?PER).
-
-testChoTypeRefSeq_cases(Rules) ->
- ?line testChoTypeRefSeq:seq(Rules).
-
-
-
-testChoTypeRefSet(suite) -> [];
-testChoTypeRefSet(Config) ->
-
- ?line testChoTypeRefSet:compile(Config,?BER,[]),
- ?line testChoTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testChoTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoTypeRefSet_cases(?BER)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[]),
- ?line testChoTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testChoTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testChoTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testChoTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testChoTypeRefSet_cases(uper_bin)),
-
- ?line testChoTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testChoTypeRefSet_cases(?PER).
-
-testChoTypeRefSet_cases(Rules) ->
- ?line testChoTypeRefSet:set(Rules).
-
-
-
-testDef(suite) -> [];
-testDef(Config) ->
-
- ?line testDef:compile(Config,?BER,[]),
- ?line testDef_cases(?BER),
-
- ?line ?ber_driver(?BER,testDef:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDef_cases(?BER)),
-
- ?line testDef:compile(Config,?PER,[]),
- ?line testDef_cases(?PER),
-
- ?line ?per_bit_opt(testDef:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDef_cases(?PER)),
-
- ?line ?uper_bin(testDef:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDef_cases(uper_bin)),
-
- ?line testDef:compile(Config,?PER,[optimize]),
- ?line testDef_cases(?PER).
-
-testDef_cases(Rules) ->
- ?line testDef:main(Rules).
-
-
-
-testOpt(suite) -> [];
-testOpt(Config) ->
-
- ?line testOpt:compile(Config,?BER),
- ?line testOpt_cases(?BER),
-
- ?line testOpt:compile(Config,?PER),
- ?line testOpt_cases(?PER).
-
-testOpt_cases(Rules) ->
- ?line testOpt:main(Rules).
-
-
-testEnumExt(suite) -> [];
-testEnumExt(Config) ->
-
- ?line testEnumExt:compile(Config,?BER,[]),
- ?line testEnumExt:main(?BER),
-
- ?line ?ber_driver(?BER,testEnumExt:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testEnumExt:main(?BER)),
-
- ?line testEnumExt:compile(Config,?PER,[]),
- ?line testEnumExt:main(?PER),
-
- ?line ?per_bit_opt(testEnumExt:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testEnumExt:main(?PER)),
-
- ?line ?uper_bin(testEnumExt:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testEnumExt:main(uper_bin)),
-
- ?line testEnumExt:compile(Config,?PER,[optimize]),
- ?line testEnumExt:main(?PER).
-
-testSeqDefault(doc) -> ["Test of OTP-2523 ENUMERATED with extensionmark."];
-testSeqDefault(suite) -> [];
-testSeqDefault(Config) ->
-
- ?line testSeqDefault:compile(Config,?BER,[]),
- ?line testSeqDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqDefault_cases(?BER)),
-
- ?line testSeqDefault:compile(Config,?PER,[]),
- ?line testSeqDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSeqDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqDefault_cases(?PER)),
-
- ?line ?uper_bin(testSeqDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqDefault_cases(uper_bin)),
-
- ?line testSeqDefault:compile(Config,?PER,[optimize]),
- ?line testSeqDefault_cases(?PER).
-
-testSeqDefault_cases(Rules) ->
- ?line testSeqDefault:main(Rules).
-
-
-
-testSeqExtension(suite) -> [];
-testSeqExtension(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExtension:compile(Config,?BER,[]),
- ?line testSeqExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExtension_cases(?BER)).
-
-testSeqExtension_cases(Rules) ->
- ?line testSeqExtension:main(Rules).
-
-
-
-testSeqExternal(suite) -> [];
-testSeqExternal(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqExternal:compile(Config,?BER,[]),
- ?line testSeqExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqExternal_cases(?BER)).
-
-testSeqExternal_cases(Rules) ->
- ?line testSeqExternal:main(Rules).
-
-
-testSeqOptional(suite) -> [];
-testSeqOptional(Config) ->
-
- ?line testSeqOptional:compile(Config,?BER,[]),
- ?line testSeqOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOptional_cases(?BER)),
-
- ?line testSeqOptional:compile(Config,?PER,[]),
- ?line testSeqOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOptional_cases(?PER)),
-
- ?line ?uper_bin(testSeqOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOptional_cases(uper_bin)),
-
- ?line testSeqOptional:compile(Config,?PER,[optimize]),
- ?line testSeqOptional_cases(?PER).
-
-testSeqOptional_cases(Rules) ->
- ?line testSeqOptional:main(Rules).
-
-
-
-testSeqPrim(suite) -> [];
-testSeqPrim(Config) ->
-
- ?line testSeqPrim:compile(Config,?BER,[]),
- ?line testSeqPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqPrim_cases(?BER)),
-
- ?line testSeqPrim:compile(Config,?PER,[]),
- ?line testSeqPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqPrim_cases(uper_bin)),
-
- ?line testSeqPrim:compile(Config,?PER,[optimize]),
- ?line testSeqPrim_cases(?PER).
-
-testSeqPrim_cases(Rules) ->
- ?line testSeqPrim:main(Rules).
-
-
-testSeq2738(doc) -> ["Test of OTP-2738 Detect corrupt optional component."];
-testSeq2738(suite) -> [];
-testSeq2738(Config) ->
-
- ?line testSeq2738:compile(Config,?BER,[]),
- ?line testSeq2738_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeq2738:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeq2738_cases(?BER)),
-
- ?line testSeq2738:compile(Config,?PER,[]),
- ?line testSeq2738_cases(?PER),
-
- ?line ?per_bit_opt(testSeq2738:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeq2738_cases(?PER)),
-
- ?line ?uper_bin(testSeq2738:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeq2738_cases(uper_bin)),
-
- ?line testSeq2738:compile(Config,?PER,[optimize]),
- ?line testSeq2738_cases(?PER).
-
-testSeq2738_cases(Rules) ->
- ?line testSeq2738:main(Rules).
-
-
-testSeqTag(suite) -> [];
-testSeqTag(Config) ->
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqTag:compile(Config,?BER,[]),
- ?line testSeqTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqTag:compile(Config,?PER,[]),
- ?line testSeqTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqTag:compile(Config,?PER,[optimize]),
- ?line testSeqTag_cases(?PER).
-
-testSeqTag_cases(Rules) ->
- ?line testSeqTag:main(Rules).
-
-
-
-
-testSeqTypeRefCho(suite) -> [];
-testSeqTypeRefCho(Config) ->
-
- ?line testSeqTypeRefCho:compile(Config,?BER,[]),
- ?line testSeqTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefCho_cases(?BER)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[]),
- ?line testSeqTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefCho_cases(uper_bin)),
-
- ?line testSeqTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefCho_cases(?PER).
-
-testSeqTypeRefCho_cases(Rules) ->
- ?line testSeqTypeRefCho:main(Rules).
-
-
-
-testSeqTypeRefPrim(suite) -> [];
-testSeqTypeRefPrim(Config) ->
-
- ?line testSeqTypeRefPrim:compile(Config,?BER,[]),
- ?line testSeqTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefPrim_cases(?BER)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[]),
- ?line testSeqTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefPrim_cases(uper_bin)),
-
- ?line testSeqTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefPrim_cases(?PER).
-
-testSeqTypeRefPrim_cases(Rules) ->
- ?line testSeqTypeRefPrim:main(Rules).
-
-
-
-testSeqTypeRefSeq(suite) -> [];
-testSeqTypeRefSeq(Config) ->
-
- ?line testSeqTypeRefSeq:compile(Config,?BER,[]),
- ?line testSeqTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSeq_cases(?BER)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[]),
- ?line testSeqTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSeq_cases(uper_bin)),
-
- ?line testSeqTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSeq_cases(?PER).
-
-testSeqTypeRefSeq_cases(Rules) ->
- ?line testSeqTypeRefSeq:main(Rules).
-
-
-
-testSeqTypeRefSet(suite) -> [];
-testSeqTypeRefSet(Config) ->
-
- ?line testSeqTypeRefSet:compile(Config,?BER,[]),
- ?line testSeqTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqTypeRefSet_cases(?BER)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[]),
- ?line testSeqTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSeqTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSeqTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqTypeRefSet_cases(uper_bin)),
-
- ?line testSeqTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSeqTypeRefSet_cases(?PER).
-
-testSeqTypeRefSet_cases(Rules) ->
- ?line testSeqTypeRefSet:main(Rules).
-
-
-
-
-testSeqOf(suite) -> [];
-testSeqOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOf:compile(Config,?BER,[]),
- ?line testSeqOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOf_cases(?BER)),
-
- ?line testSeqOf:compile(Config,?PER,[]),
- ?line testSeqOf_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOf_cases(?PER)),
-
- ?line ?uper_bin(testSeqOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOf_cases(uper_bin)),
-
- ?line testSeqOf:compile(Config,?PER,[optimize]),
- ?line testSeqOf_cases(?PER).
-
-testSeqOf_cases(Rules) ->
- ?line testSeqOf:main(Rules).
-
-
-
-
-testSeqOfCho(suite) -> [];
-testSeqOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfCho:compile(Config,?BER,[]),
- ?line testSeqOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSeqOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfCho_cases(?BER)),
-
- ?line testSeqOfCho:compile(Config,?PER,[]),
- ?line testSeqOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSeqOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSeqOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfCho_cases(uper_bin)),
-
- ?line testSeqOfCho:compile(Config,?PER,[optimize]),
- ?line testSeqOfCho_cases(?PER).
-
-testSeqOfIndefinite(suite) -> [];
-testSeqOfIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqOfIndefinite:compile(Config,?BER,[]),
- ?line testSeqOfIndefinite:main(),
-
- ?line ?ber_driver(?BER,testSeqOfIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfIndefinite:main()).
-
-testSeqOfCho_cases(Rules) ->
- ?line testSeqOfCho:main(Rules).
-
-
-testSeqOfExternal(suite) -> [];
-testSeqOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal:compile(Config,?BER,[]),
- ?line testSeqOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal:compile(Config,?PER,[]),
- ?line testSeqOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfExternal_cases(?PER).
-
-testSeqOfExternal_cases(Rules) ->
- ?line testSeqOfExternal:main(Rules).
-
-
-
-testSeqOfTag(suite) -> [];
-testSeqOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSeqOfTag:compile(Config,?BER,[]),
- ?line testSeqOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSeqOfTag:compile(Config,?PER,[]),
- ?line testSeqOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSeqOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSeqOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag:compile(Config,?PER,[optimize]),
- ?line testSeqOfTag_cases(?PER).
-
-testSeqOfTag_cases(Rules) ->
- ?line testSeqOfTag:main(Rules).
-
-
-
-
-testSetDefault(suite) -> [];
-testSetDefault(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetDefault:compile(Config,?BER,[]),
- ?line testSetDefault_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetDefault:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetDefault_cases(?BER)),
-
- ?line testSetDefault:compile(Config,?PER,[]),
- ?line testSetDefault_cases(?PER),
-
- ?line ?per_bit_opt(testSetDefault:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetDefault_cases(?PER)),
-
- ?line ?uper_bin(testSetDefault:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetDefault_cases(uper_bin)),
-
- ?line testSetDefault:compile(Config,?PER,[optimize]),
- ?line testSetDefault_cases(?PER).
-
-testSetDefault_cases(Rules) ->
- ?line testSetDefault:main(Rules).
-
-
-testParamBasic(suite) -> [];
-testParamBasic(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParamBasic:compile(Config,?BER,[]),
- ?line testParamBasic_cases(?BER),
-
- ?line ?ber_driver(?BER,testParamBasic:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParamBasic_cases(?BER)),
-
- ?line testParamBasic:compile(Config,?PER,[]),
- ?line testParamBasic_cases(?PER),
-
- ?line ?per_bit_opt(testParamBasic:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParamBasic_cases(?PER)),
-
- ?line ?uper_bin(testParamBasic:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParamBasic_cases(uper_bin)),
-
- ?line testParamBasic:compile(Config,?PER,[optimize]),
- ?line testParamBasic_cases(?PER).
-
-
-testParamBasic_cases(Rules) ->
- ?line testParamBasic:main(Rules).
-
-testSetExtension(suite) -> [];
-testSetExtension(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExtension:compile(Config,?BER,[]),
- ?line testSetExtension_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExtension_cases(?BER)).
-
-testSetExtension_cases(Rules) ->
- ?line testSetExtension:main(Rules).
-
-
-testSetExternal(suite) -> [];
-testSetExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetExternal:compile(Config,?BER,[]),
- ?line testSetExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetExternal_cases(?BER)).
-
-testSetExternal_cases(Rules) ->
- ?line testSetExternal:main(Rules).
-
-
-testSetOptional(suite) -> [];
-testSetOptional(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOptional:compile(Config,?BER,[]),
- ?line testSetOptional_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOptional:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOptional_cases(?BER)),
-
- ?line testSetOptional:compile(Config,?PER,[]),
- ?line testSetOptional_cases(?PER),
-
- ?line ?per_bit_opt(testSetOptional:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOptional_cases(?PER)),
-
- ?line ?uper_bin(testSetOptional:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOptional_cases(uper_bin)),
-
- ?line testSetOptional:compile(Config,?PER,[optimize]),
- ?line testSetOptional_cases(?PER).
-
-testSetOptional_cases(Rules) ->
- ?line ok = testSetOptional:ticket_7533(Rules),
- ?line ok = testSetOptional:main(Rules).
-
-
-
-
-testSetPrim(suite) -> [];
-testSetPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetPrim:compile(Config,?BER,[]),
- ?line testSetPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetPrim_cases(?BER)),
-
- ?line testSetPrim:compile(Config,?PER,[]),
- ?line testSetPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetPrim_cases(uper_bin)),
-
- ?line testSetPrim:compile(Config,?PER,[optimize]),
- ?line testSetPrim_cases(?PER).
-
-testSetPrim_cases(Rules) ->
- ?line testSetPrim:main(Rules).
-
-
-
-testSetTag(suite) -> [];
-testSetTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetTag:compile(Config,?BER,[]),
- ?line testSetTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetTag:compile(Config,?PER,[]),
- ?line testSetTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetTag:compile(Config,?PER,[optimize]),
- ?line testSetTag_cases(?PER).
-
-testSetTag_cases(Rules) ->
- ?line testSetTag:main(Rules).
-
-
-
-testSetTypeRefCho(suite) -> [];
-testSetTypeRefCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefCho:compile(Config,?BER,[]),
- ?line testSetTypeRefCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefCho_cases(?BER)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[]),
- ?line testSetTypeRefCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefCho_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefCho_cases(uper_bin)),
-
- ?line testSetTypeRefCho:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefCho_cases(?PER).
-
-testSetTypeRefCho_cases(Rules) ->
- ?line testSetTypeRefCho:main(Rules).
-
-
-
-testSetTypeRefPrim(suite) -> [];
-testSetTypeRefPrim(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefPrim:compile(Config,?BER,[]),
- ?line testSetTypeRefPrim_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefPrim:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefPrim_cases(?BER)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[]),
- ?line testSetTypeRefPrim_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefPrim:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefPrim_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefPrim:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefPrim_cases(uper_bin)),
-
- ?line testSetTypeRefPrim:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefPrim_cases(?PER).
-
-testSetTypeRefPrim_cases(Rules) ->
- ?line testSetTypeRefPrim:main(Rules).
-
-
-
-testSetTypeRefSeq(suite) -> [];
-testSetTypeRefSeq(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSeq:compile(Config,?BER,[]),
- ?line testSetTypeRefSeq_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSeq:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSeq_cases(?BER)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[]),
- ?line testSetTypeRefSeq_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSeq:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSeq_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSeq:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSeq_cases(uper_bin)),
-
- ?line testSetTypeRefSeq:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSeq_cases(?PER).
-
-testSetTypeRefSeq_cases(Rules) ->
- ?line testSetTypeRefSeq:main(Rules).
-
-
-
-testSetTypeRefSet(suite) -> [];
-testSetTypeRefSet(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetTypeRefSet:compile(Config,?BER,[]),
- ?line testSetTypeRefSet_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetTypeRefSet:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetTypeRefSet_cases(?BER)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[]),
- ?line testSetTypeRefSet_cases(?PER),
-
- ?line ?per_bit_opt(testSetTypeRefSet:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetTypeRefSet_cases(?PER)),
-
- ?line ?uper_bin(testSetTypeRefSet:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetTypeRefSet_cases(uper_bin)),
-
- ?line testSetTypeRefSet:compile(Config,?PER,[optimize]),
- ?line testSetTypeRefSet_cases(?PER).
-
-testSetTypeRefSet_cases(Rules) ->
- ?line testSetTypeRefSet:main(Rules).
-
-
-
-testSetOf(suite) -> [];
-testSetOf(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOf:compile(Config,?BER,[]),
- ?line testSetOf_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOf:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOf_cases(?BER)),
-
- ?line testSetOf:compile(Config,?PER,[]),
- ?line testSetOf_cases(?PER),
-
- ?line ?per_bit_opt(testSetOf:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOf_cases(?PER)),
-
- ?line ?uper_bin(testSetOf:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOf_cases(uper_bin)),
-
- ?line testSetOf:compile(Config,?PER,[optimize]),
- ?line testSetOf_cases(?PER).
-
-testSetOf_cases(Rules) ->
- ?line testSetOf:main(Rules).
-
-
-
-testSetOfCho(suite) -> [];
-testSetOfCho(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetOfCho:compile(Config,?BER,[]),
- ?line testSetOfCho_cases(?BER),
-
- ?line ?ber_driver(?BER,testSetOfCho:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfCho_cases(?BER)),
-
- ?line testSetOfCho:compile(Config,?PER,[]),
- ?line testSetOfCho_cases(?PER),
-
- ?line ?per_bit_opt(testSetOfCho:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfCho_cases(?PER)),
-
- ?line ?uper_bin(testSetOfCho:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfCho_cases(uper_bin)),
-
- ?line testSetOfCho:compile(Config,?PER,[optimize]),
- ?line testSetOfCho_cases(?PER).
-
-testSetOfCho_cases(Rules) ->
- ?line testSetOfCho:main(Rules).
-
-
-testSetOfExternal(suite) -> [];
-testSetOfExternal(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal:compile(Config,?BER,[]),
- ?line testSetOfExternal_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfExternal_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal:compile(Config,?PER,[]),
- ?line testSetOfExternal_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfExternal_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfExternal_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfExternal_cases(?PER).
-
-testSetOfExternal_cases(Rules) ->
- ?line testSetOfExternal:main(Rules).
-
-
-
-
-testSetOfTag(suite) -> [];
-testSetOfTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testExternal:compile(Config,?BER,[]),
- ?line testSetOfTag:compile(Config,?BER,[]),
- ?line testSetOfTag_cases(?BER),
-
- ?line ?ber_driver(?BER,testExternal:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetOfTag_cases(?BER)),
-
- ?line testExternal:compile(Config,?PER,[]),
- ?line testSetOfTag:compile(Config,?PER,[]),
- ?line testSetOfTag_cases(?PER),
-
- ?line ?per_bit_opt(testExternal:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testSetOfTag_cases(?PER)),
-
- ?line ?uper_bin(testExternal:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testSetOfTag_cases(uper_bin)),
-
- ?line testExternal:compile(Config,?PER,[optimize]),
- ?line testSetOfTag:compile(Config,?PER,[optimize]),
- ?line testSetOfTag_cases(?PER).
-
-testSetOfTag_cases(Rules) ->
- ?line testSetOfTag:main(Rules).
-
-
-c_syntax(suite) -> [];
-c_syntax(Config) ->
- ?line DataDir% ?line testExternal:compile(Config,?PER),
-% ?line testPrimExternal:compile(Config,?PER),
-% ?line testPrimExternal_cases(?PER).
- = ?config(data_dir,Config),
- ?line _TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line {error,_R1} = asn1ct:compile(filename:join(DataDir,"Syntax")),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"BadTypeEnding")),
- ?line {error,_R3} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment1")),
- ?line {error,_R4} = asn1ct:compile(filename:join(DataDir,
- "BadValueAssignment2")),
- ?line {error,_R5} = asn1ct:compile(filename:join(DataDir,
- "BadValueSet")),
- ?line {error,_R6} = asn1ct:compile(filename:join(DataDir,
- "ChoiceBadExtension")),
- ?line {error,_R7} = asn1ct:compile(filename:join(DataDir,
- "EnumerationBadExtension")),
- ?line {error,_R8} = asn1ct:compile(filename:join(DataDir,
- "Example")),
- ?line {error,_R9} = asn1ct:compile(filename:join(DataDir,
- "Export1")),
- ?line {error,_R10} = asn1ct:compile(filename:join(DataDir,
- "MissingEnd")),
- ?line {error,_R11} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComma")),
- ?line {error,_R12} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentName")),
- ?line {error,_R13} = asn1ct:compile(filename:join(DataDir,
- "SequenceBadComponentType")),
- ?line {error,_R14} = asn1ct:compile(filename:join(DataDir,
- "SeqBadComma")).
-
-
-c_string_per(suite) -> [];
-c_string_per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?PER,{outdir,TempDir}]).
-
-c_string_ber(suite) -> [];
-c_string_ber(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"String"),[?BER,{outdir,TempDir}]).
-
-
-c_implicit_before_choice(suite) -> [];
-c_implicit_before_choice(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line TempDir = ?config(priv_dir,Config),
- ?line {error,_R2} = asn1ct:compile(filename:join(DataDir,"CCSNARG3"),[?BER,{outdir,TempDir}]).
-
-parse(suite) -> [];
-parse(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- M1 = test_modules(),
-% M2 = parse_modules(),
- ?line ok = parse1(M1,DataDir,OutDir).
-
-parse1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[abs,{outdir,OutDir}]),
- parse1(T,DataDir,OutDir);
-parse1([],_,_) ->
- ok.
-
-per(suite) -> [];
-per(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = per1(per_modules(),DataDir,OutDir),
- ?line ?per_bit_opt(per1_bit_opt(per_modules(),DataDir,OutDir)),
- ?line ok = per1_opt(per_modules(),DataDir,OutDir).
-
-
-per1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1(T,DataDir,OutDir);
-per1([],_,_) ->
- ok.
-
-per1_bit_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimize,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_bit_opt(T,DataDir,OutDir);
-per1_bit_opt([],_,_) ->
- ok.
-
-per1_opt([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?PER,optimized,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- per1_opt(T,DataDir,OutDir);
-per1_opt([],_,_) ->
- ok.
-
-
-ber_choiceinseq(suite) ->[];
-ber_choiceinseq(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"ChoiceInSeq"),[?BER,{outdir,OutDir}]).
-
-ber_optional(suite) ->[];
-ber_optional(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),[?BER,{outdir,OutDir}]),
- ?line V = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(V,element(2,V2)).
-
-ber_optional_keyed_list(suite) ->[];
-ber_optional_keyed_list(Config) ->
- case ?BER of
- ber_bin_v2 -> ok;
- _ ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(filename:join(DataDir,"SOpttest"),
- [?BER,keyed_list,{outdir,OutDir}]),
- ?line Vrecord = {'S',{'A',10,asn1_NOVALUE,asn1_NOVALUE},
- {'B',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE},
- {'C',asn1_NOVALUE,111,asn1_NOVALUE}},
- ?line V = [ {a,[{scriptKey,10}]},
- {b,[]},
- {c,[{callingPartysCategory,111}]} ],
- ?line {ok,B} = asn1_wrapper:encode('SOpttest','S',V),
- ?line Bytes = lists:flatten(B),
- ?line V2 = asn1_wrapper:decode('SOpttest','S',Bytes),
- ?line ok = eq(Vrecord,element(2,V2))
- end.
-
-
-eq(V,V) ->
- ok.
-
-
-ber_other(suite) ->[];
-ber_other(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = ber1(ber_modules(),DataDir,OutDir).
-
-
-ber1([M|T],DataDir,OutDir) ->
- ?line ok = asn1ct:compile(DataDir ++ M,[?BER,{outdir,OutDir}]),
- ?line ok = asn1ct:test(list_to_atom(M)),
- ber1(T,DataDir,OutDir);
-ber1([],_,_) ->
- ok.
-
-default_per(suite) ->[];
-default_per(Config) ->
- default1(?PER,Config,[]).
-
-default_per_opt(suite) -> [];
-default_per_opt(Config) ->
- ?per_bit_opt(default1(?PER,Config,[optimize])),
- default1(?PER,Config,[optimize]).
-
-default_ber(suite) ->[];
-default_ber(Config) ->
- default1(?BER,Config,[]).
-
-default1(Rule,Config,Options) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Def",[Rule,{outdir,OutDir}]++Options),
- ?line {ok,Bytes1} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,
- bool1 = true,
- bool2 = true,
- bool3 = true}),
- ?line {ok,{'Def1',true,true,true,true}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes1)),
-
- ?line {ok,Bytes2} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes2)),
-
- ?line {ok,Bytes3} = asn1_wrapper:encode('Def','Def1',#'Def1'{bool0 = true,bool2=false}),
- ?line {ok,{'Def1',true,false,false,false}} = asn1_wrapper:decode('Def','Def1',lists:flatten(Bytes3)).
-
-
-value_test(suite) ->[];
-value_test(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?BER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = asn1ct:compile(DataDir ++ "ObjIdValues",[?PER,{outdir,OutDir}]),
- ?line {ok,_} = asn1_wrapper:encode('ObjIdValues','ObjIdType','ObjIdValues':'mobileDomainId'()),
- ?line ok = test_bad_values:tests(Config),
- ok.
-
-
-constructed(suite) ->
- [];
-constructed(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
- ?line ok = asn1ct:compile(DataDir ++ "Constructed",[?BER,{outdir,OutDir}]),
- ?line {ok,B} = asn1_wrapper:encode('Constructed','S',{'S',false}),
- ?line [40,3,1,1,0] = lists:flatten(B),
- ?line {ok,B1} = asn1_wrapper:encode('Constructed','S2',{'S2',false}),
- ?line [40,5,48,3,1,1,0] = lists:flatten(B1),
- ?line {ok,B2} = asn1_wrapper:encode('Constructed','I',10),
- ?line [136,1,10] = lists:flatten(B2),
- ok.
-
-ber_decode_error(suite) -> [];
-ber_decode_error(Config) ->
- ?line ok = ber_decode_error:compile(Config,?BER,[]),
- ?line ok = ber_decode_error:run([]),
-
- ?line ok = ?ber_driver(?BER,ber_decode_error:compile(Config,?BER,[driver])),
- ?line ok = ?ber_driver(?BER,ber_decode_error:run([driver])),
- ok.
-
-h323test(suite) ->
- [];
-h323test(Config) ->
- ?line ok = h323test:compile(Config,?PER,[]),
- ?line ok = h323test:run(?PER),
- ?line ?per_bit_opt(h323test:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(h323test:run(?PER)),
- ?line ?uper_bin(h323test:compile(Config,uper_bin,[])),
- ?line ?uper_bin(h323test:run(uper_bin)),
- ?line ok = h323test:compile(Config,?PER,[optimize]),
- ?line ok = h323test:run(?PER),
- ok.
-
-per_GeneralString(suite) ->
- [];
-per_GeneralString(Config) ->
- case erlang:module_loaded('MULTIMEDIA-SYSTEM-CONTROL') of
- true ->
- ok;
- false ->
- h323test:compile(Config,?PER,[])
- end,
- UI = [109,64,1,57],
- ?line {ok,_V} = asn1_wrapper:decode('MULTIMEDIA-SYSTEM-CONTROL',
- 'MultimediaSystemControlMessage',UI).
-
-per_open_type(suite) ->
- [];
-per_open_type(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",[?PER,{outdir,OutDir}]),
- Stype = {'Stype',10,true},
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes),
-
- ?line ?per_bit_opt(ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}])),
- ?line ?per_bit_opt({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?per_bit_opt({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ?uper_bin(ok = asn1ct:compile(DataDir ++ "OpenType",
- [uper_bin,{outdir,OutDir}])),
- ?line ?uper_bin({ok,Bytes}=asn1_wrapper:encode('OpenType','Ot',Stype)),
- ?line ?uper_bin({ok,Stype}=asn1_wrapper:decode('OpenType','Ot',Bytes)),
-
- ?line ok = asn1ct:compile(DataDir ++ "OpenType",
- [?PER,optimize,{outdir,OutDir}]),
- ?line {ok,Bytes} = asn1_wrapper:encode('OpenType','Ot',Stype),
- ?line {ok,Stype} = asn1_wrapper:decode('OpenType','Ot',Bytes).
-
-testConstraints(suite) ->
- [];
-testConstraints(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testConstraints:compile(Config,?BER,[]),
- ?line testConstraints:int_constraints(?BER),
-
- ?line ?ber_driver(?BER,testConstraints:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testConstraints:int_constraints(?BER)),
-
- ?line testConstraints:compile(Config,?PER,[]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER),
-
- ?line ?per_bit_opt(testConstraints:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testConstraints:int_constraints(?PER)),
- ?line ?per_bit_opt(testConstraints:refed_NNL_name(?PER)),
-
- ?line ?uper_bin(testConstraints:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testConstraints:int_constraints(uper_bin)),
- ?line ?uper_bin(testConstraints:refed_NNL_name(uper_bin)),
-
- ?line testConstraints:compile(Config,?PER,[optimize]),
- ?line testConstraints:int_constraints(?PER),
- ?line testConstraints:refed_NNL_name(?PER).
-
-testSeqIndefinite(suite) -> [];
-testSeqIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSeqIndefinite:compile(Config,?BER,[]),
- ?line testSeqIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSeqIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSeqIndefinite:main(?BER)).
-
-testSetIndefinite(suite) -> [];
-testSetIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testSetIndefinite:compile(Config,?BER,[]),
- ?line testSetIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testSetIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testSetIndefinite:main(?BER)).
-
-testChoiceIndefinite(suite) -> [];
-testChoiceIndefinite(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testChoiceIndefinite:compile(Config,?BER,[]),
- ?line testChoiceIndefinite:main(?BER),
-
- ?line ?ber_driver(?BER,testChoiceIndefinite:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testChoiceIndefinite:main(?BER)).
-
-testInfObjectClass(suite) ->
- [];
-testInfObjectClass(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testInfObjectClass:compile(Config,?PER,[]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[]),
- ?line testInfObj:main(?PER),
-
- ?line ?per_bit_opt(testInfObjectClass:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObjectClass:main(?PER)),
- ?line ?per_bit_opt(testInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testInfObj:main(?PER)),
-
- ?line ?uper_bin(testInfObjectClass:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObjectClass:main(uper_bin)),
- ?line ?uper_bin(testInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testInfObj:main(uper_bin)),
-
- ?line testInfObjectClass:compile(Config,?PER,[optimize]),
- ?line testInfObjectClass:main(?PER),
- ?line testInfObj:compile(Config,?PER,[optimize]),
- ?line testInfObj:main(?PER),
-
- ?line testInfObjectClass:compile(Config,?BER,[]),
- ?line testInfObjectClass:main(?BER),
- ?line testInfObj:compile(Config,?BER,[]),
- ?line testInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testInfObjectClass:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObjectClass:main(?BER)),
- ?line ?ber_driver(?BER,testInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testInfObj:main(?BER)),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[]),
-
- ?line ?per_bit_opt(testInfObj:compile_RANAPfiles(Config,?PER,[optimize])),
-
- ?line ?uper_bin(testInfObj:compile_RANAPfiles(Config,uper_bin,[])),
-
- ?line testInfObj:compile_RANAPfiles(Config,?PER,[optimize]),
-
- ?line testInfObj:compile_RANAPfiles(Config,?BER,[]).
-
-testParameterizedInfObj(suite) ->
- [];
-testParameterizedInfObj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line ?per_bit_opt(testParameterizedInfObj:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testParameterizedInfObj:main(?PER)),
-
- ?line ?uper_bin(testParameterizedInfObj:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testParameterizedInfObj:main(uper_bin)),
-
- ?line testParameterizedInfObj:compile(Config,?PER,[optimize]),
- ?line testParameterizedInfObj:main(?PER),
-
- ?line testParameterizedInfObj:compile(Config,?BER,[]),
- ?line testParameterizedInfObj:main(?BER),
-
- ?line ?ber_driver(?BER,testParameterizedInfObj:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testParameterizedInfObj:main(?BER)).
-
-testMergeCompile(suite) ->
- [];
-testMergeCompile(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMergeCompile:compile(Config,?PER,[]),
- ?line testMergeCompile:main(?PER),
- ?line testMergeCompile:mvrasn(?PER),
-
- ?line ?per_bit_opt(testMergeCompile:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testMergeCompile:main(?PER)),
- ?line ?per_bit_opt(testMergeCompile:mvrasn(?PER)),
-
- ?line ?uper_bin(testMergeCompile:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testMergeCompile:main(uper_bin)),
- ?line ?uper_bin(testMergeCompile:mvrasn(uper_bin)),
-
- ?line testMergeCompile:compile(Config,?BER,[]),
- ?line testMergeCompile:main(?BER),
- ?line testMergeCompile:mvrasn(?BER),
-
- ?line ?ber_driver(?BER,testMergeCompile:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testMergeCompile:main(?BER)),
- ?line ?ber_driver(?BER,testMergeCompile:mvrasn(?BER)).
-
-testobj(suite) ->
- [];
-testobj(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = testRANAP:compile(Config,?PER,[]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ?per_bit_opt(ok = testRANAP:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testRANAP:testobj(?PER)),
- ?line ?per_bit_opt(ok = testParameterizedInfObj:ranap(?PER)),
-
- ?line ?uper_bin(ok = testRANAP:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testRANAP:testobj(uper_bin)),
- ?line ?uper_bin(ok = testParameterizedInfObj:ranap(uper_bin)),
-
- ?line ok = testRANAP:compile(Config,?PER,[optimize]),
- ?line ok = testRANAP:testobj(?PER),
- ?line ok = testParameterizedInfObj:ranap(?PER),
-
- ?line ok = testRANAP:compile(Config,?BER,[]),
- ?line ok = testRANAP:testobj(?BER),
- ?line ok = testParameterizedInfObj:ranap(?BER),
-
- ?line ?ber_driver(?BER,testRANAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testRANAP:testobj(?BER)),
- ?line ?ber_driver(?BER,testParameterizedInfObj:ranap(?BER)).
-
-
-testDeepTConstr(suite) ->
- [];
-testDeepTConstr(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDeepTConstr:compile(Config,?PER,[]),
- ?line testDeepTConstr:main(?PER),
-
- ?line ?per_bit_opt(testDeepTConstr:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDeepTConstr:main(?PER)),
-
- ?line ?uper_bin(testDeepTConstr:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDeepTConstr:main(uper_bin)),
-
- ?line testDeepTConstr:compile(Config,?PER,[optimize]),
- ?line testDeepTConstr:main(?PER),
-
- ?line testDeepTConstr:compile(Config,?BER,[]),
- ?line testDeepTConstr:main(?BER),
-
- ?line ?ber_driver(?BER,testDeepTConstr:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDeepTConstr:main(?BER)).
-
-testInvokeMod(suite) ->
- [];
-testInvokeMod(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[{outdir,OutDir}]),
- ?line {ok,_Result1} = 'PrimStrings':encode('Bs1',[1,0,1,0]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"PrimStrings"),[?PER,{outdir,OutDir}]),
- ?line {ok,_Result2} = 'PrimStrings':encode('Bs1',[1,0,1,0]).
-
-testExport(suite) ->
- [];
-testExport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line {error,{asn1,_Reason}} = asn1ct:compile(filename:join(DataDir,"IllegalExport"),[{outdir,OutDir}]).
-
-testImport(suite) ->
- [];
-testImport(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line _OutDir = ?config(priv_dir,Config),
- ?line {error,_} = asn1ct:compile(filename:join(DataDir,"ImportsFrom"),[?BER]),
- ok.
-
-testMegaco(suite) ->
- [];
-testMegaco(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
- io:format("Config: ~p~n",[Config]),
- ?line {ok,ModuleName1,ModuleName2} = testMegaco:compile(Config,?BER,[]),
- ?line ok = testMegaco:main(ModuleName1,Config),
- ?line ok = testMegaco:main(ModuleName2,Config),
-
- case ?BER of
- ber_bin_v2 ->
- ?line {ok,ModuleName3,ModuleName4} = testMegaco:compile(Config,?BER,[driver]),
- ?line ok = testMegaco:main(ModuleName3,Config),
- ?line ok = testMegaco:main(ModuleName4,Config);
- _-> ok
- end,
-
- ?line {ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[]),
- ?line ok = testMegaco:main(ModuleName5,Config),
- ?line ok = testMegaco:main(ModuleName6,Config),
-
- ?line ?per_bit_opt({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?per_bit_opt(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line ?uper_bin({ok,ModuleName5,ModuleName6} = testMegaco:compile(Config,uper_bin,[])),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName5,Config)),
- ?line ?uper_bin(ok = testMegaco:main(ModuleName6,Config)),
-
- ?line {ok,ModuleName7,ModuleName8} = testMegaco:compile(Config,?PER,[optimize]),
- ?line ok = testMegaco:main(ModuleName7,Config),
- ?line ok = testMegaco:main(ModuleName8,Config).
-
-
-testMvrasn6(suite) -> [];
-testMvrasn6(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testMvrasn6:compile(Config,?BER),
- ?line testMvrasn6:main().
-
-testContextSwitchingTypes(suite) -> [];
-testContextSwitchingTypes(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testContextSwitchingTypes:compile(Config,?BER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?ber_driver(?BER,testContextSwitchingTypes:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[]),
- ?line testContextSwitchingTypes:test(),
-
- ?line ?per_bit_opt(testContextSwitchingTypes:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testContextSwitchingTypes:test()),
-
- ?line ?uper_bin(testContextSwitchingTypes:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testContextSwitchingTypes:test()),
-
- ?line testContextSwitchingTypes:compile(Config,?PER,[optimize]),
- ?line testContextSwitchingTypes:test().
-
-testTypeValueNotation(suite) -> [];
-testTypeValueNotation(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- case ?BER of
- Ber when Ber == ber; Ber == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?BER,[]),
- ?line testTypeValueNotation:main(?BER,dummy);
- _ ->
- ok
- end,
-
- ?line ?ber_driver(?BER,testTypeValueNotation:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTypeValueNotation:main(?BER,optimize)),
-
- case ?BER of
- Ber2 when Ber2 == ber; Ber2 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[]),
- ?line testTypeValueNotation:main(?PER,dummy);
- _ ->
- ok
- end,
-
- ?line ?per_bit_opt(testTypeValueNotation:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testTypeValueNotation:main(?PER,optimize)),
-
- ?line ?uper_bin(testTypeValueNotation:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testTypeValueNotation:main(uper_bin,optimize)),
- case ?BER of
- Ber3 when Ber3 == ber; Ber3 == ber_bin ->
- ?line testTypeValueNotation:compile(Config,?PER,[optimize]),
- ?line testTypeValueNotation:main(?PER,optimize);
- _ ->
- ok
- end.
-
-testOpenTypeImplicitTag(suite) -> [];
-testOpenTypeImplicitTag(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?BER,[]),
- ?line testOpenTypeImplicitTag:main(?BER),
-
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testOpenTypeImplicitTag:main(?BER)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[]),
- ?line testOpenTypeImplicitTag:main(?PER),
-
- ?line ?per_bit_opt(testOpenTypeImplicitTag:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testOpenTypeImplicitTag:main(?PER)),
-
- ?line ?uper_bin(testOpenTypeImplicitTag:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testOpenTypeImplicitTag:main(uper_bin)),
-
- ?line testOpenTypeImplicitTag:compile(Config,?PER,[optimize]),
- ?line testOpenTypeImplicitTag:main(?PER).
-
-duplicate_tags(suite) -> [];
-duplicate_tags(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- {error,{asn1,[{error,{type,_,_,'SeqOpt1Imp',{asn1,{duplicates_of_the_tags,_}}}}]}} =
- asn1ct:compile(filename:join(DataDir,"SeqOptional2"),[abs]),
- ok.
-
-rtUI(suite) -> [];
-rtUI(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?BER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Prim"),[?PER]),
- ?line {ok,_} = asn1rt:info('Prim'),
-
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:load_driver(),
- ?line ok = asn1rt:unload_driver().
-
-testROSE(suite) -> [];
-testROSE(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testROSE:compile(Config,?BER,[]),
-
- ?line testROSE:compile(Config,?PER,[]),
- ?line ?per_bit_opt(testROSE:compile(Config,?PER,[optimize])),
- ?line ?uper_bin(testROSE:compile(Config,uper_bin,[])),
- ?line testROSE:compile(Config,?PER,[optimize]).
-
-testINSTANCE_OF(suite) -> [];
-testINSTANCE_OF(Config) ->
- ?line testINSTANCE_OF:compile(Config,?BER,[]),
- ?line testINSTANCE_OF:main(?BER),
-
- ?line ?ber_driver(?BER,testINSTANCE_OF:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testINSTANCE_OF:main(?BER)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[]),
- ?line testINSTANCE_OF:main(?PER),
-
- ?line ?per_bit_opt(testINSTANCE_OF:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testINSTANCE_OF:main(?PER)),
-
- ?line ?uper_bin(testINSTANCE_OF:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testINSTANCE_OF:main(uper_bin)),
-
- ?line testINSTANCE_OF:compile(Config,?PER,[optimize]),
- ?line testINSTANCE_OF:main(?PER).
-
-testTCAP(suite) -> [];
-testTCAP(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testTCAP:compile(Config,?BER,[]),
- ?line testTCAP:test(?BER,Config),
-
- ?line ?ber_driver(?BER,testTCAP:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testTCAP:test(?BER,Config)),
-
- ?line ?ber_driver(?BER,testTCAP:compile_asn1config(Config,?BER,[asn1config])),
- ?line ?ber_driver(?BER,testTCAP:test_asn1config()).
-
-testDER(suite) ->[];
-testDER(Config) ->
- ?line true = code:add_patha(?config(priv_dir,Config)),
-
- ?line testDER:compile(Config,?BER,[]),
- ?line testDER:test(),
-
- ?line ?ber_driver(?BER,testDER:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDER:test()),
-
- ?line testParamBasic:compile_der(Config,?BER),
- ?line testParamBasic_cases(der),
-
-
- ?line testSeqSetDefaultVal:compile(Config,?BER),
- ?line testSeqSetDefaultVal_cases(?BER).
-
-testSeqSetDefaultVal_cases(?BER) ->
- ?line testSeqSetDefaultVal:main(?BER).
-
-
-specialized_decodes(suite) -> [];
-specialized_decodes(Config) ->
- ?line test_partial_incomplete_decode:compile(Config,?BER,[optimize]),
- ?line test_partial_incomplete_decode:test(?BER,Config),
- ?line test_selective_decode:test(?BER,Config).
-
-special_decode_performance(suite) ->[];
-special_decode_performance(Config) ->
- ?line ?ber_driver(?BER,test_special_decode_performance:compile(Config,?BER)),
- ?line ?ber_driver(?BER,test_special_decode_performance:go(all)).
-
-
-test_driver_load(suite) -> [];
-test_driver_load(Config) ->
- ?line test_driver_load:compile(Config,?PER),
- ?line test_driver_load:test(?PER,5).
-
-test_ParamTypeInfObj(suite) -> [];
-test_ParamTypeInfObj(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"IN-CS-1-Datatypes"),[ber_bin]).
-
-test_WS_ParamClass(suite) -> [];
-test_WS_ParamClass(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"InformationFramework"),
- [ber_bin]).
-
-test_Defed_ObjectIdentifier(suite) -> [];
-test_Defed_ObjectIdentifier(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line ok = asn1ct:compile(filename:join(DataDir,"UsefulDefinitions"),
- [ber_bin]).
-
-testSelectionType(suite) -> [];
-testSelectionType(Config) ->
-
- ?line ok = testSelectionTypes:compile(Config,?BER,[]),
- ?line {ok,_} = testSelectionTypes:test(),
-
- ?line ok = testSelectionTypes:compile(Config,?PER,[]),
- ?line {ok,_} = testSelectionTypes:test().
-
-testSSLspecs(suite) -> [];
-testSSLspecs(Config) ->
-
- ?line ok = testSSLspecs:compile(Config,?BER,
- [optimize,compact_bit_string,der]),
- ?line testSSLspecs:run(?BER),
-
- case code:which(asn1ct) of
- cover_compiled ->
- ok;
- _ ->
- ?line ok = testSSLspecs:compile_inline(Config,?BER),
- ?line ok = testSSLspecs:run_inline(?BER)
- end.
-
-testNortel(suite) -> [];
-testNortel(Config) ->
- ?line DataDir = ?config(data_dir,Config),
-
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?BER]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?BER,optimize,driver]),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[?PER]),
- ?line ?per_bit_opt(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize])),
- ?line ?uper_bin(ok = asn1ct:compile(filename:join(DataDir,"Nortel"),[uper_bin])),
- ?line ok = asn1ct:compile(filename:join(DataDir,"Nortel"),
- [?PER,optimize]).
-test_undecoded_rest(suite) -> [];
-test_undecoded_rest(Config) ->
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ok = test_undecoded_rest:compile(Config,?BER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[]),
- ?line ok = test_undecoded_rest:test([]),
-
- ?line ?per_bit_opt(ok = test_undecoded_rest:compile(Config,?PER,[optimize,undec_rest])),
- ?line ?per_bit_opt(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ?uper_bin(ok = test_undecoded_rest:compile(Config,uper_bin,[undec_rest])),
- ?line ?uper_bin(ok = test_undecoded_rest:test(undec_rest)),
-
- ?line ok = test_undecoded_rest:compile(Config,?PER,[undec_rest]),
- ?line ok = test_undecoded_rest:test(undec_rest).
-
-test_inline(suite) -> [];
-test_inline(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok=test_inline:compile(Config,?BER,[]),
- ?line test_inline:main(?BER),
- ?line test_inline:inline1(Config,?BER,[]),
- ?line test_inline:performance2()
- end.
-
-%test_inline_prf(suite) -> [];
-%test_inline_prf(Config) ->
-% ?line test_inline:performance(Config).
-
-testTcapsystem(suite) -> [];
-testTcapsystem(Config) ->
- ?line ok=testTcapsystem:compile(Config,?BER,[]).
-
-testNBAPsystem(suite) -> [];
-testNBAPsystem(Config) ->
- ?line ok=testNBAPsystem:compile(Config,?PER,?per_optimize(?BER)),
- ?line ok=testNBAPsystem:test(?PER,Config).
-
-test_compile_options(suite) -> [];
-test_compile_options(Config) ->
- case code:which(asn1ct) of
- cover_compiled ->
- {skip,"Not runnable when cover compiled"};
- _ ->
- ?line ok = test_compile_options:wrong_path(Config),
- ?line ok = test_compile_options:path(Config),
- ?line ok = test_compile_options:noobj(Config),
- ?line ok = test_compile_options:record_name_prefix(Config),
- ?line ok = test_compile_options:verbose(Config)
- end.
-testDoubleEllipses(suite) -> [];
-testDoubleEllipses(Config) ->
- ?line testDoubleEllipses:compile(Config,?BER,[]),
- ?line testDoubleEllipses:main(?BER),
- ?line ?ber_driver(?BER,testDoubleEllipses:compile(Config,?BER,[driver])),
- ?line ?ber_driver(?BER,testDoubleEllipses:main(?BER)),
- ?line ?per_bit_opt(testDoubleEllipses:compile(Config,?PER,[optimize])),
- ?line ?per_bit_opt(testDoubleEllipses:main(?PER)),
- ?line ?uper_bin(testDoubleEllipses:compile(Config,uper_bin,[])),
- ?line ?uper_bin(testDoubleEllipses:main(uper_bin)),
- ?line testDoubleEllipses:compile(Config,?PER,?per_optimize(?BER)),
- ?line testDoubleEllipses:main(?PER).
-
-test_modified_x420(suite) -> [];
-test_modified_x420(Config) ->
- ?line test_modified_x420:compile(Config),
- ?line test_modified_x420:test_io(Config).
-
-testX420(suite) -> [];
-testX420(Config) ->
- ?line testX420:compile(?BER,[der],Config),
- ?line ok = testX420:ticket7759(?BER,Config),
- ?line testX420:compile(?PER,[],Config).
-
-test_x691(suite) -> [];
-test_x691(Config) ->
- case ?PER of
- per ->
- ?line ok = test_x691:compile(Config,uper_bin,[]),
- ?line true = test_x691:cases(uper_bin,unaligned),
- ?line ok = test_x691:compile(Config,?PER,[]),
- ?line true = test_x691:cases(?PER,aligned),
-%% ?line ok = asn1_test_lib:ticket_7678(Config,[]),
- ?line ok = asn1_test_lib:ticket_7708(Config,[]),
- ?line ok = asn1_test_lib:ticket_7763(Config);
- _ ->
- ?line ok = test_x691:compile(Config,?PER,?per_optimize(?BER)),
- ?line true = test_x691:cases(?PER,aligned)
- end.
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[compact_bit_string]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize]),
-%% ?line ok = asn1_test_lib:ticket_7876(Config,?PER,[optimize,compact_bit_string]).
-
-
-ticket_6143(suite) -> [];
-ticket_6143(Config) ->
- ?line ok = test_compile_options:ticket_6143(Config).
-
-testExtensionAdditionGroup(suite) -> [];
-testExtensionAdditionGroup(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line PrivDir = ?config(priv_dir,Config),
- ?line Path = code:get_path(),
- ?line code:add_patha(PrivDir),
- DoIt = fun(Erule) ->
- ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),[Erule,{outdir,PrivDir}]),
- ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]),
- ?line ok = extensionAdditionGroup:run(Erule)
- end,
- ?line [DoIt(Rule)|| Rule <- [per_bin,uper_bin,ber_bin]],
- ?line code:set_path(Path).
-
-
-
-% parse_modules() ->
-% ["ImportsFrom"].
-
-per_modules() ->
- [X || X <- test_modules()].
-ber_modules() ->
- [X || X <- test_modules(),
- X =/= "CommonDataTypes",
- X =/= "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- X =/= "H323-MESSAGES",
- X =/= "H235-SECURITY-MESSAGES",
- X =/= "MULTIMEDIA-SYSTEM-CONTROL"].
-test_modules() ->
- _Modules = [
- "BitStr",
- "CommonDataTypes",
- "Constraints",
- "ContextSwitchingTypes",
- "DS-EquipmentUser-CommonFunctionOrig-TransmissionPath",
- "Enum",
- "From",
- "H235-SECURITY-MESSAGES",
- "H323-MESSAGES",
- %%"MULTIMEDIA-SYSTEM-CONTROL", recursive type , problem for asn1ct:value
- "Import",
- "Int",
- "MAP-commonDataTypes",
-% ambigous tags "MAP-insertSubscriberData-def",
- "Null",
- "Octetstr",
- "One",
- "P-Record",
- "P",
-% "PDUs",
- "Person",
- "PrimStrings",
- "Real",
- "XSeq",
- "XSeqOf",
- "XSet",
- "XSetOf",
- "String",
- "SwCDR",
-% "Syntax",
- "Time"
-% ANY "Tst",
-% "Two",
-% errors that should be detected "UndefType"
-] ++
- [
- "SeqSetLib", % must be compiled before Seq and Set
- "Seq",
- "Set",
- "SetOf",
- "SeqOf",
- "Prim",
- "Cho",
- "Def",
- "Opt",
- "ELDAPv3",
- "LDAP"
- ].
-
-
-common() ->
-[].
-
-particular() ->
-[smp, ticket7904].
-
-
-smp(suite) -> [];
-smp(Config) ->
- case erlang:system_info(smp_support) of
- true ->
- NumOfProcs = erlang:system_info(schedulers),
- io:format("smp starting ~p workers\n",[NumOfProcs]),
-
- ?line Msg = {initiatingMessage, testNBAPsystem:cell_setup_req_msg()},
- ?line ok = testNBAPsystem:compile(Config,per_bin,[optimize]),
-
- Parent = self(),
-
- ?line ok = asn1rt:load_driver(),
-
- smp2(Parent,NumOfProcs,Msg,2),
-
- N = 10000,
-
- ?line {Time1,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
- ?line {Time1S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
-
- ?line ok = testNBAPsystem:compile(Config,ber_bin,[optimize,driver]),
- ?line {Time2,ok} = timer:tc(?MODULE,smp2,[Parent,NumOfProcs,Msg, N]),
-
- ?line {Time2S,ok} = timer:tc(?MODULE,sequential,[NumOfProcs * N,Msg]),
-
- {comment,lists:flatten(io_lib:format("Encode/decode time parallell with ~p cores: ~p [microsecs]~nEncode/decode time sequential: ~p [microsecs]",[NumOfProcs,Time1+Time2,Time1S+Time2S]))};
- false ->
- {skipped,"No smp support"}
- end.
-
-smp2(Parent,NumOfProcs,Msg, N) ->
- Pids = [spawn_link(fun() -> worker(Msg,Parent, N) end)
- || _ <- lists:seq(1,NumOfProcs)],
- ?line ok = wait_pids(Pids).
-
-worker(Msg, Parent, N) ->
- %% io:format("smp worker ~p with ~p worker loops.~n",[self(), N]),
- worker_loop(N, Msg),
- Parent ! self().
-
-worker_loop(0, _Msg) ->
- ok;
-worker_loop(N, Msg) ->
- ?line {ok,B}=asn1_wrapper:encode('NBAP-PDU-Discriptions',
- 'NBAP-PDU',
- Msg),
- ?line {ok,_Msg}=asn1_wrapper:decode('NBAP-PDU-Discriptions',
- 'NBAP-PDU',
- B),
- worker_loop(N - 1, Msg).
-
-
-wait_pids([]) ->
- ok;
-wait_pids(Pids) ->
- receive
- Pid when is_pid(Pid) ->
- ?line true = lists:member(Pid,Pids),
- Others = lists:delete(Pid,Pids),
- io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]),
- wait_pids(Others);
- Err ->
- io:format("Err: ~p~n",[Err]),
- ?line exit(Err)
- end.
-
-sequential(N,Msg) ->
- %%io:format("sequential encode/decode with N = ~p~n",[N]),
- worker_loop(N,Msg).
-
--record('InitiatingMessage',{procedureCode,criticality,value}).
--record('Iu-ReleaseCommand',{first,second}).
-
-ticket7904(suite) -> [];
-ticket7904(Config) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line OutDir = ?config(priv_dir,Config),
-
- ?line ok = asn1ct:compile(DataDir ++
- "RANAPextract1",[per_bin,optimize,{outdir,OutDir}]),
-
- Val1 = #'InitiatingMessage'{procedureCode=1,
- criticality=ignore,
- value=#'Iu-ReleaseCommand'{
- first=13,
- second=true}},
-
- ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1),
- asn1rt:unload_driver(),
- ?line {ok,_} = 'RANAPextract1':encode('InitiatingMessage', Val1).
diff --git a/lib/asn1/test/asn1_common_SUITE.erl.src b/lib/asn1/test/asn1_common_SUITE.erl.src
index 2fa2a09f1f..12512606d8 100644
--- a/lib/asn1/test/asn1_common_SUITE.erl.src
+++ b/lib/asn1/test/asn1_common_SUITE.erl.src
@@ -18,15 +18,12 @@
%%
%%
-common() -> [app_test, appup_test,testTimer_ber,testTimer_ber_bin,
+common() -> [{group,app_test}, {group,appup_test},testTimer_ber,testTimer_ber_bin,
testTimer_ber_bin_opt, testTimer_ber_bin_opt_driver, testTimer_per,
testTimer_per_bin, testTimer_per_bin_opt, testTimer_uper_bin,
testComment,testName2Number].
-app_test(suite) -> [{asn1_app_test,all}].
-appup_test(suite) -> [{asn1_appup_test,all}].
-
testTimer_ber(suite) -> [];
testTimer_ber(Config) ->
?line testTimer:compile(Config,ber,[]),
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index 260a016c6c..7d05e5c352 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -77,7 +77,7 @@ check_EXTERNAL_DVD(asn1_NOVALUE) ->
ok;
check_EXTERNAL_DVD(DVD) ->
{error,"failed on data-value-descriptor alternative",DVD}.
-check_EXTERNAL_DV(DV) when is_list(DV) ->
+check_EXTERNAL_DV(DV) when is_list(DV);is_binary(DV) ->
ok;
check_EXTERNAL_DV(DV) ->
{error,"failed on data-value alternative",DV}.
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index 7b52e18805..36e082c8ba 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,2 +1,2 @@
#next version number to use is 1.6.15 | 1.7 | 2.0
-ASN1_VSN = 1.6.16
+ASN1_VSN = 1.6.17
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 15c7e2a9f2..826b3c598d 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,75 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ It was previously not possible to use timetrap value
+ 'infinity' with ct:timetrap/1. This has been fixed.</p>
+ <p>
+ Own Id: OTP-9159</p>
+ </item>
+ <item>
+ <p>
+ The Common Test VTS mode has been updated to be able to
+ report test results of suites that include test case
+ groups (when it would previously crash).</p>
+ <p>
+ Own Id: OTP-9195</p>
+ </item>
+ <item>
+ <p>
+ Common Test now refreshes the very top level index.html
+ page at the start of each individual test in a test run,
+ so that progress of the ongoing test can be tracked by
+ following the link to its overview page.</p>
+ <p>
+ Own Id: OTP-9210 Aux Id: OTP-9054 </p>
+ </item>
+ <item>
+ <p>
+ A bug that made it impossible to cancel the previous
+ timetrap when calling ct:timetrap/1 has been corrected.</p>
+ <p>
+ Own Id: OTP-9233 Aux Id: OTP-9159 </p>
+ </item>
+ <item>
+ <p>
+ Fix bug which would make cth's to not be removed when out
+ of scope when adding a cth in suite/0 and crashing in
+ pre_init_per_suite.</p>
+ <p>
+ Own Id: OTP-9264</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ It is now possible to return a tuple {fail,Reason} from
+ init_per_testcase/2. The result is that the associated
+ test case gets logged as failed without ever executing.</p>
+ <p>
+ Own Id: OTP-9160 Aux Id: seq11502 </p>
+ </item>
+ <item>
+ <p>
+ Common Test now accepts, but ignores, empty test case
+ group specifications.</p>
+ <p>
+ Own Id: OTP-9161</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.5.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl
index ba4adb8683..b839521e24 100644
--- a/lib/common_test/src/ct_logs.erl
+++ b/lib/common_test/src/ct_logs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl
index 081f98e889..f0bf090804 100644
--- a/lib/common_test/src/vts.erl
+++ b/lib/common_test/src/vts.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
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 40b7d2da47..c4e0d72948 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
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
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 7fcb631d06..a77d06815e 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
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
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 14eb8769ad..154c676d7e 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
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl
index 601d5315ce..31381abc40 100644
--- a/lib/common_test/test/ct_test_support.erl
+++ b/lib/common_test/test/ct_test_support.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index 8a4853e070..f77629b4d1 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1,3 +1,3 @@
-COMMON_TEST_VSN = 1.5.3
+COMMON_TEST_VSN = 1.5.4
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 5757d0c1cb..dd29323787 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -31,6 +31,30 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 4.7.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ If a variable is matched out in binary matching and used
+ as the size for a binary element, it would seem to be
+ unbound if used in a subsequent match operation. (Thanks
+ to Bernard Duggan.)</p>
+ <p>
+ Own Id: OTP-9134</p>
+ </item>
+ <item>
+ <p>Eliminate incorrect warning in
+ <c>sys_core_fold</c></p>
+ <p>
+ Own Id: OTP-9152</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 4.7.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index 5cc8252b99..415864b8e9 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 8e96569414..1365f3d20a 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 9360556e00..6ea67741fa 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index e1a593fffa..87bb5bec25 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index e46096a6df..5863842f5b 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 4.7.3
+COMPILER_VSN = 4.7.4
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
index 95941fefdd..2318ccb6d2 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ConsumerAdmin.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;ConsumerAdmin</title>
- <shorttitle>..._ConsumerAdmin</shorttitle>
+ <title>CosEventChannelAdmin_ConsumerAdmin</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
index 51f9f11613..4495fd4450 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_EventChannel.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;EventChannel</title>
- <shorttitle>..._EventChannel</shorttitle>
+ <title>CosEventChannelAdmin_EventChannel</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
index 9690c9406d..4cd20ad185 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullConsumer.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;ProxyPullConsumer</title>
- <shorttitle>..._ProxyPullConsumer</shorttitle>
+ <title>CosEventChannelAdmin_ProxyPullConsumer</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
index fb17c450f4..830c06a87c 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPullSupplier.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;ProxyPullSupplier</title>
- <shorttitle>..._ProxyPullSupplier</shorttitle>
+ <title>CosEventChannelAdmin_ProxyPullSupplier</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
index 21e6cfce6f..2c451acd9c 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushConsumer.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;ProxyPushConsumer</title>
- <shorttitle>..._ProxyPushConsumer</shorttitle>
+ <title>CosEventChannelAdmin_ProxyPushConsumer</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
index be2dfcafbe..9030c0e735 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_ProxyPushSupplier.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;ProxyPushSupplier</title>
- <shorttitle>..._ProxyPushSupplier</shorttitle>
+ <title>CosEventChannelAdmin_ProxyPushSupplier</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml b/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
index ca301bb860..e68b0854d8 100644
--- a/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
+++ b/lib/cosEvent/doc/src/CosEventChannelAdmin_SupplierAdmin.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventChannelAdmin_&shy;SupplierAdmin</title>
- <shorttitle>..._SupplierAdmin</shorttitle>
+ <title>CosEventChannelAdmin_SupplierAdmin</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/cosEvent/doc/src/notes.xml b/lib/cosEvent/doc/src/notes.xml
index 1a5c8afa17..1da5399755 100644
--- a/lib/cosEvent/doc/src/notes.xml
+++ b/lib/cosEvent/doc/src/notes.xml
@@ -22,8 +22,8 @@
</legalnotice>
<title>cosEvent Release Notes</title>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved></approved>
<checked></checked>
@@ -33,6 +33,23 @@
</header>
<section>
+ <title>cosEvent 2.1.11</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosEvent 2.1.10</title>
<section>
diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk
index 38999db5fa..85d3cf552b 100644
--- a/lib/cosEvent/vsn.mk
+++ b/lib/cosEvent/vsn.mk
@@ -1,3 +1,3 @@
-COSEVENT_VSN = 2.1.10
+COSEVENT_VSN = 2.1.11
diff --git a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
index cf1cdab966..4941f8652c 100644
--- a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
+++ b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomain.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosEventDomainAdmin_&shy;EventDomain</title>
- <shorttitle>..._EventDomain</shorttitle>
+ <title>CosEventDomainAdmin_EventDomain</title>
<prepared></prepared>
<docno></docno>
<approved>Niclas Eklund</approved>
diff --git a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
index ea605f23a0..5eff7038d9 100644
--- a/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
+++ b/lib/cosEventDomain/doc/src/CosEventDomainAdmin_EventDomainFactory.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosEventDomainAdmin_&shy;EventDomainFactory</title>
- <shorttitle>..._EventChannel</shorttitle>
+ <title>CosEventDomainAdmin_EventDomainFactory</title>
<prepared>Niclas Eklund</prepared>
<responsible>Niclas Eklund</responsible>
<docno></docno>
diff --git a/lib/cosEventDomain/doc/src/notes.xml b/lib/cosEventDomain/doc/src/notes.xml
index 522dcea829..585761ce65 100644
--- a/lib/cosEventDomain/doc/src/notes.xml
+++ b/lib/cosEventDomain/doc/src/notes.xml
@@ -32,6 +32,23 @@
</header>
<section>
+ <title>cosEventDomain 1.1.11</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosEventDomain 1.1.10</title>
<section>
diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk
index f4a77ab7a8..7df47cef2e 100644
--- a/lib/cosEventDomain/vsn.mk
+++ b/lib/cosEventDomain/vsn.mk
@@ -1,3 +1,3 @@
-COSEVENTDOMAIN_VSN = 1.1.10
+COSEVENTDOMAIN_VSN = 1.1.11
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
index af9141b205..7c68768aa9 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_Directory.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosFileTransfer_&shy;Directory</title>
- <shorttitle>..._Directory</shorttitle>
+ <title>CosFileTransfer_Directory</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
index bef7cb882f..8b317049e2 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_File.xml
@@ -23,11 +23,10 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosFileTransfer_&shy;File</title>
- <shorttitle>..._File</shorttitle>
+ <title>CosFileTransfer_File</title>
<prepared></prepared>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-11-09</date>
<rev>PA1</rev>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
index c848a9830d..80cbd1f448 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileIterator.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosFileTransfer_&shy;FileIterator</title>
- <shorttitle>..._FileIterator</shorttitle>
+ <title>CosFileTransfer_FileIterator</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
index 5f4542058b..5ac2c61c92 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_FileTransferSession.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosFileTransfer_&shy;FileTransferSession</title>
- <shorttitle>..._FileTransferSession</shorttitle>
+ <title>CosFileTransfer_FileTransferSession</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml b/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
index 8aa02b2153..7bb6e8d356 100644
--- a/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
+++ b/lib/cosFileTransfer/doc/src/CosFileTransfer_VirtualFileSystem.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosFileTransfer_&shy;VirtualFileSystem</title>
- <shorttitle>..._VirtualFileSystem</shorttitle>
+ <title>CosFileTransfer_VirtualFileSystem</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosFileTransfer/doc/src/notes.xml b/lib/cosFileTransfer/doc/src/notes.xml
index 48d0c04236..53c207db2f 100644
--- a/lib/cosFileTransfer/doc/src/notes.xml
+++ b/lib/cosFileTransfer/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,23 @@
</header>
<section>
+ <title>cosFileTransfer 1.1.11</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosFileTransfer 1.1.10</title>
<section>
diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk
index ef8ee53c5e..9d68ab2720 100644
--- a/lib/cosFileTransfer/vsn.mk
+++ b/lib/cosFileTransfer/vsn.mk
@@ -1 +1 @@
-COSFILETRANSFER_VSN = 1.1.10
+COSFILETRANSFER_VSN = 1.1.11
diff --git a/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
index 57015b3621..46c3921b66 100644
--- a/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotification_AdminPropertiesAdmin.xml
@@ -23,10 +23,9 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotification_&shy;AdminPropertiesAdmin</title>
- <shorttitle>..._AdminPropertiesAdmin</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotification_AdminPropertiesAdmin</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved>Niclas Eklund</approved>
<checked></checked>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
index 671f68d482..96ccdf1d29 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ConsumerAdmin.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ConsumerAdmin</title>
- <shorttitle>..._ConsumerAdmin</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ConsumerAdmin</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
index b6af2e2ca3..1682cf9968 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannel.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;EventChannel</title>
- <shorttitle>..._EventChannel</shorttitle>
+ <title>CosNotifyChannelAdmin_EventChannel</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
index 01976954e7..64e0e4dad8 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_EventChannelFactory.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;EventChannelFactory</title>
- <shorttitle>..._EventChannelFactory</shorttitle>
+ <title>CosNotifyChannelAdmin_EventChannelFactory</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
index 8bc182a50c..7ba74547bb 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyConsumer.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxyConsumer</title>
- <shorttitle>..._ProxyConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxyConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
index 43818e5238..d8344e004a 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullConsumer.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxyPullConsumer</title>
- <shorttitle>..._ProxyPullConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxyPullConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
index 4c0aac7ae6..cc2c17a3ca 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPullSupplier.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxyPullSupplier</title>
- <shorttitle>..._ProxyPullSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxyPullSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
index 697d00ea51..30ba264f74 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushConsumer.xml
@@ -23,10 +23,9 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxyPushConsumer</title>
- <shorttitle>..._ProxyPushConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxyPushConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved>Niclas Eklund</approved>
<checked></checked>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
index f6fc3a0f7b..d5079a5ae7 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxyPushSupplier.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxyPushSupplier</title>
- <shorttitle>..._ProxyPushSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxyPushSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
index 81d4de929a..bdd9213a8b 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_ProxySupplier.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;ProxySupplier</title>
- <shorttitle>..._ProxySupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_ProxySupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
index 4084fd443b..86796a2643 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;SequenceProxyPullConsumer</title>
- <shorttitle>..._SequenceProxyPullConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_SequenceProxyPullConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
index 16b093b9aa..c30217362a 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;SequenceProxyPullSupplier</title>
- <shorttitle>..._SequenceProxyPullSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_SequenceProxyPullSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
index 964d212715..3f3e187486 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,15 +21,14 @@
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;SequenceProxyPushConsumer</title>
- <shorttitle>..._SequenceProxyPushConsumer</shorttitle>
+ <title>CosNotifyChannelAdmin_SequenceProxyPushConsumer</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;SequenceProxyPushConsumer</module>
+ <module>CosNotifyChannelAdmin_SequenceProxyPushConsumer</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPushConsumer interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
index f8ce2072e1..f85f33de01 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.xml
@@ -23,17 +23,16 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;SequenceProxyPushSupplier</title>
- <shorttitle>..._SequenceProxyPushSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_SequenceProxyPushSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;SequenceProxyPushSupplier</module>
+ <module>CosNotifyChannelAdmin_SequenceProxyPushSupplier</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::SequenceProxyPushSupplier interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
index 0623d2891b..09546d9584 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.xml
@@ -23,17 +23,16 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;StructuredProxyPullConsumer</title>
- <shorttitle>..._StructuredProxyPullConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_StructuredProxyPullConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;StructuredProxyPullConsumer</module>
+ <module>CosNotifyChannelAdmin_StructuredProxyPullConsumer</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPullConsumer interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
index 0f0bb5d985..d171851014 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.xml
@@ -23,17 +23,16 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;StructuredProxyPullSupplier</title>
- <shorttitle>..._StructuredProxyPullSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_StructuredProxyPullSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;StructuredProxyPullSupplier</module>
+ <module>CosNotifyChannelAdmin_StructuredProxyPullSupplier</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPullSupplier interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
index 7b7a60723e..a055a0ab36 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.xml
@@ -23,17 +23,16 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;StructuredProxyPushConsumer</title>
- <shorttitle>..._StructuredProxyPushConsumer</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_StructuredProxyPushConsumer</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;StructuredProxyPushConsumer</module>
+ <module>CosNotifyChannelAdmin_StructuredProxyPushConsumer</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPushConsumer interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
index ab0a260a4b..f03322b819 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.xml
@@ -23,17 +23,16 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;StructuredProxyPushSupplier</title>
- <shorttitle>..._StructuredProxyPushSupplier</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_StructuredProxyPushSupplier</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
</header>
- <module>CosNotifyChannelAdmin_&shy;StructuredProxyPushSupplier</module>
+ <module>CosNotifyChannelAdmin_StructuredProxyPushSupplier</module>
<modulesummary>This module implements the OMG CosNotifyChannelAdmin::StructuredProxyPushSupplier interface.</modulesummary>
<description>
<p>To get access to the record definitions for the structures use: <br></br>
diff --git a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
index a567463f7d..5c7408040d 100644
--- a/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
+++ b/lib/cosNotification/doc/src/CosNotifyChannelAdmin_SupplierAdmin.xml
@@ -23,10 +23,9 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyChannelAdmin_&shy;SupplierAdmin</title>
- <shorttitle>..._SupplierAdmin</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyChannelAdmin_SupplierAdmin</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved>Niclas Eklund</approved>
<checked></checked>
diff --git a/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
index dd8ef713e8..97b15d958a 100644
--- a/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
+++ b/lib/cosNotification/doc/src/CosNotifyComm_NotifySubscribe.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosNotifyComm_&shy;NotifySubscribe</title>
- <shorttitle>..._NotifySubscribe</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosNotifyComm_NotifySubscribe</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-02-01</date>
<rev>1.0</rev>
diff --git a/lib/cosNotification/doc/src/ch_BNF.xml b/lib/cosNotification/doc/src/ch_BNF.xml
index 73e91e3cac..f658f606d3 100644
--- a/lib/cosNotification/doc/src/ch_BNF.xml
+++ b/lib/cosNotification/doc/src/ch_BNF.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -294,7 +294,7 @@ FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':
</row>
<row>
<cell align="left" valign="middle"><c>in</c></cell>
- <cell align="left" valign="middle"><c>"'Erlang' in $.FunctionalLanguages&shy;StringSeq"</c></cell>
+ <cell align="left" valign="middle"><c>"'Erlang' in $.FunctionalLanguagesStringSeq"</c></cell>
<cell align="left" valign="middle">Returns <c>TRUE</c>if a given element is found in the given sequence. The element must be of a simple type and the same as the sequence is defined to contain.</cell>
</row>
<row>
@@ -394,17 +394,17 @@ Figure 1: The structure of a structured event.</icaption>
</row>
<row>
<cell align="left" valign="middle">type_name</cell>
- <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.type_name == 'Type'"</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_type.type_name == 'Type'"</cell>
<cell align="left" valign="middle">"$type_name == 'Type'"</cell>
</row>
<row>
<cell align="left" valign="middle">domain_name</cell>
- <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;type.domain_name == 'Domain'"</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_type.domain_name == 'Domain'"</cell>
<cell align="left" valign="middle">"$domain_name == 'Domain'"</cell>
</row>
<row>
<cell align="left" valign="middle">event_name</cell>
- <cell align="left" valign="middle">"$.header.fixed_header.event_&shy;name == 'Event'"</cell>
+ <cell align="left" valign="middle">"$.header.fixed_header.event_name == 'Event'"</cell>
<cell align="left" valign="middle">"$event_name == 'Event'"</cell>
</row>
<tcaption>Table 2: Fixed Header Constraint Examples</tcaption>
diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml
index 125e25e67e..a54230c9f7 100644
--- a/lib/cosNotification/doc/src/notes.xml
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -31,6 +31,21 @@
<file>notes.xml</file>
</header>
+ <section><title>cosNotification 1.1.17</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
<section><title>cosNotification 1.1.16</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
index 6613385579..b32919a2ef 100644
--- a/lib/cosNotification/vsn.mk
+++ b/lib/cosNotification/vsn.mk
@@ -1,2 +1,2 @@
-COSNOTIFICATION_VSN = 1.1.16
+COSNOTIFICATION_VSN = 1.1.17
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
index 75c7cb38cb..623e121715 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertiesIterator.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosPropertyService_&shy;PropertiesIterator</title>
- <shorttitle>..._PropertiesIterator</shorttitle>
+ <title>CosPropertyService_PropertiesIterator</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
index 1710769661..9cb5e8f489 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertyNamesIterator.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosPropertyService_&shy;PropertyNamesIterator</title>
- <shorttitle>..._PropertyNamesIterator</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosPropertyService_PropertyNamesIterator</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-07-25</date>
<rev>1.0</rev>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
index 2c1671bf77..f9a7c9ca97 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySet.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosPropertyService_&shy;PropertySet</title>
- <shorttitle>..._PropertySet</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosPropertyService_PropertySet</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-07-25</date>
<rev>1.0</rev>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
index 7684998428..2dbfd05ba8 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDef.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosPropertyService_&shy;PropertySetDef</title>
- <shorttitle>..._PropertySetDef</shorttitle>
+ <title>CosPropertyService_PropertySetDef</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
index 67aa579e6a..a009e70f68 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetDefFactory.xml
@@ -23,10 +23,9 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosPropertyService_&shy;PropertySetDefFactory</title>
- <shorttitle>..._PropertySetDefFactory</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosPropertyService_PropertySetDefFactory</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved>Niclas Eklund</approved>
<checked></checked>
diff --git a/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml b/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
index 3fb4822948..62ee2bda4f 100644
--- a/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
+++ b/lib/cosProperty/doc/src/CosPropertyService_PropertySetFactory.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosPropertyService_&shy;PropertySetFactory</title>
- <shorttitle>..._PropertySetFactory</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosPropertyService_PropertySetFactory</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>2000-07-25</date>
<rev>1.0</rev>
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index 540fdce762..85b2119e9d 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -22,7 +22,7 @@
</legalnotice>
<title>cosProperty Release Notes</title>
- <prepared>Niclas Eklund</prepared>
+ <prepared></prepared>
<docno></docno>
<approved></approved>
<checked></checked>
@@ -32,6 +32,23 @@
</header>
<section>
+ <title>cosProperty 1.1.14</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosProperty 1.1.13</title>
<section>
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index deb1eb0450..ecc4a2746c 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1,2 +1,2 @@
-COSPROPERTY_VSN = 1.1.13
+COSPROPERTY_VSN = 1.1.14
diff --git a/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml b/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
index 4b2e57642a..2adf318674 100644
--- a/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
+++ b/lib/cosTime/doc/src/CosTimerEvent_TimerEventHandler.xml
@@ -23,10 +23,9 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosTimerEvent_&shy;TimerEventHandler</title>
- <shorttitle>..._TimerEventHandler</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosTimerEvent_TimerEventHandler</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
<approved>Niclas Eklund</approved>
<checked></checked>
diff --git a/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml b/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
index fb3fe747e5..80f5fd1466 100644
--- a/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
+++ b/lib/cosTime/doc/src/CosTimerEvent_TimerEventService.xml
@@ -23,8 +23,7 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosTimerEvent_&shy;TimerEventService</title>
- <shorttitle>..._TimerEventService</shorttitle>
+ <title>CosTimerEvent_TimerEventService</title>
<prepared>Niclas Eklund</prepared>
<responsible>Niclas Eklund</responsible>
<docno></docno>
diff --git a/lib/cosTime/doc/src/notes.xml b/lib/cosTime/doc/src/notes.xml
index 718ca23bc5..3698e4813e 100644
--- a/lib/cosTime/doc/src/notes.xml
+++ b/lib/cosTime/doc/src/notes.xml
@@ -33,6 +33,23 @@
</header>
<section>
+ <title>cosTime 1.1.11</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosTime 1.1.10</title>
<section>
diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk
index ebc5aff1cc..4d982f3013 100644
--- a/lib/cosTime/vsn.mk
+++ b/lib/cosTime/vsn.mk
@@ -1,2 +1,2 @@
-COSTIME_VSN = 1.1.10
+COSTIME_VSN = 1.1.11
diff --git a/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml b/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
index 4b870f4b90..0222f3be86 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_RecoveryCoordinator.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,12 +21,11 @@
</legalnotice>
- <title>CosTransactions_&shy;RecoveryCoordinator</title>
- <shorttitle>..._RecoveryCoordinator</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosTransactions_RecoveryCoordinator</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>1999-04-12</date>
<rev>PA1</rev>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml b/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
index 2c7b6b5215..5878b41360 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_SubtransactionAwareResource.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -21,8 +21,7 @@
</legalnotice>
- <title>CosTransactions_&shy;SubtransactionAwareResource</title>
- <shorttitle>..._SubtransactionAwareResource</shorttitle>
+ <title>CosTransactions_SubtransactionAwareResource</title>
<prepared></prepared>
<docno></docno>
<checked></checked>
diff --git a/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml b/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
index 162e6e8cd1..7e93aa2964 100644
--- a/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
+++ b/lib/cosTransactions/doc/src/CosTransactions_TransactionFactory.xml
@@ -23,12 +23,11 @@
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
- <title>CosTransactions_&shy;TransactionFactory</title>
- <shorttitle>..._TransactionFactory</shorttitle>
- <prepared>Niclas Eklund</prepared>
- <responsible>Niclas Eklund</responsible>
+ <title>CosTransactions_TransactionFactory</title>
+ <prepared></prepared>
+ <responsible></responsible>
<docno></docno>
- <approved>Niclas Eklund</approved>
+ <approved></approved>
<checked></checked>
<date>1999-04-12</date>
<rev>PA1</rev>
diff --git a/lib/cosTransactions/doc/src/notes.xml b/lib/cosTransactions/doc/src/notes.xml
index 7586e3c13f..29addf424d 100644
--- a/lib/cosTransactions/doc/src/notes.xml
+++ b/lib/cosTransactions/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2010</year>
+ <year>1999</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -33,6 +33,22 @@
</header>
<section>
+ <title>cosTransactions 1.2.11</title>
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Removed superfluous usage of shy in the documentation since it can cause problem if
+ a buggy tool is used.</p>
+ <p>
+ Own Id: OTP-9319 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosTransactions 1.2.10</title>
<section>
<title>Improvements and New Features</title>
diff --git a/lib/cosTransactions/vsn.mk b/lib/cosTransactions/vsn.mk
index 82e46f51dd..3960c58c5b 100644
--- a/lib/cosTransactions/vsn.mk
+++ b/lib/cosTransactions/vsn.mk
@@ -1 +1 @@
-COSTRANSACTIONS_VSN = 1.2.10
+COSTRANSACTIONS_VSN = 1.2.11
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in
index 3ace10403e..276c84d601 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+# Copyright Ericsson AB 1999-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 3ebf62d87c..c781ccb302 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -50,6 +50,8 @@
#include <openssl/rc2.h>
#include <openssl/blowfish.h>
#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
#ifdef VALGRIND
# include <valgrind/memcheck.h>
@@ -128,11 +130,15 @@ static ERL_NIF_TERM md4_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
static ERL_NIF_TERM md4_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM md5_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM sha_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM hmac_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM hmac_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM hmac_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -199,12 +205,18 @@ static ErlNifFunc nif_funcs[] = {
{"md4_final", 1, md4_final},
{"md5_mac_n", 3, md5_mac_n},
{"sha_mac_n", 3, sha_mac_n},
+ {"hmac_init", 2, hmac_init},
+ {"hmac_update", 2, hmac_update},
+ {"hmac_final", 1, hmac_final},
+ {"hmac_final_n", 2, hmac_final},
{"des_cbc_crypt", 4, des_cbc_crypt},
{"des_ecb_crypt", 3, des_ecb_crypt},
{"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt},
{"aes_cfb_128_crypt", 4, aes_cfb_128_crypt},
{"aes_ctr_encrypt", 3, aes_ctr_encrypt},
{"aes_ctr_decrypt", 3, aes_ctr_encrypt},
+ {"aes_ctr_stream_encrypt", 2, aes_ctr_stream_encrypt},
+ {"aes_ctr_stream_decrypt", 2, aes_ctr_stream_encrypt},
{"rand_bytes", 1, rand_bytes_1},
{"strong_rand_bytes_nif", 1, strong_rand_bytes_nif},
{"rand_bytes", 3, rand_bytes_3},
@@ -255,6 +267,7 @@ static ERL_NIF_TERM atom_true;
static ERL_NIF_TERM atom_false;
static ERL_NIF_TERM atom_sha;
static ERL_NIF_TERM atom_md5;
+static ERL_NIF_TERM atom_ripemd160;
static ERL_NIF_TERM atom_error;
static ERL_NIF_TERM atom_rsa_pkcs1_padding;
static ERL_NIF_TERM atom_rsa_pkcs1_oaep_padding;
@@ -324,6 +337,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
atom_false = enif_make_atom(env,"false");
atom_sha = enif_make_atom(env,"sha");
atom_md5 = enif_make_atom(env,"md5");
+ atom_ripemd160 = enif_make_atom(env,"ripemd160");
atom_error = enif_make_atom(env,"error");
atom_rsa_pkcs1_padding = enif_make_atom(env,"rsa_pkcs1_padding");
atom_rsa_pkcs1_oaep_padding = enif_make_atom(env,"rsa_pkcs1_oaep_padding");
@@ -581,6 +595,84 @@ static ERL_NIF_TERM sha_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
return ret;
}
+static ERL_NIF_TERM hmac_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Type, Key) */
+ ErlNifBinary key;
+ ERL_NIF_TERM ret;
+ unsigned char * ctx_buf;
+ const EVP_MD *md;
+
+ if (argv[0] == atom_sha) md = EVP_sha1();
+ else if (argv[0] == atom_md5) md = EVP_md5();
+ else if (argv[0] == atom_ripemd160) md = EVP_ripemd160();
+ else goto badarg;
+
+ if (!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
+ badarg:
+ return enif_make_badarg(env);
+ }
+
+ ctx_buf = enif_make_new_binary(env, sizeof(HMAC_CTX), &ret);
+ HMAC_CTX_init((HMAC_CTX *) ctx_buf);
+ HMAC_Init((HMAC_CTX *) ctx_buf, key.data, key.size, md);
+
+ return ret;
+}
+
+static ERL_NIF_TERM hmac_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Context, Data) */
+ ErlNifBinary context, data;
+ ERL_NIF_TERM ret;
+ unsigned char * ctx_buf;
+
+ if (!enif_inspect_binary(env, argv[0], &context)
+ || !enif_inspect_iolist_as_binary(env, argv[1], &data)
+ || context.size != sizeof(HMAC_CTX)) {
+ return enif_make_badarg(env);
+ }
+
+ ctx_buf = enif_make_new_binary(env, sizeof(HMAC_CTX), &ret);
+ memcpy(ctx_buf, context.data, context.size);
+ HMAC_Update((HMAC_CTX *)ctx_buf, data.data, data.size);
+
+ return ret;
+}
+
+static ERL_NIF_TERM hmac_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Context) or (Context, HashLen) */
+ ErlNifBinary context;
+ ERL_NIF_TERM ret;
+ HMAC_CTX ctx;
+ unsigned char mac_buf[EVP_MAX_MD_SIZE];
+ unsigned char * mac_bin;
+ unsigned int req_len = 0;
+ unsigned int mac_len;
+
+ if (!enif_inspect_binary(env, argv[0], &context)) {
+ return enif_make_badarg(env);
+ }
+ if (argc == 2 && !enif_get_uint(env, argv[1], &req_len)) {
+ return enif_make_badarg(env);
+ }
+
+ if (context.size != sizeof(ctx)) {
+ return enif_make_badarg(env);
+ }
+ memcpy(&ctx, context.data, context.size);
+
+ HMAC_Final(&ctx, mac_buf, &mac_len);
+ HMAC_CTX_cleanup(&ctx);
+
+ if (argc == 2 && req_len < mac_len) {
+ // Only truncate to req_len bytes if asked.
+ mac_len = req_len;
+ }
+ mac_bin = enif_make_new_binary(env, mac_len, &ret);
+ memcpy(mac_bin, mac_buf, mac_len);
+
+ return ret;
+}
+
static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Key, Ivec, Text, IsEncrypt) */
ErlNifBinary key, ivec, text;
@@ -695,6 +787,46 @@ static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
return ret;
}
+/* Initializes state for ctr streaming (de)encryption
+*/
+static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* ({Key, IVec, ECount, Num}, Data) */
+ ErlNifBinary key_bin, ivec_bin, text_bin, ecount_bin;
+ AES_KEY aes_key;
+ unsigned int num;
+ ERL_NIF_TERM ret, num2_term, cipher_term, ivec2_term, ecount2_term, new_state_term;
+ int state_arity;
+ const ERL_NIF_TERM *state_term;
+ unsigned char * ivec2_buf;
+ unsigned char * ecount2_buf;
+
+ if (!enif_get_tuple(env, argv[0], &state_arity, &state_term)
+ || state_arity != 4
+ || !enif_inspect_iolist_as_binary(env, state_term[0], &key_bin)
+ || AES_set_encrypt_key(key_bin.data, key_bin.size*8, &aes_key) != 0
+ || !enif_inspect_binary(env, state_term[1], &ivec_bin) || ivec_bin.size != 16
+ || !enif_inspect_binary(env, state_term[2], &ecount_bin) || ecount_bin.size != AES_BLOCK_SIZE
+ || !enif_get_uint(env, state_term[3], &num)
+ || !enif_inspect_iolist_as_binary(env, argv[1], &text_bin)) {
+ return enif_make_badarg(env);
+ }
+
+ ivec2_buf = enif_make_new_binary(env, ivec_bin.size, &ivec2_term);
+ ecount2_buf = enif_make_new_binary(env, ecount_bin.size, &ecount2_term);
+
+ memcpy(ivec2_buf, ivec_bin.data, 16);
+ memcpy(ecount2_buf, ecount_bin.data, ecount_bin.size);
+
+ AES_ctr128_encrypt((unsigned char *) text_bin.data,
+ enif_make_new_binary(env, text_bin.size, &cipher_term),
+ text_bin.size, &aes_key, ivec2_buf, ecount2_buf, &num);
+
+ num2_term = enif_make_uint(env, num);
+ new_state_term = enif_make_tuple4(env, state_term[0], ivec2_term, ecount2_term, num2_term);
+ ret = enif_make_tuple2(env, new_state_term, cipher_term);
+ return ret;
+}
+
static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Bytes) */
unsigned bytes;
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 1ccea6df79..179ba4498c 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -282,6 +282,57 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
</desc>
</func>
<func>
+ <name>hmac_init(Type, Key) -> Context</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Type = sha | md5 | ripemd160</v>
+ <v>Key = iolist() | binary()</v>
+ <v>Context = binary()</v>
+ </type>
+ <desc>
+ <p>Initializes the context for streaming HMAC operations. <c>Type</c> determines
+ which hash function to use in the HMAC operation. <c>Key</c> is the authentication
+ key. The key can be any length.</p>
+ </desc>
+ </func>
+ <func>
+ <name>hmac_update(Context, Data) -> NewContext</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Context = NewContext = binary()</v>
+ <v>Data = iolist() | binary()</v>
+ </type>
+ <desc>
+ <p>Updates the HMAC represented by <c>Context</c> using the given <c>Data</c>. <c>Context</c>
+ must have been generated using an HMAC init function (such as
+ <seealso marker="#hmac_init/2">hmac_init</seealso>). <c>Data</c> can be any length. <c>NewContext</c>
+ must be passed into the next call to <c>hmac_update</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>hmac_final(Context) -> Mac</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Context = Mac = binary()</v>
+ </type>
+ <desc>
+ <p>Finalizes the HMAC operation referenced by <c>Context</c>. The size of the resultant MAC is
+ determined by the type of hash function used to generate it.</p>
+ </desc>
+ </func>
+ <func>
+ <name>hmac_final_n(Context, HashLen) -> Mac</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Context = Mac = binary()</v>
+ <v>HashLen = non_neg_integer()</v>
+ </type>
+ <desc>
+ <p>Finalizes the HMAC operation referenced by <c>Context</c>. <c>HashLen</c> must be greater than
+ zero. <c>Mac</c> will be a binary with at most <c>HashLen</c> bytes. Note that if HashLen is greater than the actual number of bytes returned from the underlying hash, the returned hash will have fewer than <c>HashLen</c> bytes.</p>
+ </desc>
+ </func>
+ <func>
<name>sha_mac(Key, Data) -> Mac</name>
<fsummary>Compute an <c>MD5 MAC</c>message authentification code</fsummary>
<type>
@@ -589,6 +640,55 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
</desc>
</func>
<func>
+ <name>aes_ctr_stream_init(Key, IVec) -> State</name>
+ <fsummary></fsummary>
+ <type>
+ <v>State = { K, I, E, C }</v>
+ <v>Key = K = iolist()</v>
+ <v>IVec = I = E = binary()</v>
+ <v>C = integer()</v>
+ </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
+ an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with
+ <seealso marker="#aes_ctr_stream_encrypt/2">aes_ctr_stream_encrypt</seealso> and
+ <seealso marker="#aes_ctr_stream_decrypt/2">aes_ctr_stream_decrypt</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>aes_ctr_stream_encrypt(State, Text) -> { NewState, Cipher}</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Text = iolist() | binary()</v>
+ <v>Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> according to AES in Counter mode (CTR). This function can be
+ used to encrypt a stream of text using a series of calls instead of requiring all
+ text to be in memory. <c>Text</c> can be any number of bytes. State is initialized using
+ <seealso marker="#aes_ctr_stream_init/2">aes_ctr_stream_init</seealso>. <c>NewState</c> is the new streaming
+ encryption state that must be passed to the next call to <c>aes_ctr_stream_encrypt</c>.
+ <c>Cipher</c> is the encrypted cipher text.</p>
+ </desc>
+ </func>
+ <func>
+ <name>aes_ctr_stream_decrypt(State, Cipher) -> { NewState, Text }</name>
+ <fsummary></fsummary>
+ <type>
+ <v>Cipher = iolist() | binary()</v>
+ <v>Text = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts <c>Cipher</c> according to AES in Counter mode (CTR). This function can be
+ used to decrypt a stream of ciphertext using a series of calls instead of requiring all
+ ciphertext to be in memory. <c>Cipher</c> can be any number of bytes. State is initialized using
+ <seealso marker="#aes_ctr_stream_init/2">aes_ctr_stream_init</seealso>. <c>NewState</c> is the new streaming
+ encryption state that must be passed to the next call to <c>aes_ctr_stream_encrypt</c>.
+ <c>Text</c> is the decrypted data.</p>
+ </desc>
+ </func>
+ <func>
<name>erlint(Mpint) -> N</name>
<name>mpint(N) -> Mpint</name>
<fsummary>Convert between binary multi-precision integer and erlang big integer</fsummary>
diff --git a/lib/crypto/doc/src/licenses.xml b/lib/crypto/doc/src/licenses.xml
index e851655aa5..0b791acfa2 100644
--- a/lib/crypto/doc/src/licenses.xml
+++ b/lib/crypto/doc/src/licenses.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index ab1ffa9e5c..a5434ebd68 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,45 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 2.0.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Various small documentation fixes (Thanks to Bernard
+ Duggan)</p>
+ <p>
+ Own Id: OTP-9172</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ New <c>crypto</c> support for streaming of AES CTR and
+ HMAC. (Thanks to Travis Jensen)</p>
+ <p>
+ Own Id: OTP-9275</p>
+ </item>
+ <item>
+ <p>
+ Due to standard library DLL mismatches between versions
+ of OpenSSL and Erlang/OTP, OpenSSL is now linked
+ statically to the crypto driver on Windows. This fixes
+ problems starting crypto when running Erlang as a service
+ on all Windows versions.</p>
+ <p>
+ Own Id: OTP-9280</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 2.0.2.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index cc7b3acc9c..c35dfcebab 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -28,6 +28,7 @@
%-export([sha256/1, sha256_init/0, sha256_update/2, sha256_final/1]).
%-export([sha512/1, sha512_init/0, sha512_update/2, sha512_final/1]).
-export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac_96/2]).
+-export([hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
-export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]).
-export([des_ecb_encrypt/2, des_ecb_decrypt/2]).
-export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]).
@@ -53,6 +54,7 @@
-export([aes_cbc_256_encrypt/3, aes_cbc_256_decrypt/3]).
-export([aes_cbc_ivec/1]).
-export([aes_ctr_encrypt/3, aes_ctr_decrypt/3]).
+-export([aes_ctr_stream_init/2, aes_ctr_stream_encrypt/2, aes_ctr_stream_decrypt/2]).
-export([dh_generate_parameters/2, dh_check/1]). %% Testing see below
@@ -64,6 +66,7 @@
%% sha512, sha512_init, sha512_update, sha512_final,
md5_mac, md5_mac_96,
sha_mac, sha_mac_96,
+ sha_mac_init, sha_mac_update, sha_mac_final,
des_cbc_encrypt, des_cbc_decrypt,
des_ecb_encrypt, des_ecb_decrypt,
des_ede3_cbc_encrypt, des_ede3_cbc_decrypt,
@@ -85,6 +88,7 @@
%% idea_cbc_encrypt, idea_cbc_decrypt,
aes_cbc_256_encrypt, aes_cbc_256_decrypt,
aes_ctr_encrypt, aes_ctr_decrypt,
+ aes_ctr_stream_init, aes_ctr_stream_encrypt, aes_ctr_stream_decrypt,
info_lib]).
-type rsa_digest_type() :: 'md5' | 'sha'.
@@ -217,6 +221,19 @@ sha_final(_Context) -> ?nif_stub.
%%
%%
+%% HMAC (multiple hash options)
+%%
+-spec hmac_init(atom(), iodata()) -> binary().
+-spec hmac_update(binary(), iodata()) -> binary().
+-spec hmac_final(binary()) -> binary().
+-spec hmac_final_n(binary(), integer()) -> binary().
+
+hmac_init(_Type, _Key) -> ?nif_stub.
+hmac_update(_Context, _Data) -> ? nif_stub.
+hmac_final(_Context) -> ? nif_stub.
+hmac_final_n(_Context, _HashLen) -> ? nif_stub.
+
+%%
%% MD5_MAC
%%
-spec md5_mac(iodata(), iodata()) -> binary().
@@ -243,7 +260,7 @@ sha_mac_96(Key, Data) ->
sha_mac_n(Key,Data,12).
sha_mac_n(_Key,_Data,_MacSz) -> ?nif_stub.
-
+
%%
%% CRYPTO FUNCTIONS
%%
@@ -579,6 +596,22 @@ aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub.
aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub.
%%
+%% AES - in counter mode (CTR) with state maintained for multi-call streaming
+%%
+-type ctr_state() :: { iodata(), binary(), binary(), integer() }.
+
+-spec aes_ctr_stream_init(iodata(), binary()) -> ctr_state().
+-spec aes_ctr_stream_encrypt(ctr_state(), binary()) ->
+ { ctr_state(), binary() }.
+-spec aes_ctr_stream_decrypt(ctr_state(), binary()) ->
+ { ctr_state(), binary() }.
+
+aes_ctr_stream_init(Key, IVec) ->
+ {Key, IVec, << 0:128 >>, 0}.
+aes_ctr_stream_encrypt({_Key, _IVec, _ECount, _Num}=_State, _Data) -> ?nif_stub.
+aes_ctr_stream_decrypt({_Key, _IVec, _ECount, _Num}=_State, _Cipher) -> ?nif_stub.
+
+%%
%% XOR - xor to iolists and return a binary
%% NB doesn't check that they are the same size, just concatenates
%% them and sends them to the driver
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 854a8b4485..283aadb6ea 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -31,6 +31,11 @@
md4_update/1,
sha/1,
sha_update/1,
+ hmac_update_sha/1,
+ hmac_update_sha_n/1,
+ hmac_update_md5/1,
+ hmac_update_md5_io/1,
+ hmac_update_md5_n/1,
sha256/1,
sha256_update/1,
sha512/1,
@@ -44,6 +49,7 @@
aes_cbc/1,
aes_cbc_iter/1,
aes_ctr/1,
+ aes_ctr_stream/1,
mod_exp_test/1,
rand_uniform_test/1,
strong_rand_test/1,
@@ -67,9 +73,10 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[link_test, md5, md5_update, md4, md4_update, md5_mac,
md5_mac_io, sha, sha_update,
+ hmac_update_sha, hmac_update_sha_n, hmac_update_md5_n, hmac_update_md5_io, hmac_update_md5,
%% sha256, sha256_update, sha512,sha512_update,
des_cbc, aes_cfb, aes_cbc,
- aes_cbc_iter, aes_ctr, des_cbc_iter, des_ecb,
+ aes_cbc_iter, aes_ctr, aes_ctr_stream, des_cbc_iter, des_ecb,
rand_uniform_test, strong_rand_test,
rsa_verify_test, dsa_verify_test, rsa_sign_test,
dsa_sign_test, rsa_encrypt_decrypt, dh, exor_test,
@@ -284,6 +291,101 @@ sha(Config) when is_list(Config) ->
hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
+%%
+hmac_update_sha_n(doc) ->
+ ["Request a larger-than-allowed SHA1 HMAC using hmac_init, hmac_update, and hmac_final_n. "
+ "Expected values for examples are generated using crypto:sha_mac." ];
+hmac_update_sha_n(suite) ->
+ [];
+hmac_update_sha_n(Config) when is_list(Config) ->
+ ?line Key = hexstr2bin("00010203101112132021222330313233"
+ "04050607141516172425262734353637"
+ "08090a0b18191a1b28292a2b38393a3b"
+ "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
+ ?line Data = "Sampl",
+ ?line Data2 = "e #1",
+ ?line Ctx = crypto:hmac_init(sha, Key),
+ ?line Ctx2 = crypto:hmac_update(Ctx, Data),
+ ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
+ ?line Mac = crypto:hmac_final_n(Ctx3, 1024),
+ ?line Exp = crypto:sha_mac(Key, lists:flatten([Data, Data2])),
+ ?line m(Exp, Mac),
+ ?line m(size(Exp), size(Mac)).
+
+
+hmac_update_sha(doc) ->
+ ["Generate an SHA1 HMAC using hmac_init, hmac_update, and hmac_final. "
+ "Expected values for examples are generated using crypto:sha_mac." ];
+hmac_update_sha(suite) ->
+ [];
+hmac_update_sha(Config) when is_list(Config) ->
+ ?line Key = hexstr2bin("00010203101112132021222330313233"
+ "04050607141516172425262734353637"
+ "08090a0b18191a1b28292a2b38393a3b"
+ "0c0d0e0f1c1d1e1f2c2d2e2f3c3d3e3f"),
+ ?line Data = "Sampl",
+ ?line Data2 = "e #1",
+ ?line Ctx = crypto:hmac_init(sha, Key),
+ ?line Ctx2 = crypto:hmac_update(Ctx, Data),
+ ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
+ ?line Mac = crypto:hmac_final(Ctx3),
+ ?line Exp = crypto:sha_mac(Key, lists:flatten([Data, Data2])),
+ ?line m(Exp, Mac).
+
+hmac_update_md5(doc) ->
+ ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
+ "Expected values for examples are generated using crypto:md5_mac." ];
+hmac_update_md5(suite) ->
+ [];
+hmac_update_md5(Config) when is_list(Config) ->
+ % ?line Key2 = ["A fine speach", "by a fine man!"],
+ Key2 = "A fine speach by a fine man!",
+ ?line Long1 = "Four score and seven years ago our fathers brought forth on this continent a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.",
+ ?line Long2 = "Now we are engaged in a great civil war, testing whether that nation, or any nation, so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.",
+ ?line Long3 = "But, in a larger sense, we can not dedicate, we can not consecrate, we can not hallow this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us-that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain-that this nation, under God, shall have a new birth of freedom-and that government of the people, by the people, for the people, shall not perish from the earth.",
+ ?line CtxA = crypto:hmac_init(md5, Key2),
+ ?line CtxB = crypto:hmac_update(CtxA, Long1),
+ ?line CtxC = crypto:hmac_update(CtxB, Long2),
+ ?line CtxD = crypto:hmac_update(CtxC, Long3),
+ ?line Mac2 = crypto:hmac_final(CtxD),
+ ?line Exp2 = crypto:md5_mac(Key2, lists:flatten([Long1, Long2, Long3])),
+ ?line m(Exp2, Mac2).
+
+
+hmac_update_md5_io(doc) ->
+ ["Generate an MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
+ "Expected values for examples are generated using crypto:md5_mac." ];
+hmac_update_md5_io(suite) ->
+ [];
+hmac_update_md5_io(Config) when is_list(Config) ->
+ ?line Key = ["A fine speach", "by a fine man!"],
+ ?line Data = "Sampl",
+ ?line Data2 = "e #1",
+ ?line Ctx = crypto:hmac_init(md5, Key),
+ ?line Ctx2 = crypto:hmac_update(Ctx, Data),
+ ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
+ ?line Mac = crypto:hmac_final(Ctx3),
+ ?line Exp = crypto:md5_mac(Key, lists:flatten([Data, Data2])),
+ ?line m(Exp, Mac).
+
+
+hmac_update_md5_n(doc) ->
+ ["Generate a shortened MD5 HMAC using hmac_init, hmac_update, and hmac_final. "
+ "Expected values for examples are generated using crypto:md5_mac." ];
+hmac_update_md5_n(suite) ->
+ [];
+hmac_update_md5_n(Config) when is_list(Config) ->
+ ?line Key = ["A fine speach", "by a fine man!"],
+ ?line Data = "Sampl",
+ ?line Data2 = "e #1",
+ ?line Ctx = crypto:hmac_init(md5, Key),
+ ?line Ctx2 = crypto:hmac_update(Ctx, Data),
+ ?line Ctx3 = crypto:hmac_update(Ctx2, Data2),
+ ?line Mac = crypto:hmac_final_n(Ctx3, 12),
+ ?line Exp = crypto:md5_mac_96(Key, lists:flatten([Data, Data2])),
+ ?line m(Exp, Mac).
+
+
%%
%%
sha_update(doc) ->
@@ -673,6 +775,77 @@ aes_ctr_do(Key,{IVec, Plain, Cipher}) ->
?line m(C, hexstr2bin(Cipher)),
?line m(P, crypto:aes_ctr_decrypt(Key, I, C)).
+aes_ctr_stream(doc) -> "CTR Streaming";
+aes_ctr_stream(Config) when is_list(Config) ->
+ %% Sample data from NIST Spec.Publ. 800-38A
+ %% F.5.1 CTR-AES128.Encrypt
+ Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ ["6bc1bee22e409f", "96e93d7e117393172a"], % Plaintext
+ ["874d6191b620e3261bef6864990db6ce"]}, % Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ ["ae2d8a57", "1e03ac9c", "9eb76fac", "45af8e51"],
+ ["9806f66b7970fdff","8617187bb9fffdff"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ ["30c81c46a35c", "e411e5fbc119", "1a0a52ef"],
+ ["5ae4df3e","dbd5d3","5e5b4f0902","0db03eab"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ ["f69f2445df4f9b17ad2b417be66c3710"],
+ ["1e031dda2fbe","03d1792170a0","f3009cee"]}],
+ lists:foreach(fun(S) -> aes_ctr_stream_do(Key128,S) end, Samples128),
+
+ %% F.5.3 CTR-AES192.Encrypt
+ Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
+ Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ ["6bc1bee22e409f96e93d7e117393172a"], % Plaintext
+ ["1abc9324","17521c","a24f2b04","59fe7e6e0b"]}, % Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ ["ae2d8a57", "1e03ac9c9eb76fac", "45af8e51"],
+ ["090339ec0aa6faefd5ccc2c6f4ce8e94"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ ["30c81c46a35ce411", "e5fbc1191a0a52ef"],
+ ["1e36b26bd1","ebc670d1bd1d","665620abf7"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ ["f69f2445", "df4f9b17ad", "2b417be6", "6c3710"],
+ ["4f78a7f6d2980958","5a97daec58c6b050"]}],
+ lists:foreach(fun(S) -> aes_ctr_stream_do(Key192,S) end, Samples192),
+
+ %% F.5.5 CTR-AES256.Encrypt
+ Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
+ Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block
+ ["6bc1bee22e409f96", "e93d7e117393172a"], % Plaintext
+ ["601ec313775789", "a5b7a7f504bbf3d228"]}, % Ciphertext
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00",
+ ["ae2d8a571e03ac9c9eb76fac45af8e51"],
+ ["f443e3ca","4d62b59aca84","e990cacaf5c5"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01",
+ ["30c81c46","a35ce411","e5fbc119","1a0a52ef"],
+ ["2b0930daa23de94ce87017ba2d84988d"]},
+ {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02",
+ ["f69f2445df4f","9b17ad2b41","7be66c3710"],
+ ["dfc9c5","8db67aada6","13c2dd08","457941a6"]}],
+ lists:foreach(fun(S) -> aes_ctr_stream_do(Key256,S) end, Samples256).
+
+
+aes_ctr_stream_do(Key,{IVec, PlainList, CipherList}) ->
+ ?line I = hexstr2bin(IVec),
+ ?line S = crypto:aes_ctr_stream_init(Key, I),
+ ?line C = aes_ctr_stream_do_iter(
+ S, PlainList, [],
+ fun(S2,P) -> crypto:aes_ctr_stream_encrypt(S2, P) end),
+ ?line m(C, hexstr2bin(lists:flatten(CipherList))),
+ ?line P = aes_ctr_stream_do_iter(
+ S, CipherList, [],
+ fun(S2,C2) -> crypto:aes_ctr_stream_decrypt(S2, C2) end),
+ ?line m(P, hexstr2bin(lists:flatten(PlainList))).
+
+aes_ctr_stream_do_iter(_State, [], Acc, _CipherFun) ->
+ iolist_to_binary(lists:reverse(Acc));
+aes_ctr_stream_do_iter(State, [Plain|Rest], Acc, CipherFun) ->
+ ?line P = hexstr2bin(Plain),
+ ?line {S2, C} = CipherFun(State, P),
+ aes_ctr_stream_do_iter(S2, Rest, [C | Acc], CipherFun).
+
%%
%%
mod_exp_test(doc) ->
@@ -1127,7 +1300,8 @@ worker_loop(0, _) ->
worker_loop(N, Config) ->
Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc,
aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test, strong_rand_test,
- rsa_verify_test, exor_test, rc4_test, rc4_stream_test, mod_exp_test },
+ rsa_verify_test, exor_test, rc4_test, rc4_stream_test, mod_exp_test,
+ hmac_update_md5, hmac_update_sha, aes_ctr_stream },
F = element(random:uniform(size(Funcs)),Funcs),
%%io:format("worker ~p calling ~p\n",[self(),F]),
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index 740c68d8fa..e754aabc44 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 2.0.2.2
+CRYPTO_VSN = 2.0.3
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 0dadf647c3..81622a3854 100755
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -31,6 +31,45 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.4.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix the name of an error function(Thanks to Maria
+ christakis)</p>
+ <p>
+ Own Id: OTP-9175</p>
+ </item>
+ <item>
+ <p>
+ Fix crash related with the contract blame assignment
+ patch</p>
+ <p>
+ Own Id: OTP-9219</p>
+ </item>
+ <item>
+ <p>
+ dialyzer/doc: synchronize manual.txt and dialyzer.xml
+ (Thanks to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9226</p>
+ </item>
+ <item>
+ <p>
+ Simplify Dialyzer's test suite structure</p>
+ <p>
+ *_SUITE.erl files are now automatically generated by the
+ respective data directories by the Makefile.</p>
+ <p>
+ Own Id: OTP-9278</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.4.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 7137dbc036..8cb16d8f09 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -1414,6 +1414,17 @@ do_clause(C, Arg, ArgType0, OrigArgType, Map,
false ->
true
end;
+ [Pat0, Pat1] -> % binary comprehension
+ case cerl:is_c_cons(Pat0) of
+ true ->
+ not (cerl:is_c_var(cerl:cons_hd(Pat0)) andalso
+ cerl:is_c_var(cerl:cons_tl(Pat0)) andalso
+ cerl:is_c_var(Pat1) andalso
+ cerl:is_literal(Guard) andalso
+ (cerl:concrete(Guard) =:= true));
+ false ->
+ true
+ end;
_ -> true
end;
false ->
@@ -2915,7 +2926,7 @@ state__get_warnings(#state{tree_map = TreeMap, fun_tab = FunTab,
{Warn, Msg} =
case dialyzer_callgraph:lookup_name(FunLbl, Callgraph) of
error -> {true, {unused_fun, []}};
- {ok, {_M, F, A}} = MFA ->
+ {ok, {_M, F, A} = MFA} ->
{not sets:is_element(MFA, NoWarnUnused),
{unused_fun, [F, A]}}
end,
diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl
index b8da57d3f9..dc5a3fed37 100644
--- a/lib/dialyzer/src/dialyzer_succ_typings.erl
+++ b/lib/dialyzer/src/dialyzer_succ_typings.erl
@@ -158,20 +158,27 @@ postprocess_dataflow_warns([], _State, WAcc, Acc) ->
postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, {CallF, CallL}, Msg}|Rest],
#st{codeserver = Codeserver} = State, WAcc, Acc) ->
{contract_range, [Contract, M, F, A, ArgStrings, CRet]} = Msg,
- {ok, {{ContrF, _ContrL} = FileLine, _C}} =
- dialyzer_codeserver:lookup_mfa_contract({M,F,A}, Codeserver),
- case CallF =:= ContrF of
- true ->
+ case dialyzer_codeserver:lookup_mfa_contract({M,F,A}, Codeserver) of
+ {ok, {{ContrF, _ContrL} = FileLine, _C}} ->
+ case CallF =:= ContrF of
+ true ->
+ NewMsg = {contract_range, [Contract, M, F, ArgStrings, CallL, CRet]},
+ W = {?WARN_CONTRACT_RANGE, FileLine, NewMsg},
+ Filter =
+ fun({?WARN_CONTRACT_TYPES, FL, _}) when FL =:= FileLine -> false;
+ (_) -> true
+ end,
+ FilterWAcc = lists:filter(Filter, WAcc),
+ postprocess_dataflow_warns(Rest, State, FilterWAcc, [W|Acc]);
+ false ->
+ postprocess_dataflow_warns(Rest, State, WAcc, Acc)
+ end;
+ error ->
+ %% 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, FileLine, NewMsg},
- Filter =
- fun({?WARN_CONTRACT_TYPES, FL, _}) when FL =:= FileLine -> false;
- (_) -> true
- end,
- FilterWAcc = lists:filter(Filter, WAcc),
- postprocess_dataflow_warns(Rest, State, FilterWAcc, [W|Acc]);
- false ->
- postprocess_dataflow_warns(Rest, State, WAcc, Acc)
+ W = {?WARN_CONTRACT_RANGE, {CallF, CallL}, NewMsg},
+ postprocess_dataflow_warns(Rest, State, WAcc, [W|Acc])
end;
postprocess_dataflow_warns([W|Rest], State, Wacc, Acc) ->
postprocess_dataflow_warns(Rest, State, Wacc, [W|Acc]).
diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl
index c45615d670..65c2ff76bb 100644
--- a/lib/dialyzer/src/dialyzer_typesig.erl
+++ b/lib/dialyzer/src/dialyzer_typesig.erl
@@ -1684,11 +1684,14 @@ solve_scc(SCC, Map, State, TryingUnit) ->
true ->
?debug("SCC ~w reached fixpoint\n", [SCC]),
NewTypes = unsafe_lookup_type_list(Funs, Map2),
- case lists:all(fun(T) -> t_is_none(t_fun_range(T)) end, NewTypes)
+ case erl_types:any_none([t_fun_range(T) || T <- NewTypes])
andalso TryingUnit =:= false of
true ->
- UnitTypes = [t_fun(state__fun_arity(F, State), t_unit())
- || F <- Funs],
+ UnitTypes =
+ [case t_is_none(t_fun_range(T)) of
+ false -> T;
+ true -> t_fun(t_fun_args(T), t_unit())
+ end || T <- NewTypes],
Map3 = enter_type_lists(Funs, UnitTypes, Map2),
solve_scc(SCC, Map3, State, true);
false ->
diff --git a/lib/dialyzer/test/Makefile b/lib/dialyzer/test/Makefile
index 69a8fd742e..47deb17f1d 100644
--- a/lib/dialyzer/test/Makefile
+++ b/lib/dialyzer/test/Makefile
@@ -26,7 +26,7 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_tests_spec:
$(INSTALL_DIR) $(RELSYSDIR)
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
$(INSTALL_DATA) $(AUXILIARY_FILES) $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
cd $(RELSYSDIR);\
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/asn1 b/lib/dialyzer/test/r9c_SUITE_data/results/asn1
index ac83366bc8..571e562d0d 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/asn1
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/asn1
@@ -2,7 +2,7 @@
asn1ct.erl:1500: The variable Err can never match since previous clauses completely covered the type #type{}
asn1ct.erl:1596: The variable _ can never match since previous clauses completely covered the type 'ber_bin_v2'
asn1ct.erl:1673: The pattern 'all' can never match the type 'asn1_module' | 'exclusive_decode' | 'partial_decode'
-asn1ct.erl:672: The pattern <{'false', Result}, _, _> can never match the type <{'true','true'},atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()],[any()]>
+asn1ct.erl:672: The pattern <{'false', Result}, _, _> can never match the type <{'true','true'},atom() | binary() | [atom() | [any()] | char()],[any()]>
asn1ct.erl:909: Guard test is_atom(Ext::[49 | 97 | 98 | 100 | 110 | 115]) can never succeed
asn1ct_check.erl:1698: The pattern {'error', _} can never match the type [any()]
asn1ct_check.erl:2733: The pattern {'type', Tag, _, _, _, _} can never match the type 'ASN1_OPEN_TYPE' | {_,_} | {'fixedtypevaluefield',_,_}
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/inets b/lib/dialyzer/test/r9c_SUITE_data/results/inets
index fd5e36a3cd..6b16dba2ff 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/inets
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/inets
@@ -7,9 +7,6 @@ http_lib.erl:286: The call http_lib:close('ip_comm' | {'ssl',_},any()) will neve
http_lib.erl:424: The variable _ can never match since previous clauses completely covered the type any()
http_lib.erl:438: The variable _ can never match since previous clauses completely covered the type any()
http_lib.erl:99: Function getHeaderValue/2 will never be called
-httpc_handler.erl:322: Function status_continue/2 has no local return
-httpc_handler.erl:37: Function init_connection/2 has no local return
-httpc_handler.erl:65: Function next_response_with_request/2 has no local return
httpc_handler.erl:660: Function exit_session_ok/2 has no local return
httpc_manager.erl:145: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}}
httpc_manager.erl:160: The pattern {ErrorReply, State2} can never match the type {{'ok',number()},number(),#state{reqid::number()}}
@@ -27,7 +24,7 @@ httpd_manager.erl:933: Function acceptor_status/1 will never be called
httpd_request_handler.erl:374: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 66 | 98 | 100 | 103 | 105 | 111 | 116 | 121,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any())
httpd_request_handler.erl:378: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any())
httpd_request_handler.erl:401: The call httpd_response:send_status(Info::#mod{parsed_header::maybe_improper_list()},417,[32 | 77 | 97 | 100 | 101 | 104 | 108 | 110 | 111 | 116 | 119,...]) will never return since it differs in the 2nd argument from the success typing arguments: (#mod{socket_type::'ip_comm' | {'ssl',_}},100 | 301 | 304 | 400 | 401 | 403 | 404 | 412 | 414 | 416 | 500 | 501 | 503,any())
-httpd_request_handler.erl:644: The call lists:reverse(Fields0::{'error',_} | {'ok',[[any()]]}) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
+httpd_request_handler.erl:644: The call lists:reverse(Fields0::{'error',_} | {'ok',_}) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
httpd_request_handler.erl:645: Function will never be called
httpd_sup.erl:63: The variable Else can never match since previous clauses completely covered the type {'error',_} | {'ok',[any()],_,_}
httpd_sup.erl:88: The pattern {'error', Reason} can never match the type {'ok',_,_}
@@ -38,17 +35,17 @@ mod_auth_plain.erl:100: The variable _ can never match since previous clauses co
mod_auth_plain.erl:159: The variable _ can never match since previous clauses completely covered the type [any()]
mod_auth_plain.erl:83: The variable O can never match since previous clauses completely covered the type [any()]
mod_cgi.erl:372: The pattern {'http_response', NewAccResponse} can never match the type 'ok'
-mod_dir.erl:101: The call lists:flatten(nonempty_improper_list(atom() | binary() | [any()] | char(),atom())) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
+mod_dir.erl:101: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom())) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
mod_dir.erl:72: The pattern {'error', Reason} can never match the type {'ok',[[[any()] | char()],...]}
-mod_get.erl:135: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | binary() | [any()] | char()]>
-mod_head.erl:80: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]>
+mod_get.erl:135: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]>
+mod_head.erl:80: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]>
mod_htaccess.erl:460: The pattern {'error', BadData} can never match the type {'ok',_}
-mod_include.erl:193: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],maybe_improper_list()}
-mod_include.erl:195: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],maybe_improper_list()}
-mod_include.erl:197: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],maybe_improper_list()}
-mod_include.erl:201: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],maybe_improper_list()}
-mod_include.erl:692: The pattern <{'read', Reason}, Info, Path> can never match the type <{'open',atom()},#mod{},atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]>
-mod_include.erl:706: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]>
+mod_include.erl:193: The pattern {_, Name, {[], []}} can never match the type {[any()],[any()],string()}
+mod_include.erl:195: The pattern {_, Name, {PathInfo, []}} can never match the type {[any()],[any()],string()}
+mod_include.erl:197: The pattern {_, Name, {PathInfo, QueryString}} can never match the type {[any()],[any()],string()}
+mod_include.erl:201: The variable Gurka can never match since previous clauses completely covered the type {[any()],[any()],string()}
+mod_include.erl:692: The pattern <{'read', Reason}, Info, Path> can never match the type <{'open',atom()},#mod{},atom() | binary() | [atom() | [any()] | char()]>
+mod_include.erl:706: The pattern <{'enfile', _}, _Info, Path> can never match the type <atom(),#mod{},atom() | binary() | [atom() | [any()] | char()]>
mod_include.erl:716: Function read_error/3 will never be called
mod_include.erl:719: Function read_error/4 will never be called
mod_security_server.erl:386: The variable O can never match since previous clauses completely covered the type [any()]
diff --git a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
index e199581a0e..b0f4d12ae5 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
+++ b/lib/dialyzer/test/r9c_SUITE_data/results/mnesia
@@ -6,6 +6,9 @@ mnesia_bup.erl:111: The created fun has no local return
mnesia_bup.erl:574: Function fallback_receiver/2 has no local return
mnesia_bup.erl:967: Function uninstall_fallback_master/2 has no local return
mnesia_checkpoint.erl:1014: The variable Error can never match since previous clauses completely covered the type {'ok',#checkpoint_args{nodes::[any()],retainers::[any(),...]}}
+mnesia_checkpoint.erl:1209: Function system_continue/3 has no local return
+mnesia_checkpoint.erl:792: Function retainer_loop/1 has no local return
+mnesia_checkpoint.erl:894: The call sys:handle_system_msg(Msg::any(),From::any(),'no_parent','mnesia_checkpoint',[],Cp::#checkpoint_args{}) breaks the contract (Msg,From,Parent,Module,Debug,Misc) -> Void when is_subtype(Msg,term()), is_subtype(From,{pid(),Tag::_}), is_subtype(Parent,pid()), is_subtype(Module,module()), is_subtype(Debug,[dbg_opt()]), is_subtype(Misc,term()), is_subtype(Void,term())
mnesia_controller.erl:1666: The variable Tab can never match since previous clauses completely covered the type [any()]
mnesia_controller.erl:1679: The pattern {'stop', Reason, Reply, State2} can never match the type {'noreply',_} | {'reply',_,_} | {'stop','shutdown',#state{}}
mnesia_controller.erl:1685: The pattern {'noreply', State2, _Timeout} can never match the type {'reply',_,_}
@@ -15,6 +18,7 @@ mnesia_frag.erl:294: The call mnesia_frag:remote_collect(Ref::reference(),{'erro
mnesia_frag.erl:304: The call mnesia_frag:remote_collect(Ref::reference(),{'error',{'node_not_running',_}},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()]))
mnesia_frag.erl:312: The call mnesia_frag:remote_collect(Ref::reference(),LocalRes::{'error',_},[],OldSelectFun::fun(() -> [any()])) will never return since it differs in the 2nd argument from the success typing arguments: (reference(),'ok',[any()],fun(() -> [any()]))
mnesia_index.erl:52: The call mnesia_lib:other_val(Var::{_,'commit_work' | 'index' | 'setorbag' | 'storage_type' | {'index',_}},_ReASoN_::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any())
+mnesia_lib.erl:1028: The pattern {'EXIT', Reason} can never match the type [any()] | {'error',_}
mnesia_lib.erl:957: The pattern {'ok', {0, _}} can never match the type 'eof' | {'error',atom()} | {'ok',binary() | string()}
mnesia_lib.erl:959: The pattern {'ok', {_, Bin}} can never match the type 'eof' | {'error',atom()} | {'ok',binary() | string()}
mnesia_loader.erl:36: The call mnesia_lib:other_val(Var::{_,'access_mode' | 'cstruct' | 'db_nodes' | 'setorbag' | 'snmp' | 'storage_type'},Reason::any()) will never return since it differs in the 1st argument from the success typing arguments: ({_,'active_replicas' | 'where_to_read' | 'where_to_write'},any())
@@ -30,5 +34,6 @@ mnesia_schema.erl:1258: Guard test FromS::'disc_copies' | 'disc_only_copies' | '
mnesia_schema.erl:1639: The pattern {'false', 'mandatory'} can never match the type {'false','optional'}
mnesia_schema.erl:2434: The variable Reason can never match since previous clauses completely covered the type {'error',_} | {'ok',_}
mnesia_schema.erl:451: Guard test UseDirAnyway::'false' == 'true' can never succeed
+mnesia_text.erl:180: The variable T can never match since previous clauses completely covered the type {'error',{integer(),atom() | tuple(),_}} | {'ok',_}
mnesia_tm.erl:1522: Function commit_participant/5 has no local return
mnesia_tm.erl:2169: Function system_terminate/4 has no local return
diff --git a/lib/dialyzer/test/race_SUITE_data/results/extract_translations b/lib/dialyzer/test/race_SUITE_data/results/extract_translations
index f7d5abc6f5..62aa1aa511 100644
--- a/lib/dialyzer/test/race_SUITE_data/results/extract_translations
+++ b/lib/dialyzer/test/race_SUITE_data/results/extract_translations
@@ -1,5 +1,5 @@
-extract_translations.erl:140: The call ets:insert('files',{atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]) call in extract_translations.erl on line 135
+extract_translations.erl:140: The call ets:insert('files',{atom() | binary() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | binary() | [atom() | [any()] | char()]) call in extract_translations.erl on line 135
extract_translations.erl:146: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line 126
-extract_translations.erl:152: The call ets:insert('files',{atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | binary() | [atom() | binary() | [atom() | binary() | [any()] | char()] | char()]) call in extract_translations.erl on line 148
+extract_translations.erl:152: The call ets:insert('files',{atom() | binary() | [atom() | [any()] | char()]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('files',File::atom() | binary() | [atom() | [any()] | char()]) call in extract_translations.erl on line 148
extract_translations.erl:154: The call ets:insert('translations',{_,[]}) might have an unintended effect due to a possible race condition caused by its combination with the ets:lookup('translations',Str::any()) call in extract_translations.erl on line 126
diff --git a/lib/dialyzer/test/small_SUITE_data/results/flatten b/lib/dialyzer/test/small_SUITE_data/results/flatten
index 4571214e49..8aa44dd002 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/flatten
+++ b/lib/dialyzer/test/small_SUITE_data/results/flatten
@@ -1,2 +1,2 @@
-flatten.erl:17: The call lists:flatten(nonempty_improper_list(atom() | binary() | [any()] | char(),atom())) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
+flatten.erl:17: The call lists:flatten(nonempty_improper_list(atom() | [any()] | char(),atom())) will never return since it differs in the 1st argument from the success typing arguments: ([any()])
diff --git a/lib/dialyzer/test/small_SUITE_data/src/binary_lc_bug.erl b/lib/dialyzer/test/small_SUITE_data/src/binary_lc_bug.erl
new file mode 100644
index 0000000000..c1e82bfa59
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/binary_lc_bug.erl
@@ -0,0 +1,8 @@
+-module(test).
+
+-export([bin_compr/0]).
+
+bin_compr() ->
+% [ 0 || {N, V} <- [{a, b}] ]. % Works ok
+ << <<>> || {A, B} <- [{a, b}] >>. % Complains
+% << <<>> || X <- [{a, b}] >>. % Works ok
diff --git a/lib/dialyzer/test/small_SUITE_data/src/codec_can.erl b/lib/dialyzer/test/small_SUITE_data/src/codec_can.erl
new file mode 100644
index 0000000000..8abf872b37
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/codec_can.erl
@@ -0,0 +1,35 @@
+%%---------------------------------------------------------------------
+%% From: Peer Stritzinger
+%% Date: 1 May 2011
+%% Subject: Dialyzer v2.2.0 crash
+%%
+%% Binaries of the form <<_:N,_:_*M>> in specs resulted in a crash:
+%% dialyzer: Analysis failed with error: {{case_clause,8},
+%% [{erl_types,t_form_to_string,1},
+%% {erl_types,t_form_to_string,1},
+%% {dialyzer_contracts,contract_to_string_1,1},
+%% {dialyzer_contracts,extra_contract_warning,6},
+%% {dialyzer_contracts,picky_contract_check,7},
+%% because function erl_types:t_form_to_string/1 was not the inverse
+%% of erl_types:t_to_string/2.
+%%
+%% Fixed on the same date and send to OTP for inclusion.
+%%---------------------------------------------------------------------
+-module(codec_can).
+
+-export([recv/3, decode/1]).
+
+-record(can_pkt, {id, data :: binary(), timestamp}).
+
+-type can_pkt() :: #can_pkt{}.
+-type channel() :: atom() | pid() | {atom(),_}.
+
+-spec recv(<<_:64,_:_*8>>, fun((can_pkt()) -> R), channel()) -> R.
+recv(Packet, Fun, Chan) ->
+ #can_pkt{id = Can_id, data = Can_data} = P = decode(Packet),
+ Fun(P).
+
+-spec decode(<<_:64,_:_*8>>) -> #can_pkt{id::<<_:11>>,timestamp::char()}.
+decode(<<_:12, Len:4, Timestamp:16, 0:3, Id:11/bitstring, 0:18,
+ Data:Len/binary, _/binary>>) ->
+ #can_pkt{id = Id, data = Data, timestamp = Timestamp}.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/list_to_bitstring.erl b/lib/dialyzer/test/small_SUITE_data/src/list_to_bitstring.erl
new file mode 100644
index 0000000000..2da708cb15
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/list_to_bitstring.erl
@@ -0,0 +1,21 @@
+%%=====================================================================
+%% From: Ken Robinson
+%% Date: 28/04/2011, 17:26
+%%
+%% Program that produced borus "Function has no local return" warnings
+%% due to erlang:list_to_bitstring/1 having erroneous hard coded type
+%% information, namely accepting iolist() instead of bitstrlist().
+%% Fixed 29/04/2011.
+%%=====================================================================
+
+-module(list_to_bitstring).
+
+-export([l2bs/0, l2bs_ok/0]).
+
+%% This function was producing a warning
+l2bs() ->
+ erlang:list_to_bitstring([<<42>>, <<42:13>>]).
+
+%% while this one was ok.
+l2bs_ok() ->
+ erlang:list_to_bitstring([<<42>>, <<42,42>>]).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl b/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl
new file mode 100644
index 0000000000..5c24902590
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl
@@ -0,0 +1,42 @@
+%% Dialyzer couldn't infer that monitor_diskspace would go in an infinite loop
+%% instead of crashing due to the existence of list comprehensions that have a
+%% normal success typing. These were added to the monitor_diskspace's SCC and
+%% dialyzer_typesig didn't try to assign unit() to monitor_diskspace, as it
+%% required all the members of the SCC to return none().
+%%
+%% Testcase was submitted in erlang-questions mailing list by Prashanth Mundkur
+%% (http://erlang.org/pipermail/erlang-questions/2011-May/058063.html)
+
+-module(no_return_bug).
+-export([diskspace/1, monitor_diskspace/2, refresh_tags/1, monitor_launch/0]).
+
+-type diskinfo() :: {non_neg_integer(), non_neg_integer()}.
+
+-spec diskspace(nonempty_string()) -> {'ok', diskinfo()} | {'error', term()}.
+diskspace(Path) ->
+ case Path of
+ "a" -> {ok, {0,0}};
+ _ -> {error, error}
+ end.
+
+-spec monitor_diskspace(nonempty_string(),
+ [{diskinfo(), nonempty_string()}]) ->
+ no_return().
+monitor_diskspace(Root, Vols) ->
+ Df = fun(VolName) ->
+ diskspace(filename:join([Root, VolName]))
+ end,
+ NewVols = [{Space, VolName}
+ || {VolName, {ok, Space}}
+ <- [{VolName, Df(VolName)}
+ || {_OldSpace, VolName} <- Vols]],
+ monitor_diskspace(Root, NewVols).
+
+-spec refresh_tags(nonempty_string()) -> no_return().
+refresh_tags(Root) ->
+ {ok, _} = diskspace(Root),
+ refresh_tags(Root).
+
+monitor_launch() ->
+ spawn_link(fun() -> refresh_tags("abc") end),
+ spawn_link(fun() -> monitor_diskspace("root", [{{0,0}, "a"}]) end).
diff --git a/lib/dialyzer/test/small_SUITE_data/src/nowarnunused.erl b/lib/dialyzer/test/small_SUITE_data/src/nowarnunused.erl
new file mode 100644
index 0000000000..63daeee9e3
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/nowarnunused.erl
@@ -0,0 +1,7 @@
+-module(nowarnunused).
+
+-compile({nowarn_unused_function, return_error/2}).
+
+-spec return_error(integer(), any()) -> no_return().
+return_error(Line, Message) ->
+ throw({error, {Line, ?MODULE, Message}}).
diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk
index 53b6f8c553..10de07dfbb 100644
--- a/lib/dialyzer/vsn.mk
+++ b/lib/dialyzer/vsn.mk
@@ -1 +1 @@
-DIALYZER_VSN = 2.4.2
+DIALYZER_VSN = 2.4.3
diff --git a/lib/diameter/aclocal.m4 b/lib/diameter/aclocal.m4
index fcefdb7679..2abb47dba2 100644
--- a/lib/diameter/aclocal.m4
+++ b/lib/diameter/aclocal.m4
@@ -1,7 +1,7 @@
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2010. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-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
diff --git a/lib/diameter/autoconf/configure.vxworks b/lib/diameter/autoconf/configure.vxworks
index 70d7bdbaf2..33aa497680 100755
--- a/lib/diameter/autoconf/configure.vxworks
+++ b/lib/diameter/autoconf/configure.vxworks
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.general b/lib/diameter/autoconf/vxworks/sed.general
index f725a6f9ca..77b306aa0a 100644
--- a/lib/diameter/autoconf/vxworks/sed.general
+++ b/lib/diameter/autoconf/vxworks/sed.general
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_cpu32 b/lib/diameter/autoconf/vxworks/sed.vxworks_cpu32
index 163dd78897..5a1590e786 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_cpu32
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_cpu32
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc32 b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc32
index 5db28337c0..9104b24ed3 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc32
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc32
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2006-2010. All Rights Reserved.
+# Copyright Ericsson AB 2006-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603 b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603
index 40296b8f07..e1dd7c5afd 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2000-2010. All Rights Reserved.
+# Copyright Ericsson AB 2000-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603_nolongcall b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
index 2550432d1e..5d7673d323 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc603_nolongcall
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc860 b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc860
index cd7c9ff797..7a3c32df5b 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_ppc860
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_ppc860
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_simlinux b/lib/diameter/autoconf/vxworks/sed.vxworks_simlinux
index 6eb6f8ea92..56eae6507c 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_simlinux
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_simlinux
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+# Copyright Ericsson AB 2008-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_simso b/lib/diameter/autoconf/vxworks/sed.vxworks_simso
index 1d7413b484..6b845d31de 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_simso
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_simso
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2005-2010. All Rights Reserved.
+# Copyright Ericsson AB 2005-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/autoconf/vxworks/sed.vxworks_sparc b/lib/diameter/autoconf/vxworks/sed.vxworks_sparc
index ae26f234d2..6f637d8746 100644
--- a/lib/diameter/autoconf/vxworks/sed.vxworks_sparc
+++ b/lib/diameter/autoconf/vxworks/sed.vxworks_sparc
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/bin/diameterc b/lib/diameter/bin/diameterc
index cba664bfad..f5cf3ebc10 100755
--- a/lib/diameter/bin/diameterc
+++ b/lib/diameter/bin/diameterc
@@ -4,7 +4,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/diameter/configure.in b/lib/diameter/configure.in
index 76b15ced9b..9aca3859c5 100644
--- a/lib/diameter/configure.in
+++ b/lib/diameter/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1998-2010. All Rights Reserved.
+dnl Copyright Ericsson AB 1998-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
diff --git a/lib/diameter/doc/src/.gitignore b/lib/diameter/doc/src/.gitignore
new file mode 100644
index 0000000000..feeb378fd8
--- /dev/null
+++ b/lib/diameter/doc/src/.gitignore
@@ -0,0 +1,2 @@
+
+/depend.mk
diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile
index f2a91a88b7..1453138cb6 100644
--- a/lib/diameter/doc/src/Makefile
+++ b/lib/diameter/doc/src/Makefile
@@ -35,8 +35,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
include files.mk
+XML_REF_FILES = $(XML_REF1_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES)
+
XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) \
- $(XML_REF1_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES) \
+ $(XML_REF_FILES) \
$(XML_PART_FILES) $(XML_CHAPTER_FILES)
INTERNAL_HTML_FILES = $(TECHNICAL_DESCR_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -49,9 +51,7 @@ HTML_FILES = $(HTML_APP_FILES) $(HTML_EXTRA_FILES) $(HTML_PART_FILES)
INFO_FILE = ../../info
-HTML_REF_FILES = $(XML_REF1_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_REF4_FILES:%.xml=$(HTMLDIR)/%.html)
+HTML_REF_FILES = $(XML_REF_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_CHAPTER_FILES = $(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
@@ -98,6 +98,7 @@ html: gifs $(HTML_REF_MAN_FILE)
clean clean_docs: clean_pdf clean_html clean_man
rm -f errs core *~
+ rm -f depend.mk
clean_pdf:
rm -f $(PDFDIR)/*
@@ -118,7 +119,9 @@ $(INDEX_TARGET): $(INDEX_SRC) $(APP_FILE)
s/%UP_ONE_LEVEL%/..\/..\/..\/doc\/index.html/; \
s/%OFF_PRINT%/pdf\/diameter-$(VSN).pdf/' $< > $@
-depend debug opt:
+depend: depend.mk
+
+debug opt:
info:
@echo "->Makefile<-"
@@ -181,17 +184,13 @@ release_docs_spec: $(LOCAL)docs
release_spec:
-$(HTMLDIR)/diameter_app.html: diameter_app.xml
-$(HTMLDIR)/diameter_compile.html: diameter_compile.xml
-$(HTMLDIR)/diameter_debug.html: diameter_debug.xml
-$(HTMLDIR)/diameter_dict.html: diameter_dict.xml
-$(HTMLDIR)/diameter_intro.html: diameter_intro.xml
-$(HTMLDIR)/diameter_run.html: diameter_run.xml
-$(HTMLDIR)/diameter.html: diameter.xml
-$(HTMLDIR)/diameter_tcp.html: diameter_tcp.xml
-$(HTMLDIR)/diameter_transport.html: diameter_transport.xml
-$(HTMLDIR)/diameter_soc.html: diameter_soc.xml
-$(HTMLDIR)/diameter_sctp.html: diameter_sctp.xml
+depend.mk: depend.sed $(XML_REF_FILES) $(XML_CHAPTER_FILES) Makefile
+ (for f in $(XML_REF_FILES) $(XML_CHAPTER_FILES); do \
+ sed -f $< $$f | sed "s@%FILE%@`basename $$f .xml`@g"; \
+ done) \
+ > $@
+
+-include depend.mk
.PHONY: clean clean_html clean_man clean_pdf \
depend debug opt info \
diff --git a/lib/diameter/doc/src/depend.sed b/lib/diameter/doc/src/depend.sed
new file mode 100644
index 0000000000..5973c4586e
--- /dev/null
+++ b/lib/diameter/doc/src/depend.sed
@@ -0,0 +1,34 @@
+#
+# %CopyrightBegin%
+#
+# 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.
+#
+# %CopyrightEnd%
+
+#
+# Generate dependencies for html output. The output is further
+# massaged in Makefile.
+#
+
+/^<com>\([^<]*\)<\/com>/b rf
+/^<module>\([^<]*\)<\/module>/b rf
+
+/^<chapter>/!d
+
+s@@$(HTMLDIR)/%FILE%.html: %FILE%.xml@
+q
+
+:rf
+s@@$(HTMLDIR)/\1.html: %FILE%.xml@
+q
diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml
index 9774183a2a..36b6cbf0cf 100644
--- a/lib/diameter/doc/src/diameter.xml
+++ b/lib/diameter/doc/src/diameter.xml
@@ -415,6 +415,12 @@ eval(F) ->
Evaluating an evaluable() <c>E</c> on an argument list <c>A</c>
is meant in the sense of <c>eval([E|A])</c>.</p>
+<p>
+Beware of using local funs (that is, fun expressions not of the
+form <c>fun Module:Name/Arity</c>) in situations in which the fun is
+not short-lived and code is to be upgraded at runtime since any
+processes retaining such a fun will have a reference to old code.</p>
+
<marker id="peer_filter"/>
</item>
@@ -712,7 +718,7 @@ transport.</p>
<p>
Unrecognized options are silently ignored but are returned unmodified
by <seealso
-marker="#service_info_1">service_info/1,2</seealso> and can be referred to
+marker="#service_info">service_info/2</seealso> and can be referred to
in predicate functions passed to <seealso
marker="#remove_transport">remove_transport/2</seealso>.</p>
@@ -739,7 +745,9 @@ marker="#remove_transport">remove_transport/2</seealso>.</p>
</type>
<desc>
<p>
-Add transport capability to a service.
+Add transport capability to a service.</p>
+
+<p>
The service will start a transport process(es) in order to establish a
connection with the peer, either by connecting to the peer
(<c>connect</c>) or by accepting incoming connection requests
@@ -761,10 +769,8 @@ handling of DWR/DWA and required by RFC 3539 as well as for DPR/DPA.</p>
<p>
The returned reference uniquely identifies the transport within the
scope of the service.
-Not that the function returns before a transport connection has been
-established.</p>
-
-<p>
+Note that the function returns before a transport connection has been
+established.
It is not an error to add a transport to a service that has not yet
been configured: a service can be started after configuring
transports.</p>
@@ -776,7 +782,7 @@ transports.</p>
<!-- ===================================================================== -->
<func>
-<name>call(SvcName, App, Request, Options) -> Answer | {error, Reason}</name>
+<name>call(SvcName, App, Request, Options) -> ok | Answer | {error, Reason}</name>
<fsummary>Send a Diameter request message.</fsummary>
<type>
<v>SvcName = service_name()</v>
@@ -794,15 +800,19 @@ Send a Diameter request message and possibly return the answer or error.</p>
defined and callbacks to the corresponding callback module
will follow as described below and in <seealso
marker="diameter_app">diameter_app(3)</seealso>.
-The call returns either when an answer message is received from the
-peer or an error occurs, unless the <c>detach</c> option has been
-specified.
-If <c>detach</c> is not specified then the form of an <c>Answer</c> is
-as returned from a <seealso
-marker="diameter_app#handle_answer">handle_answer/4</seealso> or
+Unless the <c>detach</c> option has been specified to cause an earlier
+return, the call returns either when an answer message is received
+from the peer or an error occurs.
+In the case of an answer, the return value is as returned by a
<seealso
+marker="diameter_app#handle_answer">handle_answer/4</seealso>
+callback.
+In the case of an error, whether or not the error is returned directly
+by diameter or from a <seealso
marker="diameter_app#handle_error">handle_error/4</seealso>
-callback.</p>
+callback depends on whether or not the outgoing request is
+successfully encoded for transmission from the peer, the cases being
+documented below.</p>
<p>
If there are no suitable peers, or if
@@ -888,7 +898,8 @@ attempt to send the request over the transport.</p>
<p>
Note that <c>{error, encode}</c> is the only return value which
-guarantees that the request has not been sent over the transport.</p>
+guarantees that the request has <em>not</em> been sent over the
+transport.</p>
<marker id="origin_state_id"/>
</desc>
@@ -902,9 +913,11 @@ guarantees that the request has not been sent over the transport.</p>
<desc>
<p>
Return a reasonable value for use as Origin-State-Id in
-outgoing messages.
-The value returned is the number of seconds since 19680120T031408Z
-(the first value that can be encoded as a Time())
+outgoing messages.</p>
+
+<p>
+The value returned is the number of seconds since 19680120T031408Z,
+the first value that can be encoded as a Diameter Time(),
at the time the diameter application was started.</p>
<marker id="remove_transport"/>
@@ -959,25 +972,7 @@ DPA or timeout.</p>
<!-- TODO: document the timeout value, possibly make configurable. -->
-<marker id="service_info_1"/>
-</desc>
-</func>
-
-<!-- ===================================================================== -->
-
-<func>
-<name>service_info(SvcName) -> Info</name>
-<fsummary>Return information about a started service.</fsummary>
-<type>
-<v>SvcName = service_name()</v>
-<v>Info = [{Item, Value}]</v>
-</type>
-<desc>
-<p>
-Return information about a started service.
-Equivalent to <c>service_info(SvcName, all)</c>.</p>
-
-<marker id="service_info_2"/>
+<marker id="service_info"/>
</desc>
</func>
@@ -992,7 +987,7 @@ Equivalent to <c>service_info(SvcName, all)</c>.</p>
</type>
<desc>
<p>
-Return specific information about a started service.</p>
+Return information about a started service.</p>
<marker id="services"/>
</desc>
@@ -1018,17 +1013,36 @@ Return the list of started services.</p>
<func>
<name>session_id(Ident) -> OctetString()</name>
-<fsummary>Return a value for a Session-Id AVP</fsummary>
+<fsummary>Return a value for a Session-Id AVP.</fsummary>
<type>
<v>Ident = DiameterIdentity()</v>
</type>
<desc>
<p>
-Return a value for a Session-Id AVP.
+Return a value for a Session-Id AVP.</p>
+
+<p>
The value has the form required by section 8.8 of RFC 3588.
Ident should be the Origin-Host of the peer from which
the message containing the returned value will be sent.</p>
+<marker id="start"/>
+</desc>
+</func>
+
+<!-- ===================================================================== -->
+<func>
+<name>start() -> ok | {error, Reason}</name>
+<fsummary>Start the diameter application.</fsummary>
+<desc>
+<p>
+Start the diameter application.</p>
+
+<p>
+The diameter application must be started before starting a service.
+In a production system this will typically be accomplished by a boot
+file, not by calling <c>start/0</c> explicitly.</p>
+
<marker id="start_service"/>
</desc>
</func>
@@ -1036,7 +1050,7 @@ the message containing the returned value will be sent.</p>
<!-- ===================================================================== -->
<func>
<name>start_service(SvcName, Options) -> ok | {error, Reason}</name>
-<fsummary>Start a Diameter service</fsummary>
+<fsummary>Start a Diameter service.</fsummary>
<type>
<v>SvcName = service_name()</v>
<v>Options = [service_opt()]</v>
@@ -1044,7 +1058,9 @@ the message containing the returned value will be sent.</p>
</type>
<desc>
<p>
-Start a diameter service.
+Start a diameter service.</p>
+
+<p>
A service defines a locally-implemented Diameter peer, specifying the
capabilities of the peer to be used during capabilities exchange and
the Diameter applications that it supports.
@@ -1057,8 +1073,23 @@ marker="#add_transport">add_transport/2</seealso>.</p>
<!-- ===================================================================== -->
<func>
+<name>stop() -> ok | {error, Reason}</name>
+<fsummary>Stop the diameter application.</fsummary>
+<desc>
+<p>
+Stop the diameter application.</p>
+
+<p>
+</p>
+
+<marker id="stop_service"/>
+</desc>
+</func>
+
+<!-- ===================================================================== -->
+<func>
<name>stop_service(SvcName) -> ok | {error, Reason}</name>
-<fsummary>Stops a Diameter service.</fsummary>
+<fsummary>Stop a Diameter service.</fsummary>
<type>
<v>SvcName = service_name()</v>
<v>Reason = term()</v>
@@ -1075,7 +1106,7 @@ Stop a diameter service.</p>
<func>
<name>subscribe(SvcName) -> true</name>
-<fsummary>Subscribe to event messages from a service.</fsummary>
+<fsummary>Subscribe to event messages.</fsummary>
<type>
<v>SvcName = service_name()</v>
</type>
@@ -1095,7 +1126,7 @@ that does not yet exist.</p>
<func>
<name>unsubscribe(SvcName) -> true</name>
-<fsummary></fsummary>
+<fsummary>Unsubscribe to event messages.</fsummary>
<type>
<v>SvcName = service_name()</v>
</type>
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index c2fecce768..fc359b9d1d 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -47,23 +47,12 @@ configures one of more Diameter applications, each of whose
configuration specifies a callback that handles messages specific to
its application.
The messages and AVPs of the Diameter application are defined in a
-specification file whose format is documented in
+dictionary file whose format is documented in
<seealso marker="diameter_dict">diameter_dict(4)</seealso>
while the callback module is documented here.
The callback module implements the Diameter application-specific
functionality of a service.</p>
-<note>
-<p>
-The arities of the callback functions below assume no extra arguments.
-All functions will also be passed any extra arguments configured with
-the callback module itself when calling <seealso
-marker="diameter#start_service">diameter:start_service/2</seealso>
-and, except for peer_up, peer_down and handle_request, any extra
-arguments passed to <seealso
-marker="diameter#call">diameter:call/4</seealso>.</p>
-</note>
-
<p>
A callback module must export all of the functions documented below.
The functions themselves are of three distinct flavours:</p>
@@ -72,8 +61,8 @@ The functions themselves are of three distinct flavours:</p>
<item>
<p>
<seealso marker="#peer_up">peer_up/3</seealso> and
-<seealso marker="#peer_down">peer_down/3</seealso> signal the attainment
-or loss of communicativity with a Diameter peer.</p>
+<seealso marker="#peer_down">peer_down/3</seealso> signal the
+attainment or loss of connectivity with a Diameter peer.</p>
</item>
<item>
@@ -98,6 +87,17 @@ is called in response to an incoming Diameter request message.</p>
</description>
+<note>
+<p>
+The arities given for the the callback functions here assume no extra
+arguments.
+All functions will also be passed any extra arguments configured with
+the callback module itself when calling <seealso
+marker="diameter#start_service">diameter:start_service/2</seealso>
+and, for the call-specific callbacks, any extra arguments passed to
+<seealso marker="diameter#call">diameter:call/4</seealso>.</p>
+</note>
+
<!-- ===================================================================== -->
<!-- ===================================================================== -->
@@ -131,8 +131,8 @@ a message as defined in a dictionary file is encoded as a record with
one field for each component AVP.
Equivalently, a message can also be encoded as a list whose head is
the atom-valued message name (the record name minus any
-prefix in the dictionary file) and whose tail is a list of
-<c>{FieldName, FieldValue}</c> pairs.</p>
+prefix specified in the relevant dictionary file) and whose tail is a
+list of <c>{FieldName, FieldValue}</c> pairs.</p>
<p>
A third representation allows a message to be specified as a list
@@ -144,7 +144,8 @@ as directed by the return value of a
callback.
It differs from the other other two in that it bypasses the checks for
messages that do not agree with their definitions in the dictionary in
-question: messages are sent exactly as specified.</p>
+question (since relays agents must handle arbitrary request): messages
+are sent exactly as specified.</p>
</item>
@@ -153,8 +154,8 @@ question: messages are sent exactly as specified.</p>
<p>
A container for incoming and outgoing Diameters message that's passed
through encode/decode and transport.
-Defined in diameter.hrl.
-Fields should not be altered except as documented.</p>
+Fields of a packet() record should not be set in return values except
+as documented.</p>
</item>
<tag><c>peer_ref() = term()</c></tag>
@@ -236,18 +237,18 @@ the callback module in question has been configured.</p>
<desc>
<p>
Invoked when a transport connection has been lost following a previous
-call to <seealso marker="peer_up">peer_up/3</seealso>.</p>
+call to <seealso marker="#peer_up">peer_up/3</seealso>.</p>
<marker id="pick_peer"/>
</desc>
</func>
<func>
-<name>Mod:pick_peer(Cands, Reserved, SvcName, State)
+<name>Mod:pick_peer(Candidates, Reserved, SvcName, State)
-> {ok, Peer} | {Peer, NewState} | false</name>
<fsummary>Select a target peer for an outgoing request.</fsummary>
<type>
-<v>Cands = [Peer]</v>
+<v>Candidates = [peer()]</v>
<v>Peer = peer() | false</v>
<v>SvcName = service_name()</v>
<v>State = NewState = state()</v>
@@ -266,11 +267,9 @@ marker="diameter#start_service">diameter:start_service/2</seealso>.</p>
<p>
The candidate peers list will only include those
which are selected by any <c>filter</c> option specified in the call to
-<seealso marker="diameter#call">diameter:call/4</seealso>.</p>
-<!--
-The local candidates are those whose transport process is executing on
-the local Erlang node, the remote list those that are available on
-other nodes.</p> -->
+<seealso marker="diameter#call">diameter:call/4</seealso>, and only
+those which have indicated support for the Diameter application in
+question.</p>
<p>
The return values <c>false</c> and <c>{false, State}</c> are
@@ -326,13 +325,14 @@ A returned packet() should set the request to be encoded in its
to pass information to the transport module.
Extra arguments passed to <seealso
marker="diameter#call">diameter:call/4</seealso> can be used to
-communicate transport data to the callback.</p>
-
-<p>
-Any returned packet() can set the <c>header</c> field to a
+communicate transport data to the callback.
+A returned packet() can also set the <c>header</c> field to a
<c>diameter_header</c> record in order to specify values that should
-be preserved in the outgoing request.
-A specified <c>message_length</c> is ignored.</p>
+be preserved in the outgoing request, although this should typically
+not be necessary and allows the callback to set header values
+inappropriately.
+A returned <c>length</c>, <c>cmd_code</c> or <c>application_id</c> is
+ignored.</p>
<p>
Returning <c>{discard, Reason}</c> causes the request to be aborted
@@ -361,7 +361,7 @@ Invoked to return a request for encoding and retransmission.
Has the same role as <seealso
marker="#prepare_request">prepare_request/3</seealso> in the case that
a peer connection is lost an an alternate peer selected but the
-Packet passed to <c>prepare_retransmit/3</c> is as returned by
+argument packet() is as returned by the initial
<c>prepare_request/3</c>.</p>
<p>
@@ -391,10 +391,12 @@ discarded}</c>.</p>
Invoked when an answer message is received from a peer.
The return value is returned from the call to <seealso
marker="diameter#call">diameter:call/4</seealso> for which the
-callback takes place.</p>
+callback takes place unless the <c>detach</c> option was
+specified.</p>
<p>
-The decoded answer record is in the <c>msg</c> field of <c>Packet</c>,
+The decoded answer record is in the <c>msg</c> field of the argument
+packet(),
the undecoded binary in the <c>packet</c> field.
<c>Request</c> is the outgoing request message as was returned from
<seealso marker="#prepare_request">prepare_request/3</seealso> or
@@ -414,8 +416,10 @@ By default, an incoming answer message that cannot be successfully
decoded causes the request process in question to fail, causing the
relevant call to <seealso
marker="diameter#call">diameter:call/4</seealso>
-to return <c>{error, failure}</c>.
-There is no <c>handle_error/4</c> callback in this case.
+to return <c>{error, failure} (unless the <c>detach</c> option was
+specified)</c>.
+In particular, there is no <c>handle_error/4</c> callback in this
+case.
Application configuration may change this behaviour as described for
<seealso
marker="diameter#start_service">diameter:start_service/2</seealso>.</p>
@@ -440,7 +444,8 @@ Invoked when an error occurs before an answer message is received from
a peer in response to an outgoing request.
The return value is returned from the call to <seealso
marker="diameter#call">diameter:call/4</seealso> for which the
-callback takes place.</p>
+callback takes place (unless the <c>detach</c> option was
+specified).</p>
<p>
Reason <c>timeout</c> indicates that an answer message has not been
@@ -449,8 +454,7 @@ Reason <c>failover</c> indicates
that the transport connection to the peer to which the request has
been sent has been lost but that not alternate node was available,
possibly because a <seealso marker="#pick_peer">pick_peer/4</seealso>
-callback returned false.
-</p>
+callback returned false.</p>
<marker id="handle_request"/>
</desc>
@@ -463,40 +467,33 @@ callback returned false.
<v>Packet = packet()</v>
<v>SvcName = term()</v>
<v>Peer = peer()</v>
-<v>Action = Reply | NoReply | Relay | {eval, Action, ContF}</v>
+<v>Action = Reply | {relay, Opts} | discard | {eval, Action, ContF}</v>
<v>Reply = {reply, message()}
- | {protocol_error, ResultCode}</v>
-<v>NoReply = discard</v>
-<v>Relay = {relay, Opts}</v>
-<v>Opts = list()</v>
+ | {protocol_error, 3000..3999}</v>
+<v>Opts = diameter:call_opts()</v>
<v>ContF = diameter:evaluable()</v>
-<v>ResultCode = 3000..3999</v>
</type>
<desc>
<p>
-Invoked when a request message is received from a peer.</p>
-
-<p>
+Invoked when a request message is received from a peer.
The application in which the callback takes place (that is, the
callback module as configured with <seealso
marker="diameter#start_service">diameter:start_service/2</seealso>)
is determined by the Application Identifier in the header of the
-incoming Diameter request message, the selected module being the one
+incoming request message, the selected module being the one
whose corresponding <seealso
marker="diameter_dict#MESSAGE_RECORDS">dictionary</seealso> declares
-itself as defining the application in question, or the RFC 3588 relay
-application if the specific application is unsupported but the relay
-application has been advertised.</p>
+itself as defining either the application in question or the Relay
+application.</p>
<p>
-The packet() in which the incoming request is communicated has the
-following signature.</p>
+The argument packet() has the following signature.</p>
<code>
#diameter_packet{header = #diameter_header{},
avps = [#diameter_avp{}],
msg = record() | undefined,
- errors = [integer() | {integer(), #diameter_avp{}}],
+ errors = ['Unsigned32'() | {'Unsigned32'(), #diameter_avp{}}],
bin = binary(),
transport_data = term()}
</code>
@@ -509,12 +506,16 @@ in <seealso
marker="diameter_dict#MESSAGE_RECORDS">diameter_dict(4)</seealso>.</p>
<p>
-The <c>errors</c> field specifies any non-protocol errors that were
-encountered in decoding the request and can be returned in a
-<c>reply</c> tuple to have diameter set the Result-Code and Failed-AVP
-AVP's appropriately.
-The list is empty if the request has been received in the relay
-application.</p>
+The <c>errors</c> field specifies any Result-Code's identifying errors
+that were encountered in decoding the request.
+In this case diameter will set both Result-Code and
+Failed-AVP AVP's in a returned
+answer message() before sending it to the peer:
+the returned message() need only set any other required AVP's.
+Note that the errors detected by diameter are all of the 5xxx series
+(Permanent Failures).
+The <c>errors</c> list is empty if the request has been received in
+the relay application.</p>
<p>
The <c>transport_data</c> field contains an arbitrary term passed into
@@ -525,34 +526,59 @@ sent back to the transport process unless another value is explicitly
specified.</p>
<p>
-The semantics of each of the possible return values are as follows.
-(TODO: more.)</p>
+The semantics of each of the possible return values are as follows.</p>
<taglist>
-<tag><c>{reply, Answer}</c></tag>
+<tag><c>{reply, message()}</c></tag>
<item>
<p>
Send the specified answer message to the peer.</p>
</item>
-<tag><c>{relay, Opts}</c></tag>
+<tag><c>{protocol_error, 3000..3999}</c></tag>
<item>
<p>
-Relay a request to another peer.</p>
-</item>
-
-<tag><c>{protocol_error, ResultCode}</c></tag>
-<item>
+Send an answer message to the peer containing the specified
+protocol error.
+Equivalent to</p>
+<code>
+{reply, ['answer-message' | Avps]
+</code>
<p>
-Send an answer message to the peer containing the specified 3xxx
-protocol error.</p>
+where <c>Avps</c> sets the Origin-Host, Origin-Realm, the specified
+Result-Code and (if the request sent one) Session-Id AVP's.</p>
<p>
-RFC 3588 mandates that only answers with a 3xxx series
+Note that RFC 3588 mandates that only answers with a 3xxx series
Result-Code (protocol errors) may set the E bit.
-Returning a non-3xxx value in a <c>{protocol_error, ResultCode}</c>
-tuple will cause the request process in question to fail.</p>
+Returning a non-3xxx value in a <c>protocol_error</c> tuple
+will cause the request process in question to fail.</p>
+</item>
+
+<tag><c>{relay, Opts}</c></tag>
+<item>
+<p>
+Relay a request to another peer.
+The appropriate Route-Record AVP will be added to the relayed request
+by diameter and <seealso marker="#pick_peer">pick_peer/4</seealso>
+and <seealso marker="#prepare_request">prepare_request/3</seealso>
+callback will take place just as if <seealso
+marker="diameter#call">diameter:call/4</seealso> had been called
+explicitly.
+However, returning a <c>relay</c> tuple also causes the End-to-End
+Identifier to be preserved in the header of the relayed request as
+required by RFC 3588.</p>
+
+<p>
+The returned <c>Opts</c> should not specify <c>detach</c> and
+the <seealso marker="#handle_answer">handle_answer/4</seealso>
+callback following from a relayed request must return its first
+argument, the <c>diameter_packet</c> record containing the answer
+message.
+Note that the <c>extra</c> option can be specified to supply arguments
+that can distinguish the relay case from others if so desired,
+although the form of the request message may be sufficient.</p>
</item>
<tag><c>discard</c></tag>
@@ -565,14 +591,14 @@ Discard the request.</p>
<item>
<p>
Handle the request as if <c>Action</c> has been returned and then
-evaluate the evaluable() <c>ContF</c> in the request process.</p>
+evaluate <c>ContF</c> in the request process.</p>
</item>
</taglist>
<p>
Note that diameter will respond to protocol errors in an incoming
-request without invoking the a <c>handle_request/3</c> callback.</p>
+request without invoking <c>handle_request/3</c>.</p>
</desc>
</func>
diff --git a/lib/diameter/doc/src/diameter_dict.xml b/lib/diameter/doc/src/diameter_dict.xml
index 5bc3cab9e4..e7c530f1b8 100644
--- a/lib/diameter/doc/src/diameter_dict.xml
+++ b/lib/diameter/doc/src/diameter_dict.xml
@@ -48,37 +48,41 @@ to encode and decode its messages and AVP's.
The dictionary module is in turn generated from a file that defines
these messages and AVP's.
The format of such a file is defined in
-<seealso marker="#FILE_FORMAT">FILE FORMAT</seealso> below.</p>
+<seealso marker="#FILE_FORMAT">FILE FORMAT</seealso> below.
+Users add support for their specific applications by creating
+dictionary files, compiling them to Erlang modules using
+<seealso marker="diameterc">diameterc</seealso> and configuring the
+resulting dictionaries modules on a service.</p>
<p>
-The codec generation also results in an hrl that defines records
+The codec generation also results in a hrl file that defines records
for the messages and grouped AVP's defined for the application, these
-records being what a user of the diameter application sends and
-receives.
+records being what a user of the diameter application sends and receives.
+(Modulo other available formats as discussed in <seealso
+marker="diameter_app">diameter_app(3)</seealso>.)
These records and the underlying Erlang data types corresponding to
Diameter data formats are discussed in <seealso
marker="#MESSAGE_RECORDS">MESSAGE RECORDS</seealso> and <seealso
-marker="#DATA_TYPES">DATA TYPES</seealso> respectively.</p>
-
-<!-- TODO: Need some reserved dictionary for agents that shouldn't -->
-<!-- know about specific applications. -->
-
-<p>
-The diameter application defines the base application of RFC 3588 in
-the file diameter_gen_base_rfc3588.dia, and
-this is the only application that diameter itself has any specific
-knowledge of.
-Other applications are callback modules configured for an application
-as far as diameter is concerned.</p>
-
-<p>
-A generated hrl also contains defines for the values of defined for
+marker="#DATA_TYPES">DATA TYPES</seealso> respectively.
+The generated hrl also contains defines for the possible values of
AVPs of type Enumerated.</p>
<p>
-See <seealso marker="diameter_compile">diameterc</seealso> for a
-utility that transforms dictionary files into codec modules needed
-at runtime.</p>
+The diameter application includes three dictionary modules
+corresponding to applications defined in section 2.4 of RFC 3588:
+<c>diameter_gen_base_rfc3588</c> for the Diameter Common Messages
+application with application identifier 0,
+<c>diameter_gen_accounting</c> for the Diameter Base Accounting
+application with application identifier 3 and
+<c>diameter_gen_relay</c>the Relay application with application
+identifier 0xFFFFFFFF.
+The Common Message and Relay applications are the only applications
+that diameter itself has any specific knowledge of.
+The Common Message application is used for messages that diameter
+itself handles: CER/CEA, DWR/DWA and DPR/DPA.
+The Relay application is given special treatment with regard to
+encode/decode since the messages and AVP's it handles are not specifically
+defined.</p>
<marker id="FILE_FORMAT"/>
</description>
@@ -89,7 +93,7 @@ at runtime.</p>
<title>FILE FORMAT</title>
<p>
-A specification file consists of distinct sections.
+A dictionary file consists of distinct sections.
Each section starts with a line consisting of a tag
followed by zero or more arguments.
Each section ends at the the start of the next section or end of file.
@@ -101,7 +105,7 @@ quantity is insignificant.</p>
<p>
The tags, their arguments and the contents of each corresponding
section are as follows.
-Each section can occur only once unless otherwise specified.
+Each section can occur at most once unless otherwise specified.
The order in which sections are specified is unimportant.</p>
<taglist>
@@ -111,6 +115,7 @@ The order in which sections are specified is unimportant.</p>
<p>
Defines the integer Number as the Diameter Application Id of the
application in question.
+Required if the dictionary defines <c>@messages</c>.
The section has empty content.</p>
<p>
@@ -223,7 +228,7 @@ The section content is empty.</p>
<p>
Can occur 0 or more times (with different values of Mod) but all
dictionaries should typically inherit RFC3588 AVPs from
-diameter_gen_base_rfc3588.</p>
+<c>diameter_gen_base_rfc3588</c>.</p>
<p>
Example:</p>
@@ -248,7 +253,7 @@ M and P characters indicating the flags to be
set on an outgoing AVP or a single - (minus) character if none are to
be set.
Type identifies either an AVP Data Format as defined in <seealso
-marker="DATA_TYPES">DATA TYPES</seealso> below or a
+marker="#DATA_TYPES">DATA TYPES</seealso> below or a
type as defined by a <c>@custom_types</c> tag.</p>
<p>
@@ -263,7 +268,8 @@ Requested-Information 353 Enumerated V
<p>
Note that the P flag has been deprecated by the Diameter Maintenance
-and Extensions Working Group of the IETF.</p>
+and Extensions Working Group of the IETF: diameter will set the P flag
+to 0 as mandated by the current draft standard.</p>
</item>
@@ -365,7 +371,11 @@ Integer values can be prefixed with 0x to be interpreted as
hexidecimal.</p>
<p>
-Can occur 0 or more times (with different values of Name).</p>
+Can occur 0 or more times (with different values of Name).
+The AVP in question can be defined in an inherited dictionary in order
+to introduce additional values.
+An AVP so extended must be referenced by in a <c>@messages</c> or
+<c>@grouped</c> section.</p>
<p>
Example:</p>
@@ -446,7 +456,7 @@ as values of the types defined here.
Values are passed to <seealso
marker="diameter#call">diameter:call/4</seealso>
in a request record when sending a request, returned in a resulting
-answer record and passed to a diameter_app(3) <seealso
+answer record and passed to a <seealso
marker="diameter_app#handle_request">handle_request</seealso>
callback upon reception of an incoming request.</p>
@@ -476,8 +486,8 @@ Grouped() = record()
<p>
On encode, an OctetString() can be specified as an iolist(),
excessively large floats (in absolute value) are equivalent to
-infinity or '-infinity' and excessively large integers result in
-encode failure.
+<c>infinity</c> or <c>'-infinity'</c> and excessively large integers
+result in encode failure.
The records for grouped AVPs are as discussed in the previous
section.</p>
@@ -583,7 +593,7 @@ QoSFilterRule() = OctetString()
</code>
<p>
-Values of these types are not parsed by diameter.</p>
+Values of these types are not currently parsed by diameter.</p>
</section>
@@ -594,7 +604,9 @@ Values of these types are not parsed by diameter.</p>
<title>SEE ALSO</title>
<p>
-<seealso marker="diameter_util">diameterc(1)</seealso></p>
+<seealso marker="diameterc">diameterc(1)</seealso>,
+<seealso marker="diameter">diameter(3)</seealso>,
+<seealso marker="diameter_app">diameter_app(3)</seealso></p>
</section>
diff --git a/lib/diameter/doc/src/diameter_examples.xml b/lib/diameter/doc/src/diameter_examples.xml
index 344b237866..966d1f1eee 100644
--- a/lib/diameter/doc/src/diameter_examples.xml
+++ b/lib/diameter/doc/src/diameter_examples.xml
@@ -36,5 +36,10 @@ under the License.
<!-- ===================================================================== -->
+<p>
+To be written.
+Example code can be found in the diameter application's
+<c>examples</c> subdirectory.</p>
+
</chapter>
diff --git a/lib/diameter/doc/src/diameter_intro.xml b/lib/diameter/doc/src/diameter_intro.xml
index 0009b2b77d..ef08002a8b 100644
--- a/lib/diameter/doc/src/diameter_intro.xml
+++ b/lib/diameter/doc/src/diameter_intro.xml
@@ -36,10 +36,60 @@ under the License.
<p>
The diameter application is an implementation of the Diameter protocol
as defined by RFC 3588.
-It supports arbitrary Diameter applications by allowing a client to
-specify the commands and AVP's to be supported and has support for
-implementing all roles defined in the RFC: client, server and agent.
-</p>
+It supports arbitrary Diameter applications by way of a
+<em>dictionary</em> interface that allows messages and AVP's to be
+defined and input into diameter as configuration.
+It has support for all roles defined in the RFC: client, server and
+agent.
+This chapter provides a short overview of the application.</p>
+
+<p>
+A Diameter peer is implemented by configuring a <em>service</em> and
+one or more <em>transports</em> using the interface module
+<seealso marker="diameter">diameter</seealso>.
+The service configuration defines the Diameter applications to be
+supported by the peer and, typically, the capabilities that it should
+send to remote peers at capabilities exchange upon the establishment
+of transport connections.
+A transport is configured on a service and provides protocol-specific
+send/receive functionality by way of a transport interface defined by
+diameter and implemented by a transport module.
+The diameter application provides two transport modules: <seealso
+marker="diameter_tcp">diameter_tcp</seealso> and <seealso
+marker="diameter_sctp">diameter_sctp</seealso> for transport over TCP
+(using <c>gen_tcp</c>) and SCTP (using <c>gen_sctp</c>) respectively.
+Other transports can be provided by any module that implements
+diameter's <seealso marker="diameter_transport">transport
+interface</seealso>.</p>
+
+<p>
+While a service typically implements a single Diameter peer (as
+identified by an Origin-Host AVP), transports can themselves be
+associated with capabilities AVP's so that a single service be used to
+implement more than one Diameter peer.</p>
+
+<p>
+Each Diameter application defined on a service is configured with a
+callback module that implements the <seealso
+marker="diameter_app">application interface</seealso> through which
+diameter communicates the connectivity of remote peers, requests peer
+selection for outgoing requests, and communicates the reception of
+incoming Diameter request and answer messages.
+An application using diameter implements these application callback
+modules to provide the functionality of the Diameter peer(s) it
+implements.</p>
+
+<p>
+Each Diameter application is also configured with one or more
+dictionary modules
+that provide encode/decode functionality for outgoing/incoming
+Diameter messages.
+A module is generated from a <seealso
+marker="diameter_dict">specification file</seealso> using the <seealso
+marker="diameterc">diameterc</seealso> utility.
+Dictionaries for the RFC 3588 Diameter Common Messages, Base
+Accounting and Relay applications are provided by the diameter
+application.</p>
</chapter>
diff --git a/lib/diameter/doc/src/diameter_transport.xml b/lib/diameter/doc/src/diameter_transport.xml
index be1bb2c56e..37cc871e75 100644
--- a/lib/diameter/doc/src/diameter_transport.xml
+++ b/lib/diameter/doc/src/diameter_transport.xml
@@ -33,7 +33,7 @@ under the License.
</header>
<module>diameter_transport</module>
-<modulesummary>Diameter transport behaviour.</modulesummary>
+<modulesummary>Diameter transport interface.</modulesummary>
<description>
diff --git a/lib/diameter/doc/src/diameter_using.xml b/lib/diameter/doc/src/diameter_using.xml
index 737a0a3941..809b76bdf3 100644
--- a/lib/diameter/doc/src/diameter_using.xml
+++ b/lib/diameter/doc/src/diameter_using.xml
@@ -35,6 +35,9 @@ under the License.
</header>
+<p>
+To be written.</p>
+
<!-- ===================================================================== -->
</chapter>
diff --git a/lib/diameter/doc/src/files.mk b/lib/diameter/doc/src/files.mk
index 23558e394f..79d53abceb 100644
--- a/lib/diameter/doc/src/files.mk
+++ b/lib/diameter/doc/src/files.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# 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
diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml
index 8fdb88749e..eafddd7d1e 100644
--- a/lib/diameter/doc/src/notes.xml
+++ b/lib/diameter/doc/src/notes.xml
@@ -40,8 +40,65 @@ first.</p>
<title>diameter 0.9</title>
<p>
-First OTP release.</p>
+Initial release of the diameter application.</p>
+<p>
+Known issues or limitations:</p>
+
+<list>
+
+<item>
+<p>
+Some agent-related functionality is not entirely complete.
+In particular, support for proxy agents, that advertise specific
+Diameter applications but otherwise relay messages in much the same
+way as relay agents (for which a <seealso
+marker="diameter_app#handle_request">handle_request/3</seealso>
+callback can return a <c>relay</c> tuple), will be completed in an
+upcoming release.
+There may also be more explicit support for redirect agents, although
+redirect behaviour can be implemented with the current
+functionality.</p>
+
+</item>
+
+<item>
+<p>
+There is some asymmetry in the treatment of messages sent as
+<c>diameter_header/avp</c> records and those sent in the "normal"
+fashion, and not all of this is documented.
+This is related to the previous point since this form of sending a
+message was introduced specifically to handle relay agent behaviour
+using the same callback interface as for client/server behaviour.</p>
+</item>
+
+<item>
+<p>
+The User's Guide is currently quite thin.
+The introductory chapter followed by the examples (in the application
+<c>examples</c> subdirectory) may be sufficient
+for those having some familiarity with the Diameter protocol but the
+intention is to provide more introductory text.
+The reference documentation is quite complete, although some points
+could likely be expanded upon.</p>
+</item>
+
+<item>
+<p>
+The function <seealso
+marker="diameter#service_info">diameter:service_info/2</seealso>
+can be used to retrieve information about a started service
+(statistics, information about connected peers, etc) but
+this is not yet documented and both the input and output may change
+in the next release.</p>
+</item>
+
+
+</list>
+
+<p>
+See <seealso marker="diameter_soc">Standards Compliance</seealso> for
+standards-related issues.</p>
</section>
</chapter>
diff --git a/lib/diameter/examples/server_cb.erl b/lib/diameter/examples/server_cb.erl
index b8705aedfc..43b8e24b5c 100644
--- a/lib/diameter/examples/server_cb.erl
+++ b/lib/diameter/examples/server_cb.erl
@@ -74,11 +74,8 @@ handle_request(#diameter_packet{msg = Req, errors = []}, _SvcName, {_, Caps})
{reply, answer(RT, Id, OH, OR)};
%% ... or one that wasn't. 3xxx errors are answered by diameter itself
-%% but these are non-3xxx errors for which we must contruct a reply.
-%% Returning a packet with the non-[] errors field will cause
-%% diameter to add the appropriate result code and Failed-AVPs avps.
-%% We just have to return the relevant answer record with any required
-%% avps.
+%% but these are 5xxx errors for which we must contruct a reply.
+%% diameter will set Result-Code and Failed-AVP's.
handle_request(#diameter_packet{msg = Req} = Pkt, _SvcName, {_, Caps})
when is_record(Req, diameter_base_RAR) ->
#diameter_caps{origin_host = {OH,_},
@@ -91,7 +88,7 @@ handle_request(#diameter_packet{msg = Req} = Pkt, _SvcName, {_, Caps})
'Origin-Realm' = OR,
'Session-Id' = Id},
- {reply, Pkt#diameter_packet{msg = Ans}};
+ {reply, Ans};
%% Should really reply to other base messages that we don't support
%% but simply discard them instead.
diff --git a/lib/diameter/include/diameter.hrl b/lib/diameter/include/diameter.hrl
index 8bd1ad1e51..0fa7fd406f 100644
--- a/lib/diameter/include/diameter.hrl
+++ b/lib/diameter/include/diameter.hrl
@@ -110,7 +110,7 @@
%% The diameter service and diameter_apps records are only passed
%% through the transport interface when starting a transport process,
%% although typically a transport implementation will (and probably
-%% should) only be interested diameter_service.host_ip_address.
+%% should) only be interested host_ip_address.
-record(diameter_service,
{pid,
diff --git a/lib/diameter/make/release_targets.mk b/lib/diameter/make/release_targets.mk
index 479a9aded1..5a3b585cbc 100644
--- a/lib/diameter/make/release_targets.mk
+++ b/lib/diameter/make/release_targets.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/make/rules.mk.in b/lib/diameter/make/rules.mk.in
index 9fd1c3b0d0..4a1a55b8d3 100644
--- a/lib/diameter/make/rules.mk.in
+++ b/lib/diameter/make/rules.mk.in
@@ -2,7 +2,7 @@
# ----------------------------------------------------
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+# Copyright Ericsson AB 2009-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/make/subdir.mk b/lib/diameter/make/subdir.mk
index 49198bbefd..24b08080ae 100644
--- a/lib/diameter/make/subdir.mk
+++ b/lib/diameter/make/subdir.mk
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/src/app/.gitignore b/lib/diameter/src/app/.gitignore
index 1310a0da6b..d388e61877 100644
--- a/lib/diameter/src/app/.gitignore
+++ b/lib/diameter/src/app/.gitignore
@@ -2,4 +2,5 @@
/diameter_gen_*.erl
/diameter_gen_*.hrl
/depend.mk
+/diameter.mk
diff --git a/lib/diameter/src/app/Makefile b/lib/diameter/src/app/Makefile
index 8985ca4911..6de220d282 100644
--- a/lib/diameter/src/app/Makefile
+++ b/lib/diameter/src/app/Makefile
@@ -187,7 +187,7 @@ depend: depend.mk
# has already been made since it's currently not smart enough to not
# force a rebuild of those beams dependent on generated hrls, and this
# is a no-no at make release.
-depend.mk: depend.sed $(MODULES:%=%.erl) modules.mk Makefile
+depend.mk: depend.sed $(MODULES:%=%.erl) Makefile
(for f in $(MODULES); do \
sed -f $< $$f.erl | sed "s@/@/$$f@"; \
done) \
diff --git a/lib/diameter/src/app/diameter.erl b/lib/diameter/src/app/diameter.erl
index 5f2ab82475..2f721421d8 100644
--- a/lib/diameter/src/app/diameter.erl
+++ b/lib/diameter/src/app/diameter.erl
@@ -35,7 +35,6 @@
%% Information.
-export([services/0,
- service_info/1,
service_info/2]).
%% Start/stop the application. In a "real" application this should
@@ -44,12 +43,6 @@
-export([start/0,
stop/0]).
-%% Backwards compatibility.
--export([add_connector/2,
- add_listener/2,
- remove_connector/2,
- remove_listener/2]).
-
-include("diameter_internal.hrl").
-include("diameter_types.hrl").
@@ -109,7 +102,7 @@ services() ->
[Name || {Name, _} <- diameter_service:services()].
%%% --------------------------------------------------------------------------
-%%% service_info/[12]
+%%% service_info/2
%%% --------------------------------------------------------------------------
-spec service_info(service_name(), atom() | [atom()])
@@ -118,9 +111,6 @@ services() ->
service_info(SvcName, Option) ->
diameter_service:info(SvcName, Option).
-service_info(SvcName) ->
- service_info(SvcName, all).
-
%%% --------------------------------------------------------------------------
%%% add_transport/3
%%% --------------------------------------------------------------------------
@@ -133,12 +123,6 @@ add_transport(SvcName, {T, Opts} = Cfg)
when is_list(Opts), (T == connect orelse T == listen) ->
diameter_config:add_transport(SvcName, Cfg).
-add_listener(SvcName, Opts) ->
- add_transport(SvcName, {listen, Opts}).
-
-add_connector(SvcName, Opts) ->
- add_transport(SvcName, {connect, Opts}).
-
%%% --------------------------------------------------------------------------
%%% remove_transport/2
%%% --------------------------------------------------------------------------
@@ -149,12 +133,6 @@ add_connector(SvcName, Opts) ->
remove_transport(SvcName, Pred) ->
diameter_config:remove_transport(SvcName, Pred).
-remove_listener(SvcName, Pred) ->
- remove_transport(SvcName, {listen, Pred}).
-
-remove_connector(SvcName, Pred) ->
- remove_transport(SvcName, {connect, Pred}).
-
%%% --------------------------------------------------------------------------
%%% # subscribe(SvcName)
%%%
diff --git a/lib/diameter/src/app/diameter_service.erl b/lib/diameter/src/app/diameter_service.erl
index 82a8d7a994..63b0649dc4 100644
--- a/lib/diameter/src/app/diameter_service.erl
+++ b/lib/diameter/src/app/diameter_service.erl
@@ -1278,18 +1278,15 @@ send_request({TPid, Caps, App}, Msg, Opts, Caller, SvcName) ->
%% make_packet/1
%%
%% Turn an outgoing request as passed to call/4 into a diameter_packet
-%% record in preparation for a prepare_request callback. There are two
-%% cases: a diameter_packet as argument when we're calling call/4
-%% ourselves in order to relay a request or a bare message in case the
-%% call came by way of diameter:call/4.
+%% record in preparation for a prepare_request callback.
make_packet(Bin)
when is_binary(Bin) ->
#diameter_packet{header = diameter_codec:decode_header(Bin),
bin = Bin};
-make_packet(#diameter_packet{msg = [#diameter_header{} | _]} = Pkt) ->
- Pkt;
+make_packet(#diameter_packet{msg = [#diameter_header{} = Hdr | Avps]} = Pkt) ->
+ Pkt#diameter_packet{msg = [make_header(Hdr) | Avps]};
make_packet(#diameter_packet{header = Hdr} = Pkt) ->
Pkt#diameter_packet{header = make_header(Hdr)};
@@ -1955,6 +1952,7 @@ is_loop(Code, Vid, OH, Avps) ->
%%
%% Send a locally originating reply.
+%% No errors or a diameter_header/avp list.
reply(Msg, Dict, TPid, #diameter_packet{errors = Es,
transport_data = TD}
= ReqPkt)
@@ -1964,11 +1962,7 @@ reply(Msg, Dict, TPid, #diameter_packet{errors = Es,
incr(send, Pkt, Dict, TPid), %% count result codes in sent answers
send(TPid, Pkt#diameter_packet{transport_data = TD});
-%% Simplify the handling of error cases by accepting a list consisting
-%% of an answer record followed by failed AVPs to be packed into a
-%% Failed-AVP field, either directly or into an AVP field. Only if
-%% the message is a tuple-list or record however, not a list
-%% with a list of #diameter_header{} and #diameter_avp{}.
+%% Or not: set Result-Code and Failed-AVP AVP's.
reply(Msg, Dict, TPid, #diameter_packet{errors = [H|_] = Es} = Pkt) ->
reply(rc(Msg, rc(H), [A || {_,A} <- Es], Dict),
Dict,
diff --git a/lib/diameter/src/compiler/Makefile b/lib/diameter/src/compiler/Makefile
index 8512eb515a..3ab76064ac 100644
--- a/lib/diameter/src/compiler/Makefile
+++ b/lib/diameter/src/compiler/Makefile
@@ -130,7 +130,7 @@ force:
depend: depend.mk
# Generate dependencies makefile.
-depend.mk: ../app/depend.sed $(ERL_FILES) modules.mk Makefile
+depend.mk: ../app/depend.sed $(ERL_FILES) Makefile
for f in $(MODULES); do \
sed -f $< $$f.erl | sed "s@/@/$$f@"; \
done \
diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl
index 213ba0d22c..30caebc544 100644
--- a/lib/diameter/src/compiler/diameter_codegen.erl
+++ b/lib/diameter/src/compiler/diameter_codegen.erl
@@ -250,9 +250,14 @@ f_name(Name) ->
%%% ------------------------------------------------------------------------
f_id(Spec) ->
- Id = orddict:fetch(id, Spec),
{?function, id, 0,
- [{?clause, [], [], [?INTEGER(Id)]}]}.
+ [c_id(orddict:find(id, Spec))]}.
+
+c_id({ok, Id}) ->
+ {?clause, [], [], [?INTEGER(Id)]};
+
+c_id(error) ->
+ ?UNEXPECTED(0).
%%% ------------------------------------------------------------------------
%%% # vendor_id/0
@@ -454,9 +459,10 @@ avp(Spec) ->
Native = get_value(avp_types, Spec),
Custom = get_value(custom_types, Spec),
Imported = get_value(import_avps, Spec),
- avp([{N,T} || {N,_,T,_,_} <- Native], Imported, Custom).
+ Enums = get_value(enums, Spec),
+ avp([{N,T} || {N,_,T,_,_} <- Native], Imported, Custom, Enums).
-avp(Native, Imported, Custom) ->
+avp(Native, Imported, Custom, Enums) ->
Dict = orddict:from_list(Native),
report(native, Dict),
@@ -470,8 +476,8 @@ avp(Native, Imported, Custom) ->
false == lists:member(N, CustomNames)
end,
Native))
- ++ lists:flatmap(fun c_imported_avp/1, Imported)
- ++ lists:flatmap(fun(C) -> c_custom_avp(C, Dict) end, Custom).
+ ++ lists:flatmap(fun(I) -> cs_imported_avp(I, Enums) end, Imported)
+ ++ lists:flatmap(fun(C) -> cs_custom_avp(C, Dict) end, Custom).
c_base_avp({AvpName, T}) ->
{?clause, [?VAR('T'), ?VAR('Data'), ?ATOM(AvpName)],
@@ -487,23 +493,35 @@ base_avp(AvpName, 'Grouped') ->
base_avp(_, Type) ->
?APPLY(diameter_types, Type, [?VAR('T'), ?VAR('Data')]).
-c_imported_avp({Mod, Avps}) ->
- lists:map(fun(A) -> imported_avp(Mod, A) end, Avps).
+cs_imported_avp({Mod, Avps}, Enums) ->
+ lists:map(fun(A) -> imported_avp(Mod, A, Enums) end, Avps).
-imported_avp(_Mod, {AvpName, _, 'Grouped' = T, _, _}) ->
+imported_avp(_Mod, {AvpName, _, 'Grouped' = T, _, _}, _) ->
c_base_avp({AvpName, T});
-imported_avp(Mod, {AvpName, _, _, _, _}) ->
+imported_avp(Mod, {AvpName, _, 'Enumerated' = T, _, _}, Enums) ->
+ case lists:keymember(AvpName, 1, Enums) of
+ true ->
+ c_base_avp({AvpName, T});
+ false ->
+ c_imported_avp(Mod, AvpName)
+ end;
+
+imported_avp(Mod, {AvpName, _, _, _, _}, _) ->
+ c_imported_avp(Mod, AvpName).
+
+c_imported_avp(Mod, AvpName) ->
{?clause, [?VAR('T'), ?VAR('Data'), ?ATOM(AvpName)],
[],
[?APPLY(Mod, avp, [?VAR('T'),
?VAR('Data'),
?ATOM(AvpName)])]}.
-c_custom_avp({Mod, Avps}, Dict) ->
- lists:map(fun(N) -> custom_avp(Mod, N, orddict:fetch(N, Dict)) end, Avps).
+cs_custom_avp({Mod, Avps}, Dict) ->
+ lists:map(fun(N) -> c_custom_avp(Mod, N, orddict:fetch(N, Dict)) end,
+ Avps).
-custom_avp(Mod, AvpName, Type) ->
+c_custom_avp(Mod, AvpName, Type) ->
{?clause, [?VAR('T'), ?VAR('Data'), ?ATOM(AvpName)],
[],
[?APPLY(Mod, AvpName, [?VAR('T'), ?ATOM(Type), ?VAR('Data')])]}.
@@ -516,9 +534,25 @@ f_enumerated_avp(Spec) ->
{?function, enumerated_avp, 3, enumerated_avp(Spec) ++ [?UNEXPECTED(3)]}.
enumerated_avp(Spec) ->
- lists:flatmap(fun c_enumerated_avp/1, get_value(enums, Spec)).
+ Enums = get_value(enums, Spec),
+ lists:flatmap(fun cs_enumerated_avp/1, Enums)
+ ++ lists:flatmap(fun({M,Es}) -> enumerated_avp(M, Es, Enums) end,
+ get_value(import_enums, Spec)).
+
+enumerated_avp(Mod, Es, Enums) ->
+ lists:flatmap(fun({N,_}) ->
+ cs_enumerated_avp(lists:keymember(N, 1, Enums),
+ Mod,
+ N)
+ end,
+ Es).
-c_enumerated_avp({AvpName, Values}) ->
+cs_enumerated_avp(true, Mod, Name) ->
+ [c_imported_avp(Mod, Name)];
+cs_enumerated_avp(false, _, _) ->
+ [].
+
+cs_enumerated_avp({AvpName, Values}) ->
lists:flatmap(fun(V) -> c_enumerated_avp(AvpName, V) end, Values).
c_enumerated_avp(AvpName, {I,_}) ->
@@ -537,10 +571,14 @@ f_msg_header(Spec) ->
{?function, msg_header, 1, msg_header(Spec) ++ [?UNEXPECTED(1)]}.
msg_header(Spec) ->
+ msg_header(get_value(messages, Spec), Spec).
+
+msg_header([], _) ->
+ [];
+msg_header(Msgs, Spec) ->
ApplId = orddict:fetch(id, Spec),
- lists:map(fun({M,C,F,_,_}) -> c_msg_header(M, C, F, ApplId) end,
- get_value(messages, Spec)).
+ lists:map(fun({M,C,F,_,_}) -> c_msg_header(M, C, F, ApplId) end, Msgs).
%% Note that any application id in the message header spec is ignored.
@@ -616,10 +654,12 @@ f_empty_value(Spec) ->
{?function, empty_value, 1, empty_value(Spec)}.
empty_value(Spec) ->
+ Imported = lists:flatmap(fun avps/1, get_value(import_enums, Spec)),
Groups = get_value(grouped, Spec)
++ lists:flatmap(fun avps/1, get_value(import_groups, Spec)),
- Enums = get_value(enums, Spec)
- ++ lists:flatmap(fun avps/1, get_value(import_enums, Spec)),
+ Enums = [T || {N,_} = T <- get_value(enums, Spec),
+ not lists:keymember(N, 1, Imported)]
+ ++ Imported,
lists:map(fun c_empty_value/1, Groups ++ Enums)
++ [{?clause, [?VAR('Name')], [], [?CALL(empty, [?VAR('Name')])]}].
diff --git a/lib/diameter/src/compiler/diameter_forms.hrl b/lib/diameter/src/compiler/diameter_forms.hrl
index 4125e2331c..d93131df34 100644
--- a/lib/diameter/src/compiler/diameter_forms.hrl
+++ b/lib/diameter/src/compiler/diameter_forms.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/diameter/src/compiler/diameter_spec_util.erl b/lib/diameter/src/compiler/diameter_spec_util.erl
index 322d53a199..b60886b678 100644
--- a/lib/diameter/src/compiler/diameter_spec_util.erl
+++ b/lib/diameter/src/compiler/diameter_spec_util.erl
@@ -39,11 +39,11 @@ parse(Path, Options) ->
{ok, B} = file:read_file(Path),
Chunks = chunk(B),
Spec = make_spec(Chunks),
- true = enums_defined(Spec), %% sanity checks
- true = groups_defined(Spec), %%
+ true = groups_defined(Spec), %% sanity checks
true = customs_defined(Spec), %%
Full = import_enums(import_groups(import_avps(insert_codes(Spec),
Options))),
+ true = enums_defined(Full), %% sanity checks
true = v_flags_set(Spec),
Full.
@@ -243,35 +243,48 @@ get_value(Key, Spec) ->
%% with an appropriate type.
enums_defined(Spec) ->
- is_defined(Spec, 'Enumerated', enums).
+ Avps = get_value(avp_types, Spec),
+ Import = get_value(import_enums, Spec),
+ lists:all(fun({N,_}) ->
+ true = enum_defined(N, Avps, Import)
+ end,
+ get_value(enums, Spec)).
-groups_defined(Spec) ->
- is_defined(Spec, 'Grouped', grouped).
+enum_defined(Name, Avps, Import) ->
+ case lists:keyfind(Name, 1, Avps) of
+ {Name, _, 'Enumerated', _, _} ->
+ true;
+ {Name, _, T, _, _} ->
+ ?ERROR({avp_has_wrong_type, Name, 'Enumerated', T});
+ false ->
+ lists:any(fun({_,Is}) -> lists:keymember(Name, 1, Is) end, Import)
+ orelse ?ERROR({avp_not_defined, Name, 'Enumerated'})
+ end.
+%% Note that an AVP is imported only if referenced by a message or
+%% grouped AVP, so the final branch will fail if an enum definition is
+%% extended without this being the case.
-is_defined(Spec, Type, Key) ->
+groups_defined(Spec) ->
Avps = get_value(avp_types, Spec),
- lists:all(fun(T) -> true = is_local(name(Key, T), Type, Avps) end,
- get_value(Key, Spec)).
+ lists:all(fun({N,_,_,_}) -> true = group_defined(N, Avps) end,
+ get_value(grouped, Spec)).
-name(enums, {N,_}) -> N;
-name(grouped, {N,_,_,_}) -> N.
-
-is_local(Name, Type, Avps) ->
+group_defined(Name, Avps) ->
case lists:keyfind(Name, 1, Avps) of
- {Name, _, Type, _, _} ->
+ {Name, _, 'Grouped', _, _} ->
true;
{Name, _, T, _, _} ->
- ?ERROR({avp_has_wrong_type, Name, Type, T});
+ ?ERROR({avp_has_wrong_type, Name, 'Grouped', T});
false ->
- ?ERROR({avp_not_defined, Name, Type})
+ ?ERROR({avp_not_defined, Name, 'Grouped'})
end.
customs_defined(Spec) ->
Avps = get_value(avp_types, Spec),
- lists:all(fun(A) -> true = is_local(A, Avps) end,
+ lists:all(fun(A) -> true = custom_defined(A, Avps) end,
lists:flatmap(fun last/1, get_value(custom_types, Spec))).
-is_local(Name, Avps) ->
+custom_defined(Name, Avps) ->
case lists:keyfind(Name, 1, Avps) of
{Name, _, T, _, _} when T == 'Grouped';
T == 'Enumerated' ->
@@ -510,6 +523,9 @@ choose(false, _, X) -> X.
%% ------------------------------------------------------------------------
%% import_groups/1
%% import_enums/1
+%%
+%% For each inherited module, store the content of imported AVP's of
+%% type grouped/enumerated in a new key.
import_groups(Spec) ->
orddict:store(import_groups, import(grouped, Spec), Spec).
diff --git a/lib/diameter/src/subdirs.mk b/lib/diameter/src/subdirs.mk
index 3026224e00..3e12d935bc 100644
--- a/lib/diameter/src/subdirs.mk
+++ b/lib/diameter/src/subdirs.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# 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
diff --git a/lib/diameter/src/transport/Makefile b/lib/diameter/src/transport/Makefile
index 5dc1772796..4b53100fd2 100644
--- a/lib/diameter/src/transport/Makefile
+++ b/lib/diameter/src/transport/Makefile
@@ -130,7 +130,7 @@ force:
depend: depend.mk
# Generate dependencies makefile.
-depend.mk: ../app/depend.sed $(ERL_FILES) modules.mk Makefile
+depend.mk: ../app/depend.sed $(ERL_FILES) Makefile
for f in $(MODULES); do \
sed -f $< $$f.erl | sed "s@/@/$$f@"; \
done \
diff --git a/lib/diameter/subdirs.mk b/lib/diameter/subdirs.mk
index 1e292d0ed1..d80c97d57a 100644
--- a/lib/diameter/subdirs.mk
+++ b/lib/diameter/subdirs.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# 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
diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile
index daae70b1e2..b3648c7bb1 100644
--- a/lib/diameter/test/Makefile
+++ b/lib/diameter/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# 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
@@ -404,5 +404,5 @@ release_tests_spec: tests
# $(HRL_FILES) $(ERL_FILES) \
# $(RELSYSDIR)
#
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
diff --git a/lib/diameter/test/diameter_reg_test.erl b/lib/diameter/test/diameter_reg_test.erl
index 0469b833cb..a2638d6712 100644
--- a/lib/diameter/test/diameter_reg_test.erl
+++ b/lib/diameter/test/diameter_reg_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010_2011. All Rights Reserved.
+%% Copyright Ericsson AB 2010-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
diff --git a/lib/diameter/test/diameter_tcp_test.erl b/lib/diameter/test/diameter_tcp_test.erl
index 01b5dc5293..b002a3d289 100644
--- a/lib/diameter/test/diameter_tcp_test.erl
+++ b/lib/diameter/test/diameter_tcp_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/diameter/test/diameter_test_lib.erl b/lib/diameter/test/diameter_test_lib.erl
index 16b3b9d216..3d46236526 100644
--- a/lib/diameter/test/diameter_test_lib.erl
+++ b/lib/diameter/test/diameter_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/diameter/test/diameter_test_lib.hrl b/lib/diameter/test/diameter_test_lib.hrl
index 8b1352f801..0b86f38de7 100644
--- a/lib/diameter/test/diameter_test_lib.hrl
+++ b/lib/diameter/test/diameter_test_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk
index fa8b4a8eda..ddc720d0c1 100644
--- a/lib/diameter/test/modules.mk
+++ b/lib/diameter/test/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010. All Rights Reserved.
+# 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
diff --git a/lib/diameter/test/slask/diameter_persistent_table_test.erl b/lib/diameter/test/slask/diameter_persistent_table_test.erl
index 25bbe41347..bb907a5777 100644
--- a/lib/diameter/test/slask/diameter_persistent_table_test.erl
+++ b/lib/diameter/test/slask/diameter_persistent_table_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/docbuilder/doc/src/notes.xml b/lib/docbuilder/doc/src/notes.xml
index 4b8c04f323..d04c8dd839 100644
--- a/lib/docbuilder/doc/src/notes.xml
+++ b/lib/docbuilder/doc/src/notes.xml
@@ -31,6 +31,28 @@
<p>This document describes the changes made to the DocBuilder
application.</p>
+<section><title>Docbuilder 0.9.8.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> fop 1.0 crashed when building the docbuilder pdf with
+ the following message
+ "java.lang.IllegalArgumentException: factor &lt; 0; was:
+ -1". <br/> This is a known bug in fop 1.0 (fop bug id:
+ Bug 50524) when there is a word that consist of a single
+ soft hyphen (&amp;shy;). this has been fixed in fop
+ source archive but not it's not in a release yet. It's
+ fixed in our documentation by removing the soft hyphens
+ where this is a problem. </p>
+ <p>
+ Own Id: OTP-9143</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Docbuilder 0.9.8.9</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/docbuilder/vsn.mk b/lib/docbuilder/vsn.mk
index 1209b80d94..2475966ec2 100644
--- a/lib/docbuilder/vsn.mk
+++ b/lib/docbuilder/vsn.mk
@@ -1 +1 @@
-DOCB_VSN = 0.9.8.9
+DOCB_VSN = 0.9.8.10
diff --git a/lib/edoc/Makefile b/lib/edoc/Makefile
index e512e390e3..1add669398 100644
--- a/lib/edoc/Makefile
+++ b/lib/edoc/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/edoc/doc/Makefile b/lib/edoc/doc/Makefile
index a0f6484382..c5f68b25d0 100644
--- a/lib/edoc/doc/Makefile
+++ b/lib/edoc/doc/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id: Makefile,v 1.1.1.1 2004/10/04 13:53:33 richardc Exp $
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/edoc/doc/overview.edoc b/lib/edoc/doc/overview.edoc
index bd603b7a13..fa699c6f08 100644
--- a/lib/edoc/doc/overview.edoc
+++ b/lib/edoc/doc/overview.edoc
@@ -1084,10 +1084,11 @@ Details:
the Erlang programming language.</li>
<li>`boolean()' is the subset of `atom()' consisting
of the atoms `true' and `false'.</li>
- <li>`char()' is a subset of
- `integer()' representing character codes.</li>
+ <li>`char()' is the subset of `integer()' representing
+ Unicode character codes: hex 000000-10FFFF.</li>
<li>`tuple()' is the set of all tuples `{...}'.</li>
- <li>`list(T)' is just an alias for `[T]'.</li>
+ <li>`list(T)' is just an alias for `[T]'; list() is an alias
+ for `list(any())', i.e., `[any()]'.</li>
<li>`nil()' is an alias for the empty list `[]'.</li>
<li>`cons(H,T)' is the list constructor. This is usually not
used directly. It is possible to recursively define `list(T)
diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile
index 5ee0096f0f..b933094464 100644
--- a/lib/edoc/doc/src/Makefile
+++ b/lib/edoc/doc/src/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index 630271b115..31a54788e5 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -31,6 +31,40 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix infinite loop for malformed edoc input</p>
+ <p>
+ When processing an edoc comment with ``` in it, if the
+ comment ends without a matching ''' then an infinite loop
+ occurs in the function edoc_wiki:strip_empty_lines/2.
+ This change fixes that by adding a clause to return from
+ the function upon the end of the comment input. This
+ allows an error to be thrown to indicate the problem,
+ which is the same behaviour as leaving either `` or `
+ unmatched. (Thanks to Taylor Venable)</p>
+ <p>
+ Own Id: OTP-9165</p>
+ </item>
+ <item>
+ <p> Bugs concerning the option
+ <c>report_missing_types</c> that was added in EDoc-0.7.7
+ have been corrected: the option was misspelled in the
+ source, and local definitions as well as the function
+ tags <c>@private</c> and <c>@hidden</c> were not handled
+ correctly. (Thanks to Manolis Papadakis.) </p>
+ <p>
+ Own Id: OTP-9301</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/edoc/include/Makefile b/lib/edoc/include/Makefile
index 0533c27567..5b2ad38c9d 100644
--- a/lib/edoc/include/Makefile
+++ b/lib/edoc/include/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/edoc/priv/edoc_generate.src b/lib/edoc/priv/edoc_generate.src
index e87fdbc902..7ec89207b0 100644
--- a/lib/edoc/priv/edoc_generate.src
+++ b/lib/edoc/priv/edoc_generate.src
@@ -14,9 +14,6 @@
# Portions created by Ericsson are Copyright 1999-2000, Ericsson
# Utvecklings AB. All Rights Reserved.''
#
-# $Id$
-#
-#
#EDOC_DIR=/clearcase/otp/internal_tools/edoc
EDOC_DIR=/home/otp/sgml/edoc-%EDOC_VSN%
diff --git a/lib/edoc/src/Makefile b/lib/edoc/src/Makefile
index 9c5a9d30d1..fcb0b61292 100644
--- a/lib/edoc/src/Makefile
+++ b/lib/edoc/src/Makefile
@@ -23,7 +23,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/edoc-$(VSN)
EBIN = ../ebin
XMERL = ../../xmerl
-ERL_COMPILE_FLAGS += -I../include -I$(XMERL)/include +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_deprecated_guard
+ERL_COMPILE_FLAGS += -pa $(XMERL) -I../include -I$(XMERL)/include +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_deprecated_guard
SOURCES= \
edoc.erl edoc_data.erl edoc_doclet.erl edoc_extract.erl \
diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl
index 360f2dbc9e..a279f7dcb3 100644
--- a/lib/edoc/src/edoc.erl
+++ b/lib/edoc/src/edoc.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @copyright 2001-2007 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @version {@version}
@@ -60,8 +58,6 @@
-compile({no_auto_import,[error/1]}).
--import(edoc_report, [report/2, report/3, error/1, error/3]).
-
-include("edoc.hrl").
@@ -179,8 +175,8 @@ application(App, Options) when is_atom(App) ->
Dir when is_list(Dir) ->
application(App, Dir, Options);
_ ->
- report("cannot find application directory for '~s'.",
- [App]),
+ edoc_report:report("cannot find application directory for '~s'.",
+ [App]),
exit(error)
end.
@@ -663,8 +659,8 @@ read_source(Name, Opts0) ->
check_forms(Forms, Name),
Forms;
{error, R} ->
- error({"error reading file '~s'.",
- [edoc_lib:filename(Name)]}),
+ edoc_report:error({"error reading file '~s'.",
+ [edoc_lib:filename(Name)]}),
exit({error, R})
end.
@@ -688,11 +684,10 @@ check_forms(Fs, Name) ->
error_marker ->
case erl_syntax:error_marker_info(F) of
{L, M, D} ->
- error(L, Name, {format_error, M, D});
-
+ edoc_report:error(L, Name, {format_error, M, D});
Other ->
- report(Name, "unknown error in "
- "source code: ~w.", [Other])
+ edoc_report:report(Name, "unknown error in "
+ "source code: ~w.", [Other])
end,
exit(error);
_ ->
diff --git a/lib/edoc/src/edoc_data.erl b/lib/edoc/src/edoc_data.erl
index 27f43dca5a..e3b5a0d51b 100644
--- a/lib/edoc/src/edoc_data.erl
+++ b/lib/edoc/src/edoc_data.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_doclet.erl b/lib/edoc/src/edoc_doclet.erl
index 30eef3e63a..c66be9d7c7 100644
--- a/lib/edoc/src/edoc_doclet.erl
+++ b/lib/edoc/src/edoc_doclet.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @copyright 2003-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @see edoc
@@ -52,7 +50,7 @@
-define(IMAGE, "erlang.png").
-define(NL, "\n").
--include("xmerl.hrl").
+-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
diff --git a/lib/edoc/src/edoc_extract.erl b/lib/edoc/src/edoc_extract.erl
index 5e28762c53..1209d86fe5 100644
--- a/lib/edoc/src/edoc_extract.erl
+++ b/lib/edoc/src/edoc_extract.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id: $
-%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @see edoc
@@ -238,8 +236,8 @@ file(File, Context, Env, Opts) ->
case file:read_file(File) of
{ok, Bin} ->
{ok, text(binary_to_list(Bin), Context, Env, Opts, File)};
- {error, _R} = Error ->
- Error
+ {error, _} = Error ->
+ Error
end.
@@ -298,8 +296,8 @@ get_module_info(Forms, File) ->
{Name, Vars} = case lists:keyfind(module, 1, L) of
{module, N} when is_atom(N) ->
{N, none};
- {module, {N, _Vs} = NVs} when is_atom(N) ->
- NVs;
+ {module, {N, _}=Mod} when is_atom(N) ->
+ Mod;
_ ->
report(File, "module name missing.", []),
exit(error)
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index 3ec87b7060..1c0841815f 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id: $
-%%
%% @author Richard Carlsson <[email protected]>
%% @copyright 2001-2006 Richard Carlsson
%% @see edoc
@@ -33,7 +31,7 @@
-import(edoc_report, [report/2]).
--include("xmerl.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
-define(HTML_EXPORT, xmerl_html).
-define(DEFAULT_XML_EXPORT, ?HTML_EXPORT).
@@ -959,12 +957,16 @@ local_label(R) ->
xhtml(Title, CSS, Body) ->
[{html, [?NL,
- {head, [?NL,
- {title, Title},
- ?NL] ++ CSS},
- ?NL,
- {body, [{bgcolor, "white"}], Body},
- ?NL]
+ {head, [?NL,
+ {meta, [{'http-equiv',"Content-Type"},
+ {content, "text/html; charset=ISO-8859-1"}],
+ []},
+ ?NL,
+ {title, Title},
+ ?NL] ++ CSS},
+ ?NL,
+ {body, [{bgcolor, "white"}], Body},
+ ?NL]
},
?NL].
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index 585e30a2d2..6c698e83ef 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @see edoc
@@ -40,7 +38,7 @@
-import(edoc_report, [report/2, warning/2]).
-include("edoc.hrl").
--include("xmerl.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
-define(FILE_BASE, "/").
@@ -494,7 +492,7 @@ uri_get_file(File0) ->
uri_get_http(URI) ->
%% Try using option full_result=false
case catch {ok, httpc:request(get, {URI,[]}, [],
- [{full_result, false}])} of
+ [{full_result, false}])} of
{'EXIT', _} ->
uri_get_http_r10(URI);
Result ->
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index 6943f1bdb8..3ce4cde4fb 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -23,9 +23,6 @@
%% USA
%%
%% Author contact: [email protected]
-%%
-%% $Id $
-%%
%% =====================================================================
Nonterminals
@@ -362,10 +359,10 @@ parse_spec(S, L) ->
{ok, Spec} ->
Spec;
{error, E} ->
- throw_error(E, L)
+ throw_error({parse_spec, E}, L)
end;
{error, E, _} ->
- throw_error(E, L)
+ throw_error({parse_spec, E}, L)
end.
%% ---------------------------------------------------------------------
diff --git a/lib/edoc/src/edoc_report.erl b/lib/edoc/src/edoc_report.erl
index ee54c60c90..f082513bee 100644
--- a/lib/edoc/src/edoc_report.erl
+++ b/lib/edoc/src/edoc_report.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_run.erl b/lib/edoc/src/edoc_run.erl
index 96e5ea4631..1355db840f 100644
--- a/lib/edoc/src/edoc_run.erl
+++ b/lib/edoc/src/edoc_run.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @copyright 2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @see edoc
diff --git a/lib/edoc/src/edoc_scanner.erl b/lib/edoc/src/edoc_scanner.erl
index 9d2e6f3aed..8e895ad1ad 100644
--- a/lib/edoc/src/edoc_scanner.erl
+++ b/lib/edoc/src/edoc_scanner.erl
@@ -13,8 +13,6 @@
%% AB. Portions created by Ericsson are Copyright 1999, Ericsson
%% Utvecklings AB. All Rights Reserved.''
%%
-%% $Id: $
-%%
%% @private
%% @copyright Richard Carlsson 2001-2003. Portions created by Ericsson
%% are Copyright 1999, Ericsson Utvecklings AB. All Rights Reserved.
diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl
index b3d2da5a86..5acf8ac0d5 100644
--- a/lib/edoc/src/edoc_specs.erl
+++ b/lib/edoc/src/edoc_specs.erl
@@ -86,8 +86,9 @@ dummy_spec(Form) ->
#tag{name = spec, line = element(2, hd(TypeSpecs)),
origin = code, data = S}.
--spec docs(Forms::[syntaxTree()], CommentFun) -> dict() when
- CommentFun :: fun(([syntaxTree()], Line :: term()) -> #tag{}).
+-spec docs(Forms::[syntaxTree()],
+ CommentFun :: fun( ([syntaxTree()], Line :: term()) -> #tag{} ))
+ -> dict().
%% @doc Find comments after -type/-opaque declarations.
%% Postcomments "inside" the type are skipped.
@@ -304,8 +305,6 @@ d2e({ann_type,_,[V, T0]}) ->
%% layout module.
T = d2e(T0),
?add_t_ann(T, element(3, V));
-d2e({type,_,no_return,[]}) ->
- #t_type{name = #t_name{name = none}};
d2e({remote_type,_,[{atom,_,M},{atom,_,F},Ts0]}) ->
Ts = d2e(Ts0),
typevar_anno(#t_type{name = #t_name{module = M, name = F}, args = Ts}, Ts);
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index 8ee8f87b5f..80989428ce 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 1ded63dffe..a54544868c 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -34,13 +32,13 @@
%% @headerfile "edoc_types.hrl"
-include("edoc_types.hrl").
--include("xmerl.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;
+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;
@@ -51,6 +49,7 @@ 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;
diff --git a/lib/edoc/src/edoc_wiki.erl b/lib/edoc/src/edoc_wiki.erl
index 9a31bc9a82..2f2d14853c 100644
--- a/lib/edoc/src/edoc_wiki.erl
+++ b/lib/edoc/src/edoc_wiki.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @private
%% @copyright 2001-2003 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
@@ -70,7 +68,7 @@
-export([parse_xml/2, expand_text/2]).
-include("edoc.hrl").
--include("xmerl.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
-define(BASE_HEADING, 3).
@@ -82,8 +80,8 @@ parse_xml(Data, Line) ->
parse_xml_1(Text, Line) ->
Text1 = "<doc>" ++ Text ++ "</doc>",
- Options = [{line, Line}, {encoding, "iso-8859-1"}],
- case catch {ok, xmerl_scan:string(Text1, Options)} of
+ Opts = [{line, Line}, {encoding, 'iso-8859-1'}],
+ case catch {ok, xmerl_scan:string(Text1, Opts)} of
{ok, {E, _}} ->
E#xmlElement.content;
{'EXIT', {fatal, {Reason, L, _C}}} ->
@@ -360,10 +358,7 @@ par_text(Cs, As, Bs, E, Es) ->
[] -> Bs;
_ -> [#xmlElement{name = p, content = Es1} | Bs]
end,
- Bs1 = case Ss of
- [] -> Bs0;
- _ -> [#xmlText{value = Ss} | Bs0]
- end,
+ Bs1 = [#xmlText{value = Ss} | Bs0],
case Cs2 of
[] ->
par(Es, [], Bs1);
diff --git a/lib/edoc/src/otpsgml_layout.erl b/lib/edoc/src/otpsgml_layout.erl
index 45f74b299e..d425dc0ed8 100644
--- a/lib/edoc/src/otpsgml_layout.erl
+++ b/lib/edoc/src/otpsgml_layout.erl
@@ -14,8 +14,6 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
%% @author Richard Carlsson <[email protected]>
%% @author Kenneth Lundin <[email protected]>
%% @copyright 2001-2004 Richard Carlsson
@@ -34,7 +32,7 @@
-import(edoc_report, [report/2]).
--include("xmerl.hrl").
+-include_lib("xmerl/include/xmerl.hrl").
-define(SGML_EXPORT, xmerl_otpsgml).
-define(DEFAULT_XML_EXPORT, ?SGML_EXPORT).
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index 0d57591e3e..5b95c35756 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -13,8 +13,6 @@
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
%% AB. All Rights Reserved.''
%%
-%% $Id$
-%%
-module(edoc_SUITE).
-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index febac9cc42..30cf191ffc 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.7
+EDOC_VSN = 0.7.8
diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml
index 7c8a2c8208..f79639769f 100644
--- a/lib/erl_docgen/doc/src/notes.xml
+++ b/lib/erl_docgen/doc/src/notes.xml
@@ -30,7 +30,22 @@
</header>
<p>This document describes the changes made to the erl_docgen application.</p>
- <section><title>erl_docgen 0.2.4</title>
+ <section><title>Erl_Docgen 0.2.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> The support for using Erlang specifications and types
+ has been improved. </p>
+ <p>
+ Own Id: OTP-9261</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>erl_docgen 0.2.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/erl_docgen/priv/bin/xref_mod_app.escript b/lib/erl_docgen/priv/bin/xref_mod_app.escript
index 13671ef2f8..c2bd62f9e0 100755
--- a/lib/erl_docgen/priv/bin/xref_mod_app.escript
+++ b/lib/erl_docgen/priv/bin/xref_mod_app.escript
@@ -73,7 +73,12 @@ usage() ->
modapp(TopDir) ->
AppDirs = filelib:wildcard(filename:join([TopDir,"lib","*"])),
AM = [appmods(D) || D <- AppDirs],
- lists:keysort(1, [{M,A} || {A,Ms} <- AM, M <- Ms]).
+ ERTS = [preloaded(TopDir) || lists:keyfind("erts", 1, AM) =:= false],
+ lists:keysort(1, [{M,A} || {A,Ms} <- ERTS++AM, M <- Ms]).
+
+preloaded(TopDir) ->
+ {"preloaded",Mods} = appmods(filename:join([TopDir,"erts","preloaded"])),
+ {"erts",Mods}.
%% It's OK if too much data is generated as long as all applications
%% and all modules are mentioned.
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index 982572aeef..a9052f29e5 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -433,6 +433,8 @@
<!-- Search "local types" as well -->
<xsl:variable name="local_types"
select="ancestor::desc/preceding-sibling::type
+ [string-length(@name) > 0]
+ | ancestor::type_desc/preceding-sibling::type
[string-length(@name) > 0]"/>
<xsl:variable name="has_anno_in_local_type">
<xsl:for-each select="$local_types">
diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl
index 25b62f68c5..8db4714249 100644
--- a/lib/erl_docgen/priv/xsl/db_man.xsl
+++ b/lib/erl_docgen/priv/xsl/db_man.xsl
@@ -363,6 +363,8 @@
<!-- Search "local types" as well -->
<xsl:variable name="local_types"
select="ancestor::desc/preceding-sibling::type
+ [string-length(@name) > 0]
+ | ancestor::type_desc/preceding-sibling::type
[string-length(@name) > 0]"/>
<xsl:variable name="has_anno_in_local_type">
<xsl:for-each select="$local_types">
diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl
index 5119e3e36a..a3d601d861 100644
--- a/lib/erl_docgen/priv/xsl/db_pdf.xsl
+++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl
@@ -410,6 +410,8 @@
<!-- Search "local types" as well -->
<xsl:variable name="local_types"
select="ancestor::desc/preceding-sibling::type
+ [string-length(@name) > 0]
+ | ancestor::type_desc/preceding-sibling::type
[string-length(@name) > 0]"/>
<xsl:variable name="has_anno_in_local_type">
<xsl:for-each select="$local_types">
diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk
index 29585d8520..cafb5287de 100644
--- a/lib/erl_docgen/vsn.mk
+++ b/lib/erl_docgen/vsn.mk
@@ -1,2 +1,2 @@
-ERL_DOCGEN_VSN = 0.2.4
+ERL_DOCGEN_VSN = 0.2.5
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index d83a8307e4..7055fcd5c9 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,42 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix using sizeof() for array given as function argument</p>
+ <p>
+ When using the sizeof() operator for an array given as
+ function argument it returns the size of the pointer. In
+ this case, the affected function hex(char digest[16],
+ char buff[33]) will just print 4 or 8 byte instead of the
+ full length of 16 bytes, on 32bit and 64bit systems
+ respectively. (Thanks to Cristian greco)</p>
+ <p>
+ Own Id: OTP-9151</p>
+ </item>
+ <item>
+ <p>
+ Initialize <c>to</c> and <c>to_name</c> in
+ <c>erl_receive_msg</c>. (Thanks to G�ran Larsson)</p>
+ <p>
+ Own Id: OTP-9241</p>
+ </item>
+ <item>
+ <p>
+ erl_interface: fix compile error(Thanks to Michael
+ Santos)</p>
+ <p>
+ Own Id: OTP-9252</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.7.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c
index 50c5a4161d..ba8f8fbce3 100644
--- a/lib/erl_interface/src/connect/ei_resolve.c
+++ b/lib/erl_interface/src/connect/ei_resolve.c
@@ -185,7 +185,12 @@ static int verify_dns_configuration(void)
* align: increment buf until it is dword-aligned, reduce len by same amount.
* advance: increment buf by n bytes, reduce len by same amount .
*/
-#define align_buf(buf,len) for (;(((unsigned)buf)&0x3); (buf)++, len--)
+#if defined SIZEOF_VOID_P
+#define ALIGNBYTES (SIZEOF_VOID_P - 1)
+#else
+#define ALIGNBYTES (sizeof(void*) - 1)
+#endif
+#define align_buf(buf,len) for (;(((unsigned)buf) & ALIGNBYTES); (buf)++, len--)
#define advance_buf(buf,len,n) ((buf)+=(n),(len)-=(n))
/* "and now the tricky part..." */
diff --git a/lib/erl_interface/src/epmd/epmd_port.c b/lib/erl_interface/src/epmd/epmd_port.c
index 6450f285cc..a433815eb7 100644
--- a/lib/erl_interface/src/epmd/epmd_port.c
+++ b/lib/erl_interface/src/epmd/epmd_port.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index 0317462106..75f2b7101b 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.7.3
+EI_VSN = 3.7.4
diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml
index cd4787c5e7..e3be8422c8 100644
--- a/lib/et/doc/src/notes.xml
+++ b/lib/et/doc/src/notes.xml
@@ -36,6 +36,22 @@
one section in this document. The title of each section is the
version number of <c>Event Tracer (ET)</c>.</p>
+<section><title>ET 1.4.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The popup window 'contents viewer' did not display
+ properly on Windows.</p>
+ <p>
+ Own Id: OTP-9238</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>ET 1.4.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/et/src/et_wx_viewer.erl b/lib/et/src/et_wx_viewer.erl
index 7d4286ed9d..386f8fc86b 100644
--- a/lib/et/src/et_wx_viewer.erl
+++ b/lib/et/src/et_wx_viewer.erl
@@ -257,10 +257,10 @@ parse_opt([H | T], S, CollectorOpt) ->
Actors = [create_actor(Name) || Name <- ActorNames2],
parse_opt(T, S#state{actors = Actors}, CollectorOpt);
{include, ActorNames} when is_list(ActorNames) ->
- Actors = [opt_create_actor(Name, include, S#state.actors) || Name <- ActorNames],
+ Actors = [opt_create_actor(Name, include, S) || Name <- ActorNames],
parse_opt(T, S#state{actors = Actors}, CollectorOpt);
{exclude, ActorNames} when is_list(ActorNames) ->
- Actors = [opt_create_actor(Name, exclude, S#state.actors) || Name <- ActorNames],
+ Actors = [opt_create_actor(Name, exclude, S) || Name <- ActorNames],
parse_opt(T, S#state{actors = Actors}, CollectorOpt);
{first_event, _FirstKey} ->
%% NYI
diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk
index d7cfd7bc84..ea98aeba11 100644
--- a/lib/et/vsn.mk
+++ b/lib/et/vsn.mk
@@ -1 +1 @@
-ET_VSN = 1.4.2
+ET_VSN = 1.4.3
diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml
index a9960153e5..a02d76c5b9 100644
--- a/lib/eunit/doc/src/notes.xml
+++ b/lib/eunit/doc/src/notes.xml
@@ -32,6 +32,46 @@
</header>
<p>This document describes the changes made to the EUnit application.</p>
+<section><title>Eunit 2.1.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Increase depth of error messages in Eunit Surefire
+ reports</p>
+ <p>
+ Currently, error messages in Eunit Surefire reports are
+ shortened just like when written to a terminal. However,
+ the space limitations that constrain terminal output do
+ not apply here, so it's more useful to include more of
+ the error message. The new depth of 100 should be enough
+ for most cases, while protecting against runaway errors.
+ (Thanks to Magnus Henoch)</p>
+ <p>
+ Own Id: OTP-9220</p>
+ </item>
+ <item>
+ <p>
+ Don't let eunit_surefire report back to eunit when
+ stopping</p>
+ <p>
+ When eunit is terminating, a stop message is sent to all
+ listeners and eunit then waits for *one* result message
+ but previously both eunit_tty and eunit_surefire sent a
+ response on error. Don't send a result message from
+ eunit_surefire; let eunit_tty take care of all result
+ reporting, both positive and negative to avoid race
+ conditions and inconsistencies. (Thanks to Klas
+ Johansson)</p>
+ <p>
+ Own Id: OTP-9269</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Eunit 2.1.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl
index dfb08c90b2..25b5cde09c 100644
--- a/lib/eunit/src/eunit_surefire.erl
+++ b/lib/eunit/src/eunit_surefire.erl
@@ -64,6 +64,7 @@
}).
-record(testsuite,
{
+ id = 0 :: integer(),
name = <<>> :: binary(),
time = 0 :: integer(),
output = <<>> :: binary(),
@@ -76,7 +77,7 @@
-record(state, {verbose = false,
indent = 0,
xmldir = ".",
- testsuite = #testsuite{}
+ testsuites = [] :: [#testsuite{}]
}).
start() ->
@@ -89,55 +90,60 @@ init(Options) ->
XMLDir = proplists:get_value(dir, Options, ?XMLDIR),
St = #state{verbose = proplists:get_bool(verbose, Options),
xmldir = XMLDir,
- testsuite = #testsuite{}},
+ testsuites = []},
receive
{start, _Reference} ->
St
end.
terminate({ok, _Data}, St) ->
- TestSuite = St#state.testsuite,
+ TestSuites = St#state.testsuites,
XmlDir = St#state.xmldir,
- write_report(TestSuite, XmlDir),
+ write_reports(TestSuites, XmlDir),
ok;
terminate({error, _Reason}, _St) ->
%% Don't report any errors here, since eunit_tty takes care of that.
%% Just terminate.
ok.
-handle_begin(group, Data, St) ->
+handle_begin(Kind, Data, St) when Kind == group; Kind == test ->
+ %% Run this code both for groups and tests; test is a bit
+ %% surprising: This is a workaround for the fact that we don't get
+ %% a group (handle_begin(group, ...) for testsuites (modules)
+ %% which only have one test case. In that case we get a test case
+ %% with an id comprised of just one integer - the group id.
NewId = proplists:get_value(id, Data),
case NewId of
[] ->
St;
- [_GroupId] ->
+ [GroupId] ->
Desc = proplists:get_value(desc, Data),
- TestSuite = St#state.testsuite,
- NewTestSuite = TestSuite#testsuite{name = Desc},
- St#state{testsuite=NewTestSuite};
+ TestSuite = #testsuite{id = GroupId, name = Desc},
+ St#state{testsuites=store_suite(TestSuite, St#state.testsuites)};
%% Surefire format is not hierarchic: Ignore subgroups:
_ ->
St
- end;
-handle_begin(test, _Data, St) ->
- St.
+ end.
handle_end(group, Data, St) ->
%% Retrieve existing test suite:
case proplists:get_value(id, Data) of
[] ->
St;
- [_GroupId|_] ->
- TestSuite = St#state.testsuite,
+ [GroupId|_] ->
+ TestSuites = St#state.testsuites,
+ TestSuite = lookup_suite_by_group_id(GroupId, TestSuites),
%% Update TestSuite data:
Time = proplists:get_value(time, Data),
Output = proplists:get_value(output, Data),
NewTestSuite = TestSuite#testsuite{ time = Time, output = Output },
- St#state{testsuite=NewTestSuite}
+ St#state{testsuites=store_suite(NewTestSuite, TestSuites)}
end;
handle_end(test, Data, St) ->
%% Retrieve existing test suite:
- TestSuite = St#state.testsuite,
+ [GroupId|_] = proplists:get_value(id, Data),
+ TestSuites = St#state.testsuites,
+ TestSuite = lookup_suite_by_group_id(GroupId, TestSuites),
%% Create test case:
Name = format_name(proplists:get_value(source, Data),
@@ -149,7 +155,7 @@ handle_end(test, Data, St) ->
TestCase = #testcase{name = Name, description = Desc,
time = Time,output = Output},
NewTestSuite = add_testcase_to_testsuite(Result, TestCase, TestSuite),
- St#state{testsuite=NewTestSuite}.
+ St#state{testsuites=store_suite(NewTestSuite, TestSuites)}.
%% Cancel group does not give information on the individual cancelled test case
%% We ignore this event
@@ -157,7 +163,9 @@ handle_cancel(group, _Data, St) ->
St;
handle_cancel(test, Data, St) ->
%% Retrieve existing test suite:
- TestSuite = St#state.testsuite,
+ [GroupId|_] = proplists:get_value(id, Data),
+ TestSuites = St#state.testsuites,
+ TestSuite = lookup_suite_by_group_id(GroupId, TestSuites),
%% Create test case:
Name = format_name(proplists:get_value(source, Data),
@@ -171,7 +179,7 @@ handle_cancel(test, Data, St) ->
NewTestSuite = TestSuite#testsuite{
skipped = TestSuite#testsuite.skipped+1,
testcases=[TestCase|TestSuite#testsuite.testcases] },
- St#state{testsuite=NewTestSuite}.
+ St#state{testsuites=store_suite(NewTestSuite, TestSuites)}.
format_name({Module, Function, Arity}, Line) ->
lists:flatten([atom_to_list(Module), ":", atom_to_list(Function), "/",
@@ -183,6 +191,12 @@ format_desc(Desc) when is_binary(Desc) ->
format_desc(Desc) when is_list(Desc) ->
Desc.
+lookup_suite_by_group_id(GroupId, TestSuites) ->
+ #testsuite{} = lists:keyfind(GroupId, #testsuite.id, TestSuites).
+
+store_suite(#testsuite{id=GroupId} = TestSuite, TestSuites) ->
+ lists:keystore(GroupId, #testsuite.id, TestSuites, TestSuite).
+
%% Add testcase to testsuite depending on the result of the test.
add_testcase_to_testsuite(ok, TestCaseTmp, TestSuite) ->
TestCase = TestCaseTmp#testcase{ result = ok },
@@ -214,6 +228,10 @@ add_testcase_to_testsuite({error, Exception}, TestCaseTmp, TestSuite) ->
%% Write a report to the XML directory.
%% This function opens the report file, calls write_report_to/2 and closes the file.
%% ----------------------------------------------------------------------------
+write_reports(TestSuites, XmlDir) ->
+ lists:foreach(fun(TestSuite) -> write_report(TestSuite, XmlDir) end,
+ TestSuites).
+
write_report(#testsuite{name = Name} = TestSuite, XmlDir) ->
Filename = filename:join(XmlDir, lists:flatten(["TEST-", escape_suitename(Name)], ".xml")),
case file:open(Filename, [write, raw]) of
diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk
index e1965630e3..d7edd7977b 100644
--- a/lib/eunit/vsn.mk
+++ b/lib/eunit/vsn.mk
@@ -1 +1 @@
-EUNIT_VSN = 2.1.6
+EUNIT_VSN = 2.1.7
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index c009164f4c..82e3675938 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -154,7 +154,7 @@ type(binary, bin_to_list, Arity, Xs) when 1 =< Arity, Arity =< 3 ->
fun(_) -> t_list(t_integer()) end);
type(binary, compile_pattern, 1, Xs) ->
strict(arg_types(binary, compile_pattern, 1), Xs,
- fun(_) -> t_tuple([t_atom(bm),t_binary()]) end);
+ fun(_) -> t_binary_compiled_pattern() end);
type(binary, copy, Arity, Xs) when Arity =:= 1; Arity =:= 2 ->
strict(arg_types(binary, copy, Arity), Xs,
fun(_) -> t_binary() end);
@@ -672,6 +672,9 @@ type(erlang, call_on_load_function, 1, Xs) ->
type(erlang, cancel_timer, 1, Xs) ->
strict(arg_types(erlang, cancel_timer, 1), Xs,
fun (_) -> t_sup(t_integer(), t_atom('false')) end);
+type(erlang, check_old_code, 1, Xs) ->
+ strict(arg_types(erlang, check_old_code, 1), Xs,
+ fun (_) -> t_boolean() end);
type(erlang, check_process_code, 2, Xs) ->
strict(arg_types(erlang, check_process_code, 2), Xs,
fun (_) -> t_boolean() end);
@@ -702,7 +705,7 @@ type(erlang, demonitor, 1, Xs) ->
type(erlang, demonitor, 2, Xs) ->
strict(arg_types(erlang, demonitor, 2), Xs, fun (_) -> t_boolean() end);
type(erlang, disconnect_node, 1, Xs) ->
- strict(arg_types(erlang, disconnect_node, 1), Xs, fun (_) -> t_boolean() end);
+ strict(arg_types(erlang, disconnect_node, 1), Xs, fun (_) -> t_sup([t_boolean(), t_atom('ignored')]) end);
type(erlang, display, 1, _) -> t_atom('true');
type(erlang, display_string, 1, Xs) ->
strict(arg_types(erlang, display_string, 1), Xs, fun(_) -> t_atom('true') end);
@@ -1124,7 +1127,7 @@ type(erlang, nodes, 0, _) -> t_list(t_node());
type(erlang, nodes, 1, Xs) ->
strict(arg_types(erlang, nodes, 1), Xs, fun (_) -> t_list(t_node()) end);
type(erlang, now, 0, _) ->
- t_time();
+ t_timestamp();
type(erlang, open_port, 2, Xs) ->
strict(arg_types(erlang, open_port, 2), Xs, fun (_) -> t_port() end);
type(erlang, phash, 2, Xs) ->
@@ -1585,8 +1588,7 @@ type(erlang, system_info, 1, Xs) ->
['multi_scheduling_blockers'] ->
t_list(t_pid());
['os_type'] ->
- t_tuple([t_sup([t_atom('ose'), % XXX: undocumented
- t_atom('unix'),
+ t_tuple([t_sup([t_atom('unix'),
t_atom('vxworks'),
t_atom('win32')]),
t_atom()]);
@@ -2693,7 +2695,7 @@ type(os, getpid, 0, _) -> t_string();
type(os, putenv, 2, Xs) ->
strict(arg_types(os, putenv, 2), Xs, fun (_) -> t_atom('true') end);
type(os, timestamp, 0, _) ->
- t_time();
+ t_timestamp();
%%-- re -----------------------------------------------------------------------
type(re, compile, 1, Xs) ->
strict(arg_types(re, compile, 1), Xs,
@@ -3396,6 +3398,8 @@ arg_types(erlang, call_on_load_function, 1) ->
[t_atom()];
arg_types(erlang, cancel_timer, 1) ->
[t_reference()];
+arg_types(erlang, check_old_code, 1) ->
+ [t_atom()];
arg_types(erlang, check_process_code, 2) ->
[t_pid(), t_atom()];
arg_types(erlang, concat_binary, 1) ->
@@ -4458,6 +4462,9 @@ t_date() ->
t_time() ->
t_tuple([t_non_neg_fixnum(), t_non_neg_fixnum(), t_non_neg_fixnum()]).
+t_timestamp() ->
+ t_tuple([t_non_neg_fixnum(), t_non_neg_fixnum(), t_non_neg_fixnum()]).
+
t_packet() ->
t_sup([t_binary(), t_iolist(), t_httppacket()]).
@@ -4469,27 +4476,6 @@ t_endian() ->
t_sup(t_atom('big'), t_atom('little')).
%% =====================================================================
-%% Types for the binary module
-%% =====================================================================
-
-t_binary_part() ->
- t_tuple([t_non_neg_integer(), t_integer()]).
-
-t_binary_canonical_part() ->
- t_tuple([t_non_neg_integer(), t_non_neg_integer()]).
-
-t_binary_pattern() ->
- t_sup([t_binary(),
- t_list(t_binary()),
- t_binary_compiled_pattern()]).
-
-t_binary_compiled_pattern() ->
- t_tuple([t_atom('cp'), t_binary()]).
-
-t_binary_options() ->
- t_list(t_tuple([t_atom('scope'), t_binary_part()])).
-
-%% =====================================================================
%% HTTP types documented in R12B-4
%% =====================================================================
@@ -4544,7 +4530,28 @@ t_HttpFieldAtom() ->
'Keep-Alive', 'Proxy-Connection']).
t_HttpString() ->
- t_sup(t_string(),t_binary()).
+ t_sup(t_string(), t_binary()).
+
+%% =====================================================================
+%% These are used for the built-in functions of 'binary'
+%% =====================================================================
+
+t_binary_part() ->
+ t_tuple([t_non_neg_integer(), t_integer()]).
+
+t_binary_canonical_part() ->
+ t_tuple([t_non_neg_integer(), t_non_neg_integer()]).
+
+t_binary_pattern() ->
+ t_sup([t_binary(),
+ t_list(t_binary()),
+ t_binary_compiled_pattern()]).
+
+t_binary_compiled_pattern() ->
+ t_tuple([t_sup(t_atom('bm'), t_atom('ac')), t_binary()]).
+
+t_binary_options() ->
+ t_list(t_tuple([t_atom('scope'), t_binary_part()])).
%% =====================================================================
%% These are used for the built-in functions of 'code'
@@ -4565,11 +4572,6 @@ t_code_load_error_rsn() -> % also used in erlang:load_module/2
t_atom('on_load'),
t_atom('sticky_directory')]). % only for the 'code' functions
-t_code_loaded_fname_or_status() ->
- t_sup([t_string(), % filename
- t_atom('preloaded'),
- t_atom('cover_compiled')]).
-
%% =====================================================================
%% These are used for the built-in functions of 'erlang'
%% =====================================================================
@@ -4734,7 +4736,6 @@ t_scheduler_bind_type_results() ->
t_atom('thread_no_node_processor_spread'),
t_atom('unbound')]).
-
t_system_monitor_settings() ->
t_sup([t_atom('undefined'),
t_tuple([t_pid(), t_system_monitor_options()])]).
@@ -4814,13 +4815,6 @@ t_ets_info_items() ->
t_atom('type')]).
%% =====================================================================
-%% These are used for the built-in functions of 'prim_file'
-%% =====================================================================
-
-t_prim_file_name() ->
- t_sup(t_unicode_string(), t_binary()).
-
-%% =====================================================================
%% These are used for the built-in functions of 'gen_tcp'
%% =====================================================================
@@ -5014,6 +5008,13 @@ t_re_CapturedData() ->
t_sup([t_tuple([t_integer(), t_integer()]), t_string(), t_binary()]).
%% =====================================================================
+%% These are used for the built-in functions of 'prim_file'
+%% =====================================================================
+
+t_prim_file_name() ->
+ t_sup(t_unicode_string(), t_binary()).
+
+%% =====================================================================
%% These are used for the built-in functions of 'unicode'
%% =====================================================================
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 5c06e5e558..4eb188f76f 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,39 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix hipe bug causing minor heap corruption related to
+ binary matching. The bug has not been confirmed as the
+ cause of any actual fault symptom.</p>
+ <p>
+ Own Id: OTP-9182</p>
+ </item>
+ <item>
+ <p>
+ Enable HiPE by default when compiling for PPC64</p>
+ <p>
+ Own Id: OTP-9198</p>
+ </item>
+ <item>
+ <p>
+ Fix handling of &lt;&lt;_:N,_:_*M&gt;&gt; type
+ expressions Fix the argument of
+ erlang:list_to_bitstring/1 Remove unneeded function
+ 'sequence/2' Same functionality provided by
+ string:join/2.</p>
+ <p>
+ Own Id: OTP-9277</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.7.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 6ba9009a24..58ebe68401 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.7.9
+HIPE_VSN = 3.8
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 5f6c31069c..de519d5f84 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1998</year><year>2010</year>
+ <year>1998</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -31,6 +31,22 @@
</header>
<section>
+ <title>IC 4.2.27</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Reduced compile overhead (Thanks to Haitao Li).</p>
+ <p>
+ Own Id: OTP-9460 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>IC 4.2.26</title>
<section>
diff --git a/lib/ic/src/ic_pp.erl b/lib/ic/src/ic_pp.erl
index db06118d32..8b53473caa 100644
--- a/lib/ic/src/ic_pp.erl
+++ b/lib/ic/src/ic_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -92,6 +92,14 @@
%%
%%======================================================================================
+%% Multiple Include Optimization
+%%
+%% Algorithm described at:
+%% http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
+-record(mio, {valid = true, %% multiple include valid
+ cmacro, %% controlling macro of the current conditional directive
+ depth = 0, %% conditional directive depth
+ included = []}).
@@ -130,7 +138,7 @@ run(FileList, FileName, IncDir, Flags) ->
%%----------------------------------------------------------
%% Run the second phase, i.e expand macros
%%----------------------------------------------------------
- {Out, Err, War, _Defs, IfCou} = expand(File, FileName, IncDir, Flags),
+ {Out, Err, War, _Defs, _Mio, IfCou} = expand(File, FileName, IncDir, Flags),
%%----------------------------------------------------------
%% Check if all #if #ifdef #ifndef have a matching #endif
@@ -155,9 +163,9 @@ run(FileList, FileName, IncDir, Flags) ->
%% The entry for all included files
%%
%%
-%% Output {Out, Defs, Err, War}
+%% Output {Out, Err, War, Defs, MultipleIncludeValid}
%%======================================================================================
-run_include(FileName, FileList, _Out, Defs, Err, War, IncLine, IncFile, IncDir) ->
+run_include(FileName, FileList, _Out, Defs, Err, War, IncLine, IncFile, IncDir, Mio) ->
%%----------------------------------------------------------
%% Run the first phase, i.e tokenise the file
@@ -169,18 +177,21 @@ run_include(FileName, FileList, _Out, Defs, Err, War, IncLine, IncFile, IncDir)
%%----------------------------------------------------------
%% Run the second phase, i.e expand macros
%%----------------------------------------------------------
-
- %% Try first pass without file info start/end
- {OutT, ErrT, WarT, DefsT, IfCouT} =
- expand(File, Defs, Err, War, [FileName|IncFile], IncDir),
-
- {Out2, Err2, War2, Defs2, IfCou2} =
- case only_nls(OutT) of
- true -> %% The file is defined before
- {["\n"], ErrT, WarT, DefsT, IfCouT};
- false -> %% The file is not defined before, try second pass
- expand([FileInfoStart|File]++FileInfoEnd, Defs, Err, War, [FileName|IncFile], IncDir)
- end,
+ {Out2, Err2, War2, Defs2, Mio2, IfCou2} =
+ expand([FileInfoStart|File]++FileInfoEnd, Defs, Err, War,
+ [FileName|IncFile], IncDir,
+ #mio{included=Mio#mio.included}),
+
+ MergeIncluded = sets:to_list(sets:from_list(Mio#mio.included ++ Mio2#mio.included)),
+
+ Mio3 =
+ case {Mio2#mio.valid, Mio2#mio.cmacro} of
+ {V, Macro} when V == false;
+ Macro == undefined ->
+ update_mio(Mio#mio{included=MergeIncluded});
+ {true, _} ->
+ update_mio({include, FileName}, Mio#mio{included=MergeIncluded})
+ end,
%%----------------------------------------------------------
%% Check if all #if #ifdef #ifndef have a matching #endif
@@ -192,26 +203,7 @@ run_include(FileName, FileList, _Out, Defs, Err, War, IncLine, IncFile, IncDir)
[]
end,
- {Out2, Defs2, Err2++IfError, War2}.
-
-
-
-%% Return true if there is no data
-%% other than new lines
-only_nls([]) ->
- true;
-only_nls(["\n"|Rem]) ->
- only_nls(Rem);
-only_nls(["\r","\n"|Rem]) ->
- only_nls(Rem);
-only_nls([_|_Rem]) ->
- false.
-
-
-
-
-
-
+ {Out2, Defs2, Err2++IfError, War2, Mio3}.
@@ -647,87 +639,86 @@ expand(List, FileName, IncDir, Flags) ->
%% Get all definitions from preprocessor commnads
%% and merge them on top of the file collected.
CLDefs = get_cmd_line_defs(Flags),
- expand(List, [], [], CLDefs, [FileName], IncDir, check_all, [], [], 1, FileName).
-
-expand(List, Defs, Err, War, [FileName|IncFile], IncDir) ->
- expand(List, [], [], Defs, [FileName|IncFile], IncDir, check_all, Err, War, 1, FileName).
+ expand(List, [], [], CLDefs, [FileName], IncDir, #mio{}, check_all, [], [], 1, FileName).
+expand(List, Defs, Err, War, [FileName|IncFile], IncDir, Mio) ->
+ expand(List, [], [], Defs, [FileName|IncFile], IncDir, Mio, check_all, Err, War, 1, FileName).
%%=======================================================
%% Main loop for the expansion
%%=======================================================
-expand([], Out, _SelfRef, Defs, _IncFile, _IncDir, IfCou, Err, War, _L, _FN) ->
+expand([], Out, _SelfRef, Defs, _IncFile, _IncDir, Mio, IfCou, Err, War, _L, _FN) ->
% io:format("~n ===============~n"),
% io:format(" definitions ~p~n",[lists:reverse(Defs)]),
% io:format(" found warnings ~p~n",[lists:reverse(War)]),
% io:format(" found errors ~p~n",[lists:reverse(Err)]),
% io:format(" ===============~n~n~n"),
- {Out, Err, War, Defs, IfCou};
+ {Out, Err, War, Defs, Mio, IfCou};
-expand([{file_info, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, Str++Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{file_info, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, Str++Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN);
%%---------------------------------------
%% Searching for endif,
%% i.e skip all source lines until matching
%% end if is encountered
%%---------------------------------------
-expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)
+expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN)
when Command == "ifdef" ->
{_Removed, Rem2, _Nl} = read_to_nl(Rem),
IfCou2 = {endif, Endif+1, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err, War, L, FN);
-expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)
+expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN)
when Command == "ifndef" ->
{_Removed, Rem2, _Nl} = read_to_nl(Rem),
IfCou2 = {endif, Endif+1, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err, War, L, FN);
-expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)
+expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN)
when Command == "if" ->
- case pp_command(Command, Rem, Defs, IncDir, Err, War, L, FN) of
+ case pp_command(Command, Rem, Defs, IncDir, Mio, Err, War, L, FN) of
{{'if', true}, Rem2, Err2, War2, Nl} ->
IfCou2 = {endif, Endif+1, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err2, War2, L+Nl, FN);
%% {{'if', false}, Rem2, Err2, War2, Nl} -> Not implemented yet
{{'if', error}, Rem2, Err2, War2, Nl} ->
IfCou2 = {endif, Endif, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN)
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err2, War2, L+Nl, FN)
end;
-expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)
+expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN)
when Command == "endif" ->
{_Removed, Rem2, Nl} = read_to_nl(Rem),
case Endif of
1 ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio, check_all, Err, War, L+Nl, FN);
_ ->
IfCou2 = {endif, Endif-1, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L+Nl, FN)
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err, War, L+Nl, FN)
end;
-expand([{command,_Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) ->
+expand([{command,_Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN) ->
{_Removed, Rem2, _Nl} = read_to_nl(Rem),
IfCou2 = {endif, Endif, IfLine},
- expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);
+ expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err, War, L, FN);
%% Solves a bug when spaces in front of hashmark !
-expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) ->
- expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);
+expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN) ->
+ expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN);
-expand([{nl,_Nl} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) ->
- expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);
+expand([{nl,_Nl} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN) ->
+ expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN);
-expand([_X | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) ->
+expand([_X | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN) ->
{_Removed, Rem2, Nl} = read_to_nl(Rem),
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio, {endif, Endif, IfLine}, Err, War, L, FN);
@@ -736,121 +727,132 @@ expand([_X | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine},
%%---------------------------------------
%% Check all tokens
%%---------------------------------------
-expand([{nl, _N} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [$\n | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L+1, FN);
+expand([{nl, _N} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [$\n | Out], SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L+1, FN);
-expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN);
-expand([space_exp | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([space_exp | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN);
-expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L, FN) ->
- case pp_command(Command, Rem, Defs, IncDir, Err, War, L, FN) of
+expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, check_all, Err, War, L, FN) ->
+ case pp_command(Command, Rem, Defs, IncDir, Mio, Err, War, L, FN) of
{define, Rem2, Defs2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, update_mio(Mio), check_all, Err2, War2, L+Nl, FN);
{undef, Rem2, Defs2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, update_mio(Mio), check_all, Err2, War2, L+Nl, FN);
{{include, ok}, FileName, FileCont, Rem2, Nl, Err2, War2} ->
- {Out3, Defs3, Err3, War3} =
- run_include(FileName, FileCont, Out, Defs, Err2, War2, L+Nl, IncFile, IncDir),
+ {Out3, Defs3, Err3, War3, Mio2} =
+ run_include(FileName, FileCont, Out, Defs, Err2, War2, L+Nl, IncFile, IncDir, Mio),
Nls = [],
Out4 = Out3++Nls++Out,
- expand(Rem2, Out4, SelfRef, Defs3, IncFile, IncDir, check_all, Err3, War3, L+Nl, FN);
+ expand(Rem2, Out4, SelfRef, Defs3, IncFile, IncDir, Mio2, check_all, Err3, War3, L+Nl, FN);
{{include, error}, Rem2, Nl, Err2, War2} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, Err2, War2, L+Nl, FN);
+
+ {{include, skip}, Rem2} ->
+ Out2 = [$\n|Out],
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, Err, War, L+1, FN);
{{ifdef, true}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
IfCou2 = {endif, 1, L},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err2, War2, L+Nl, FN);
{{ifdef, false}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ Mio2 = update_mio(ifdef, Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err2, War2, L+Nl, FN);
{{ifndef, true}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
IfCou2 = {endif, 1, L},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);
- {{ifndef, false}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err2, War2, L+Nl, FN);
+ {{ifndef, false}, Macro, Rem2, Err2, War2, Nl} ->
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ Mio2 = update_mio({ifndef, Macro}, Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err2, War2, L+Nl, FN);
{endif, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ Mio2 = update_mio(endif, Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err2, War2, L+Nl, FN);
{{'if', true}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
IfCou2 = {endif, 1, L},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio, IfCou2, Err2, War2, L+Nl, FN);
%% {{'if', false}, Removed, Rem2, Nl} -> Not implemented at present
{{'if', error}, Rem2, Err2, War2, Nl} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ Mio2 = update_mio('if', Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err2, War2, L+Nl, FN);
{'else', {_Removed, Rem2, Nl}} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
Err2 = {FN, L, "`else' command is not implemented at present"},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN);
+ Mio2 = update_mio('else', Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, [Err2|Err], War, L+Nl, FN);
{'elif', {_Removed, Rem2, Nl}} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
Err2 = {FN, L, "`elif' command is not implemented at present"},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN);
+ Mio2 = update_mio('elif', Mio),
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, [Err2|Err], War, L+Nl, FN);
{warning, {WarningText, Rem2, Nl}} ->
[FileName|_More] = IncFile,
War2 = {FileName, L, "warning: #warning "++detokenise(WarningText)},
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, [War2|War], L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, Err, [War2|War], L+Nl, FN);
{error, {ErrorText, Rem2, Nl}} ->
[FileName|_More] = IncFile,
Err2 = {FileName, L, detokenise(ErrorText)},
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, [Err2|Err], War, L+Nl, FN);
{{line, ok}, {_Removed, Rem2, Nl}, L2, FN2, LineText} ->
Out2 = lists:duplicate(Nl,$\n)++LineText++Out,
[_X|IF] = IncFile,
IncFile2 = [FN2|IF],
- expand(Rem2, Out2, SelfRef, Defs, IncFile2, IncDir, check_all, Err, War, L2, FN2);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile2, IncDir, update_mio(Mio), check_all, Err, War, L2, FN2);
{{line, error}, {_Removed, Rem2, Nl}, Err2} ->
- Out2 = [lists:duplicate(Nl,$\n)|Out],
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN);
+ Out2 = lists:duplicate(Nl,$\n) ++ Out,
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, [Err2|Err], War, L+Nl, FN);
hash_mark ->
- expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L, FN);
+ expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, Mio, check_all, Err, War, L, FN);
{pragma, Rem2, Nl, Text} ->
Out2 = lists:duplicate(Nl,$\n)++Text++Out,
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, Err, War, L+Nl, FN);
{ident, Rem2, Nl, Text} ->
Out2 = lists:duplicate(Nl,$\n)++Text++Out,
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, update_mio(Mio), check_all, Err, War, L+Nl, FN);
{not_recognised, {Removed, Rem2, Nl}} ->
Text = lists:reverse([$#|Command]),
RemovedS = lists:reverse([?space|detokenise(Removed)]),
Out2 = [$\n|RemovedS]++Text++Out,
+ Mio2 = update_mio(Mio),
case Command of
[X|_T] when ?is_upper(X) ->
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err, War, L+Nl, FN);
[X|_T] when ?is_lower(X) ->
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err, War, L+Nl, FN);
[X|_T] when ?is_underline(X) ->
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN);
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, Err, War, L+Nl, FN);
_ ->
Err2 = {FN, L, "invalid preprocessing directive name"},
- expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN)
+ expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, Mio2, check_all, [Err2|Err], War, L+Nl, FN)
end;
Else ->
@@ -859,19 +861,19 @@ expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, check_all
end;
-expand([{var, "__LINE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, "__LINE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
LL = io_lib:format("~p",[L]),
- expand(Rem, [LL | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, [LL | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, "__FILE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [$",FN,$" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{var, "__FILE__"}|Rem], Out, SelfRef, Defs, IncFile, Mio, IncDir, IfCou, Err, War, L, FN) ->
+ expand(Rem, [$",FN,$" | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, "__DATE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, "__DATE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
{{Y,M,D},{_H,_Mi,_S}} = calendar:universal_time(),
Date = io_lib:format("\"~s ~p ~p\"",[month(M),D,Y]),
- expand(Rem, [Date | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, [Date | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, "__TIME__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, "__TIME__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
{{_Y,_M,_D},{H,Mi,S}} = calendar:universal_time(),
HS = if H < 10 -> "0"++integer_to_list(H);
true -> integer_to_list(H)
@@ -883,40 +885,40 @@ expand([{var, "__TIME__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err,
true -> integer_to_list(S)
end,
Time = io_lib:format("\"~s:~s:~s\"",[HS,MiS,SS]),
- expand(Rem, [Time | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, [Time | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, "__INCLUDE_LEVEL__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, "__INCLUDE_LEVEL__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
IL = io_lib:format("~p",[length(IncFile)-1]),
- expand(Rem, [IL | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, [IL | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, "__BASE_FILE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, "__BASE_FILE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
[BF|_T] = lists:reverse(IncFile),
- expand(Rem, [$",BF,$" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, [$",BF,$" | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{var, Var} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{var, Var} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
{Out2, Err2, War2, Rem2, SelfRef2} =
source_line(Var, Rem, SelfRef, Defs, Err, War, L, FN),
- expand(Rem2, [Out2 | Out], SelfRef2, Defs, IncFile, IncDir, IfCou, Err2, War2, L, FN);
+ expand(Rem2, [Out2 | Out], SelfRef2, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err2, War2, L, FN);
-expand([{char, Char} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [Char | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{char, Char} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [Char | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{number, Number} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [Number | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{number, Number} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [Number | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{expanded, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [Str | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{expanded, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [Str | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{self_ref, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{self_ref, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
SelfRef2 = lists:delete(Str,SelfRef),
- expand(Rem, Out, SelfRef2, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+ expand(Rem, Out, SelfRef2, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{string, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
- expand(Rem, [$", Str, $" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);
+expand([{string, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
+ expand(Rem, [$", Str, $" | Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L, FN);
-expand([{string_part, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) ->
+expand([{string_part, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, Mio, IfCou, Err, War, L, FN) ->
{Str2, Rem2, Nl} = expand_string_part([$"|Str], Rem),
- expand(Rem2, [Str2| Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L+Nl, FN).
+ expand(Rem2, [Str2| Out], SelfRef, Defs, IncFile, IncDir, update_mio(Mio), IfCou, Err, War, L+Nl, FN).
@@ -954,13 +956,14 @@ expand_string_part([{string_part, Str_part} | Rem], Str, Nl) ->
get_cmd_line_defs(Flags) ->
Adjusted = parse_cmd_line(Flags,[]),
- {_Out, _Err, _War, Defs, _IfCou} =
+ {_Out, _Err, _War, Defs, _IfCou, _Mio} =
expand(tokenise(Adjusted,""),
[],
[],
[],
[],
[],
+ #mio{},
check_all,
[],
[],
@@ -1030,10 +1033,10 @@ collect_undefine([C|Rest],Found) ->
%%======================================================================================
%%======================================================================================
-pp_command(Command, [space|File], Defs, IncDir, Err, War, L, FN) ->
- pp_command(Command, File, Defs, IncDir, Err, War, L, FN);
+pp_command(Command, [space|File], Defs, IncDir, Mio, Err, War, L, FN) ->
+ pp_command(Command, File, Defs, IncDir, Mio, Err, War, L, FN);
-pp_command(Command, File, Defs, IncDir, Err, War, L, FN) ->
+pp_command(Command, File, Defs, IncDir, Mio, Err, War, L, FN) ->
case Command of
%%----------------------------------------
@@ -1081,14 +1084,16 @@ pp_command(Command, File, Defs, IncDir, Err, War, L, FN) ->
%% #include
%%----------------------------------------
"include" ->
- case include(File, IncDir) of
- {error, Rem, Nl, Err2} ->
- {{include, error}, Rem, Nl, [{FN, L, Err2}|Err], War};
- {error, Rem, Nl, Err2, NameNl} ->
- {{include, error}, Rem, Nl, [{FN, L+ NameNl, Err2}|Err], War};
- {ok, FileName, FileCont, Rem, Nl} ->
- {{include, ok}, FileName, FileCont, Rem, Nl, Err, War}
- end;
+ case include(File, IncDir, Mio) of
+ {error, Rem, Nl, Err2} ->
+ {{include, error}, Rem, Nl, [{FN, L, Err2}|Err], War};
+ {error, Rem, Nl, Err2, NameNl} ->
+ {{include, error}, Rem, Nl, [{FN, L+ NameNl, Err2}|Err], War};
+ {ok, FileNamePath, FileCont, Rem, Nl} ->
+ {{include, ok}, FileNamePath, FileCont, Rem, Nl, Err, War};
+ {skip, Rem} ->
+ {{include, skip}, Rem}
+ end;
%%----------------------------------------
%% #ifdef
@@ -1127,14 +1132,14 @@ pp_command(Command, File, Defs, IncDir, Err, War, L, FN) ->
yes ->
{{ifndef, true}, Rem, Err2, War2, Nl};
no ->
- {{ifndef, false}, Rem, Err2, War2, Nl}
+ {{ifndef, false}, Name, Rem, Err2, War2, Nl}
end;
{ok, Rem, Name, No_of_para, _Parameters, _Macro, Err2, War2, Nl} ->
case is_defined_before(Name, No_of_para, Defs) of
yes ->
{{ifndef, true}, Rem, Err2, War2, Nl};
no ->
- {{ifndef, false}, Rem, Err2, War2, Nl}
+ {{ifndef, false}, Name, Rem, Err2, War2, Nl}
end
end;
@@ -1408,29 +1413,32 @@ undef(_Rem) ->
%%===============================================================
%%===============================================================
-include(File, IncDir) ->
+include(File, IncDir, Mio) ->
case include2(File) of
- {ok, FileName, Rem, Nl, FileType} ->
- %% The error handling is lite strange just to make it compatible to gcc
- case {read_inc_file(FileName, IncDir), Nl, FileType} of
- {{ok, FileList, FileNamePath}, _, _} ->
- {ok, FileNamePath, FileList, Rem, Nl};
- {{error, Text}, _, own_file} ->
- NameNl = count_nl(FileName,0),
- Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),
- {error, Rem, Nl, Error, NameNl};
- {{error, Text}, 1, sys_file} ->
- NameNl = count_nl(FileName,0),
- Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),
- {error, Rem, Nl, Error, NameNl};
- {{error, _Text}, _, sys_file} ->
- {error, Rem, Nl, "`#include' expects \"FILENAME\" or <FILENAME>"}
- end;
-
- {error, {_Removed, Rem, Nl}} ->
- {error, Rem, Nl, "`#include' expects \"FILENAME\" or <FILENAME>"}
+ {ok, FileName, Rem, Nl, FileType} ->
+ Result = read_inc_file(FileName, IncDir, Mio),
+ case {Result, Nl, FileType} of
+ {{ok, FileNamePath, FileCont}, _, _} ->
+ {ok, FileNamePath, FileCont, Rem, Nl};
+ {skip, _, _} ->
+ {skip, Rem};
+ {{error, Text}, _, own_file} ->
+ NameNl = count_nl(FileName,0),
+ Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),
+ {error, Rem, Nl, Error, NameNl};
+ {{error, Text}, 1, sys_file} ->
+ NameNl = count_nl(FileName,0),
+ Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),
+ {error, Rem, Nl, Error, NameNl};
+ {{error, _Text}, _, sys_file} ->
+ {error, Rem, Nl, "`#include' expects \"FILENAME\" or <FILENAME>"}
+ end;
+ {error, {_Removed, Rem, Nl}} ->
+ {error, Rem, Nl, "`#include' expects \#FILENAME\" or <FILENAME>"}
end.
+
+
count_nl([],Nl) ->
Nl;
count_nl([$\n|T],Nl) ->
@@ -1909,18 +1917,37 @@ include_dir(Flags,IncDir) ->
%% Read a included file. Try current dir first then the IncDir list
%%===============================================================
-read_inc_file(FileName, IncDir) ->
- case catch file:read_file(FileName) of
- {ok, Bin} ->
- FileList = binary_to_list(Bin),
- {ok, FileList, FileName};
+read_inc_file(FileName, IncDir, Mio) ->
+ case find_inc_file(FileName, IncDir) of
+ {ok, AbsFile} ->
+ %% is included before?
+ case lists:member(FileName, Mio#mio.included) of
+ false ->
+ case catch file:read_file(AbsFile) of
+ {ok, Bin} ->
+ FileList = binary_to_list(Bin),
+ {ok, AbsFile, FileList};
+ {error, Text} ->
+ {error, Text}
+ end;
+ true ->
+ skip
+ end;
+ {error, Text} ->
+ {error, Text}
+ end.
+
+find_inc_file(FileName, IncDir) ->
+ case catch file:read_file_info(FileName) of
+ {ok, _} ->
+ {ok, FileName};
{error, _} ->
- read_inc_file2(FileName, IncDir)
+ find_inc_file2(FileName, IncDir)
end.
-read_inc_file2(_FileName, []) ->
+find_inc_file2(_FileName, []) ->
{error, "No such file or directory"};
-read_inc_file2(FileName, [D|Rem]) ->
+find_inc_file2(FileName, [D|Rem]) ->
Dir = case lists:last(D) of
$/ ->
D;
@@ -1928,17 +1955,14 @@ read_inc_file2(FileName, [D|Rem]) ->
D++"/"
end,
- case catch file:read_file(Dir++FileName) of
- {ok, Bin} ->
- FileList = binary_to_list(Bin),
- {ok, FileList, Dir++FileName};
+ case catch file:read_file_info(Dir++FileName) of
+ {ok, _} ->
+ {ok, Dir++FileName};
{error, _} ->
- read_inc_file2(FileName, Rem)
+ find_inc_file2(FileName, Rem)
end.
-
-
%%===============================================================
%% Read parameters of a macro or a variable in a source line
%%===============================================================
@@ -2135,5 +2159,73 @@ month(11) -> "Nov";
month(12) -> "Dec".
+%% Multiple Include Optimization
+%%
+%% Algorithm described at:
+%% http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
+update_mio({include, FileName}, #mio{included=Inc}=Mio) ->
+ Mio#mio{valid=false, included=[FileName|Inc]};
+
+%% valid=false & cmacro=undefined indicates it is already decided this file is
+%% not subject to MIO
+update_mio(_, #mio{valid=false, depth=0, cmacro=undefined}=Mio) ->
+ Mio;
+
+%% if valid=true, there is no non-whitespace tokens before this ifndef
+update_mio({'ifndef', Macro}, #mio{valid=true, depth=0, cmacro=undefined}=Mio) ->
+ Mio#mio{valid=false, cmacro=Macro, depth=1};
+
+%% detect any tokens before top level #ifndef
+update_mio(_, #mio{valid=true, depth=0, cmacro=undefined}=Mio) ->
+ Mio#mio{valid=false};
+
+%% If cmacro is alreay set, this is after the top level #endif
+update_mio({'ifndef', _}, #mio{valid=true, depth=0}=Mio) ->
+ Mio#mio{valid=false, cmacro=undefined};
+
+%% non-top level conditional, just update depth
+update_mio({'ifndef', _}, #mio{depth=D}=Mio) when D > 0 ->
+ Mio#mio{depth=D+1};
+update_mio('ifdef', #mio{depth=D}=Mio) ->
+ Mio#mio{depth=D+1};
+update_mio('if', #mio{depth=D}=Mio) ->
+ Mio#mio{depth=D+1};
+
+%% top level #else #elif invalidates multiple include optimization
+update_mio('else', #mio{depth=1}=Mio) ->
+ Mio#mio{valid=false, cmacro=undefined};
+update_mio('else', Mio) ->
+ Mio;
+update_mio('elif', #mio{depth=1}=Mio) ->
+ Mio#mio{valid=false, cmacro=undefined};
+update_mio('elif', Mio) ->
+ Mio;
+
+%% AT exit to top level, if the controlling macro is not set, this could be the
+%% end of a non-ifndef conditional block, or there were tokens before entering
+%% the #ifndef block. In either way, this invalidates the MIO
+%%
+%% It doesn't matter if `valid` is true at the time of exiting, it is set to
+%% true. This will be used to detect if more tokens are following the top
+%% level #endif.
+update_mio('endif', #mio{depth=1, cmacro=undefined}=Mio) ->
+ Mio#mio{valid=false, depth=0};
+update_mio('endif', #mio{depth=1}=Mio) ->
+ Mio#mio{valid=true, depth=0};
+update_mio('endif', #mio{depth=D}=Mio) when D > 1 ->
+ Mio#mio{valid=true, depth=D-1};
+
+%%if more tokens are following the top level #endif.
+update_mio('endif', #mio{depth=1, cmacro=undefined}=Mio) ->
+ Mio#mio{valid=false, depth=0};
+update_mio('endif', #mio{depth=D}=Mio) when D > 0 ->
+ Mio#mio{valid=true, depth=D-1};
+update_mio(_, Mio) ->
+ Mio#mio{valid=false}.
+
+%% clear `valid`, this doesn't matter since #endif will restore it if
+%% appropriate
+update_mio(Mio) ->
+ Mio#mio{valid=false}.
diff --git a/lib/ic/src/ic_pragma.erl b/lib/ic/src/ic_pragma.erl
index 45cb64c9c8..7f2216b9dc 100644
--- a/lib/ic/src/ic_pragma.erl
+++ b/lib/ic/src/ic_pragma.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1600,9 +1600,8 @@ remove_inheriters(S,RS,InheriterList) ->
[_OneOnly] ->
ReducedInhList;
_Other ->
- EtsList = ets:tab2list(S),
CleanList =
- [X || X <- EtsList, element(1,X) == inherits],
+ ets:match(S, {inherits,'_','_'}),
% CodeOptList =
% [X || X <- EtsList, element(1,X) == codeopt],
NoInheriters =remove_inheriters2(S,ReducedInhList,CleanList),
@@ -1648,9 +1647,8 @@ remove_inh([X],[Y],List,EtsList) ->
%%% from others in the list
%%%----------------------------------------------
remove_inherited(S,InheriterList) ->
- EtsList = ets:tab2list(S),
CleanList =
- [X || X <- EtsList, element(1,X) == inherits],
+ ets:match(S, {inherits, '_', '_'}),
remove_inherited(S,InheriterList,CleanList).
@@ -1694,11 +1692,8 @@ remove_inhed([X],[Y],List,EtsList) ->
%% are inherited from scope in the list
%%%----------------------------------------------
get_inherited(S,Scope,OpScopeList) ->
- EtsList = ets:tab2list(S),
- [[element(3,X)] || X <- EtsList,
- element(1,X) == inherits,
- element(2,X) == Scope,
- member([element(3,X)],OpScopeList)].
+ EtsList1 = ets:match(S, {inherits, Scope, '$1'}),
+ [X || X <- EtsList1, member(X, OpScopeList)].
@@ -1771,9 +1766,7 @@ inherits2(_X,Y,Z,EtsList) ->
%% false otherwise
%%
is_inherited_by(Interface1,Interface2,PragmaTab) ->
- FullList = ets:tab2list(PragmaTab),
- InheritsList =
- [X || X <- FullList, element(1,X) == inherits],
+ InheritsList = ets:match(PragmaTab, {inherits, '_', '_'}),
inherits(Interface2,Interface1,InheritsList).
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index 6d6c7fa625..6561ccd2a7 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1 +1 @@
-IC_VSN = 4.2.26
+IC_VSN = 4.2.27
diff --git a/lib/inets/Makefile b/lib/inets/Makefile
index ec05efa461..f4c2746b0a 100644
--- a/lib/inets/Makefile
+++ b/lib/inets/Makefile
@@ -36,6 +36,8 @@ SPECIAL_TARGETS =
# ----------------------------------------------------
include $(ERL_TOP)/make/otp_subdir.mk
+.PHONY: info gclean
+
info:
@echo "OS: $(OS)"
@echo "DOCB: $(DOCB)"
@@ -44,3 +46,5 @@ info:
@echo "APP_VSN: $(APP_VSN)"
@echo ""
+gclean:
+ git clean -fXd
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 959386e471..599a939913 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index f6b6827e93..d1671ac9bd 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -144,7 +144,7 @@ filename() = string()
<v>Result = {status_line(), headers(), Body} |
{status_code(), Body} | request_id() </v>
<v>Body = string() | binary()</v>
- <v>Profile = profile()</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
<v>Reason = term() </v>
</type>
<desc>
@@ -194,16 +194,16 @@ filename() = string()
<v>Result = {status_line(), headers(), Body} |
{status_code(), Body} | request_id() </v>
<v>Body = string() | binary()</v>
- <v>Profile = profile() </v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
<v>Reason = {connect_failed, term()} |
{send_failed, term()} | term() </v>
</type>
<desc>
<p>Sends a HTTP-request. The function can be both synchronous
- and asynchronous. In the later case the function will return
- <c>{ok, RequestId}</c> and later on the information will be delivered
- to the <c>receiver</c> depending on that value. </p>
+ 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>Http option (<c>http_option()</c>) details: </p>
<taglist>
@@ -211,7 +211,7 @@ filename() = string()
<item>
<p>Timeout time for the request. </p>
<p>The clock starts ticking as soon as the request has been
- sent. </p>
+ sent. </p>
<p>Time is in milliseconds. </p>
<p>Defaults to <c>infinity</c>. </p>
</item>
@@ -219,7 +219,7 @@ filename() = string()
<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>
+ when the client is <em>connecting</em> to the server. </p>
<p>Time is in milliseconds. </p>
<p>Defaults to the value of the <c>timeout</c> option. </p>
</item>
@@ -227,60 +227,61 @@ filename() = string()
<tag><c><![CDATA[ssl]]></c></tag>
<item>
<p>This is the default ssl config option, currently defaults to
- <c>essl</c>, see below. </p>
+ <c>essl</c>, see below. </p>
<p>Defaults to <c>[]</c>. </p>
</item>
<tag><c><![CDATA[ossl]]></c></tag>
<item>
<p>If using the OpenSSL based (old) implementation of SSL,
- these SSL-specific options are used. </p>
+ these SSL-specific options are used. </p>
<p>Defaults to <c>[]</c>. </p>
</item>
<tag><c><![CDATA[essl]]></c></tag>
<item>
<p>If using the Erlang based (new) implementation of SSL,
- these SSL-specific options are used. </p>
+ these SSL-specific options are used. </p>
<p>Defaults to <c>[]</c>. </p>
</item>
<tag><c><![CDATA[autoredirect]]></c></tag>
<item>
- <p>Should the client automatically 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>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>
</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>
+ password will be added to the request. </p>
</item>
<tag><c><![CDATA[version]]></c></tag>
<item>
<p>Can be used to make the client act as an <c>HTTP/1.0</c> or
- <c>HTTP/0.9</c> client. By default this is an <c>HTTP/1.1</c>
- client. When using <c>HTTP/1.0</c> persistent connections will
- not be used. </p>
- <p>Defaults to the string <c>"HTTP/1.1"</c>. </p>
+ <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>
</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>If set to <c>true</c> workarounds for known server deviations
+ from the HTTP-standard are enabled. </p>
<p>Defaults to <c>false</c>. </p>
</item>
<tag><c><![CDATA[url_encode]]></c></tag>
<item>
- <p>Will apply Percent-encoding, also known as URL encoding on the URL.</p>
+ <p>Will apply Percent-encoding, also known as URL encoding on the
+ URL.</p>
<p>Defaults to <c>false</c>. </p>
</item>
</taglist>
@@ -296,77 +297,77 @@ filename() = string()
<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,
- stream_start, Headers}, {http, {RequestId, stream,
- BinBodyPart}, {http, {RequestId, stream_end, Headers}</c>. When
- streaming to to the calling processes using the option
- <c>{self, once}</c> the first message will have an additional
- element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}</c>,
- this is the process id that should 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>
+ 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,
+ stream_start, Headers}, {http, {RequestId, stream,
+ BinBodyPart}, {http, {RequestId, stream_end, Headers}</c>. When
+ streaming to to the calling processes using the option
+ <c>{self, once}</c> the first message will have an additional
+ element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}</c>,
+ this is the process id that should 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
- 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>
+ 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>
</item>
<tag><c><![CDATA[body_format]]></c></tag>
<item>
<p>Defines if the body shall be delivered as a string or as a
- binary. This option is only valid for the synchronous
- request. </p>
+ binary. This option is only valid for the synchronous
+ request. </p>
<p>Defaults to <c>string</c>. </p>
</item>
<tag><c><![CDATA[full_result]]></c></tag>
<item>
<p>Should a "full result" be returned to the caller (that is,
- the body, the headers and the entire status-line) or not
- (the body and the status code). </p>
+ the body, the headers and the entire status-line) or not
+ (the body and the status code). </p>
<p>Defaults to <c>true</c>. </p>
</item>
<tag><c><![CDATA[header_as_is]]></c></tag>
<item>
<p>Shall the headers provided by the user be made
- lower case or be regarded as case sensitive. </p>
+ lower case or be regarded as case sensitive. </p>
<p>Note that the http standard requires them to be
- case insenstive. This feature should only be used if there is
- no other way to communicate with the server or for testing
- purpose. Also note that when this option is used no headers
- will be automatically added, all necessary headers have to be
- provided by the user. </p>
- <p>Defaults to <c>false</c>. </p>
+ case insenstive. This feature should only be used if there is
+ no other way to communicate with the server or for testing
+ purpose. Also note that when this option is used no headers
+ will be automatically added, all necessary headers have to be
+ provided by the user. </p>
+ <p>Defaults to <c>false</c>. </p>
</item>
<tag><c><![CDATA[socket_opts]]></c></tag>
<item>
<p>Socket options to be used for this and subsequent
- request(s). </p>
- <p>Overrides any value set by the
- <seealso marker="#set_options">set_options</seealso>
- function. </p>
+ 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>
+ 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>
+ (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>
+ <seealso marker="#set_options">set_options/1,2</seealso>
+ function are used when establishing a connection. </p>
</item>
<tag><c><![CDATA[receiver]]></c></tag>
<item>
<p>Defines how the client will deliver the result of an
- asynchroneous request (<c>sync</c> has the value
- <c>false</c>). </p>
+ asynchroneous request (<c>sync</c> has the value
+ <c>false</c>). </p>
<taglist>
<tag><c><![CDATA[pid()]]></c></tag>
@@ -380,7 +381,7 @@ filename() = string()
<tag><c><![CDATA[function/1]]></c></tag>
<item>
<p>Information will be delivered to the receiver via calls
- to the provided fun: </p>
+ to the provided fun: </p>
<pre>
Receiver(ReplyInfo)
</pre>
@@ -389,7 +390,7 @@ Receiver(ReplyInfo)
<tag><c><![CDATA[{Module, Funcion, Args}]]></c></tag>
<item>
<p>Information will be delivered to the receiver via calls
- to the callback function: </p>
+ to the callback function: </p>
<pre>
apply(Module, Function, [ReplyInfo | Args])
</pre>
@@ -410,7 +411,7 @@ apply(Module, Function, [ReplyInfo | Args])
</pre>
<p>Defaults to the <c>pid()</c> of the process calling the request
- function (<c>self()</c>). </p>
+ function (<c>self()</c>). </p>
</item>
</taglist>
@@ -425,7 +426,7 @@ apply(Module, Function, [ReplyInfo | Args])
<type>
<v>RequestId = request_id() - A unique identifier as returned
by request/4</v>
- <v>Profile = profile()</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
</type>
<desc>
<p>Cancels an asynchronous HTTP-request. </p>
@@ -514,11 +515,10 @@ apply(Module, Function, [ReplyInfo | Args])
This option is used to switch on (or off)
different levels of erlang trace on the client.
It is a debug feature.</d>
- <v>Profile = profile()</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
</type>
<desc>
- <p>Sets options to be used for subsequent
- requests.</p>
+ <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
@@ -548,7 +548,7 @@ apply(Module, Function, [ReplyInfo | Args])
</type>
<desc>
<p>Triggers the next message to be streamed, e.i.
- same behavior as active once for sockets.</p>
+ same behavior as active once for sockets. </p>
<marker id="verify_cookies"></marker>
<marker id="store_cookies"></marker>
@@ -562,14 +562,14 @@ apply(Module, Function, [ReplyInfo | Args])
<type>
<v>SetCookieHeaders = headers() - where field = "set-cookie"</v>
<v>Url = url()</v>
- <v>Profile = profile()</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>
+ 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>
@@ -582,13 +582,12 @@ apply(Module, Function, [ReplyInfo | Args])
making a request to Url using the profile <c>Profile</c>.</fsummary>
<type>
<v>Url = url()</v>
- <v>Profile = profile()</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
</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>
+ 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>
<marker id="reset_cookies"></marker>
</desc>
@@ -600,12 +599,12 @@ apply(Module, Function, [ReplyInfo | Args])
<name>reset_cookies(Profile) -> void()</name>
<fsummary>Reset the cookie database.</fsummary>
<type>
- <v>Profile = profile()</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
</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>Resets (clears) the cookie database for the specified
+ <c>Profile</c>. If no profile is specified the default profile
+ will be used. </p>
</desc>
</func>
@@ -615,17 +614,16 @@ apply(Module, Function, [ReplyInfo | Args])
<name>which_cookies(Profile) -> cookies()</name>
<fsummary>Dumps out the entire cookie database.</fsummary>
<type>
- <v>Profile = profile()</v>
- <v>cookies() = [cooie_stores()]</v>
- <v>cookie_stores() = {cookies, icookies()} | {session_cookies, icookies()}</v>
- <v>icookies() = [icookie()]</v>
+ <v>Profile = profile() | pid() (when started <c>stand_alone</c>)</v>
+ <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>
+ It is intended for debugging/testing purposes.
+ If no profile is specified the default profile will be used. </p>
</desc>
</func>
</funcs>
diff --git a/lib/inets/doc/src/inets.xml b/lib/inets/doc/src/inets.xml
index a2bf42320f..079f60779d 100644
--- a/lib/inets/doc/src/inets.xml
+++ b/lib/inets/doc/src/inets.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2010</year>
+ <year>2007</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 0926df8581..34f26bf45b 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,6 +32,63 @@
<file>notes.xml</file>
</header>
+ <section><title>Inets 5.7</title>
+
+ <section><title>Improvements and New Features</title>
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc|httpd] Added support for IPv6 with ssl. </p>
+ <p>Own Id: OTP-5566</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] Remove unnecessary usage of iolist_to_binary when
+ processing body (for PUT and POST). </p>
+ <p>Filipe David Manana</p>
+ <p>Own Id: OTP-9317</p>
+ </item>
+
+ <item>
+ <p>[ftp] FTP client doesn't work with IPv6 host.</p>
+ <p>Attila Rajmund Nohl</p>
+ <p>Own Id: OTP-9342 Aux Id: seq11853</p>
+ </item>
+
+ <item>
+ <p>[httpd] Peer/sockname resolv doesn't work with IPv6 addrs
+ in HTTP. </p>
+ <p>Attila Rajmund Nohl.</p>
+ <p>Own Id: OTP-9343</p>
+ </item>
+
+ <item>
+ <p>[httpc] Clients started stand-alone not properly handled.
+ Also it was not documented how to use them, that is that
+ once started, they are represented by a <c>pid()</c> and not by
+ their <c>profile()</c>. </p>
+ <p>Own Id: OTP-9365</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.7 -->
+
+
<section><title>Inets 5.6</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index fe6cb0c191..ac72963347 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -1038,10 +1038,12 @@ handle_call({_, {open, ip_comm, Opts}}, From, State) ->
Port = key_search(port, Opts, ?FTP_PORT),
Timeout = key_search(timeout, Opts, ?CONNECTION_TIMEOUT),
Progress = key_search(progress, Opts, ignore),
+ IpFamily = key_search(ipfamily, Opts, inet),
State2 = State#state{client = From,
mode = Mode,
- progress = progress(Progress)},
+ progress = progress(Progress),
+ ipfamily = IpFamily},
?fcrd("handle_call(open) -> setup ctrl connection with",
[{host, Host}, {port, Port}, {timeout, Timeout}]),
diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl
index b70b16f57f..fe8e93af1f 100644
--- a/lib/inets/src/http_client/httpc.erl
+++ b/lib/inets/src/http_client/httpc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -64,17 +64,16 @@ default_profile() ->
profile_name(?DEFAULT_PROFILE) ->
httpc_manager;
+profile_name(Profile) when is_pid(Profile) ->
+ Profile;
profile_name(Profile) ->
- profile_name("httpc_manager_", Profile).
+ Prefix = lists:flatten(io_lib:format("~w_", [?MODULE])),
+ profile_name(Prefix, Profile).
profile_name(Prefix, Profile) when is_atom(Profile) ->
list_to_atom(Prefix ++ atom_to_list(Profile));
-profile_name(Prefix, Profile) when is_pid(Profile) ->
- ProfileStr0 =
- string:strip(string:strip(erlang:pid_to_list(Profile), left, $<), right, $>),
- F = fun($.) -> $_; (X) -> X end,
- ProfileStr = [F(C) || C <- ProfileStr0],
- list_to_atom(Prefix ++ "pid_" ++ ProfileStr).
+profile_name(_Prefix, Profile) when is_pid(Profile) ->
+ Profile.
%%--------------------------------------------------------------------------
@@ -115,9 +114,11 @@ request(Url, Profile) ->
%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
%% {ciphers, string()}
%% Options - [Option]
-%% Option - {sync, Boolean} | {body_format, BodyFormat} |
-%% {full_result, Boolean} | {stream, To} |
-%% {headers_as_is, Boolean}
+%% Option - {sync, Boolean} |
+%% {body_format, BodyFormat} |
+%% {full_result, Boolean} |
+%% {stream, To} |
+%% {headers_as_is, Boolean}
%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
%% HTTPVersion = string()
%% StatusCode = integer()
@@ -518,17 +519,15 @@ mk_chunkify_fun(ProcessBody) ->
eof ->
{ok, <<"0\r\n\r\n">>, eof_body};
{ok, Data, NewAcc} ->
- {ok, mk_chunk_bin(Data), NewAcc}
+ Chunk = [
+ integer_to_list(iolist_size(Data), 16),
+ "\r\n",
+ Data,
+ "\r\n"],
+ {ok, Chunk, NewAcc}
end
end.
-mk_chunk_bin(Data) ->
- Bin = iolist_to_binary(Data),
- iolist_to_binary([hex_size(Bin), "\r\n", Bin, "\r\n"]).
-
-hex_size(Bin) ->
- hd(io_lib:format("~.16B", [size(Bin)])).
-
handle_answer(RequestId, false, _) ->
{ok, RequestId};
@@ -552,9 +551,7 @@ return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
{ok, Body};
return_answer(Options, {StatusLine, Headers, BinBody}) ->
-
Body = maybe_format_body(BinBody, Options),
-
case proplists:get_value(full_result, Options, true) of
true ->
{ok, {StatusLine, Headers, Body}};
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 1f0e012e7e..9ac9ee6f7b 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -515,7 +515,7 @@ handle_info({Proto, _Socket, Data},
{stop, normal, NewState}
end,
- ?hcri("data processed", []),
+ ?hcri("data processed", [{final_result, FinalResult}]),
FinalResult;
@@ -629,8 +629,9 @@ handle_info(timeout_queue, #state{timers = Timers} = State) ->
Timers#timers{queue_timer = undefined}}};
%% Setting up the connection to the server somehow failed.
-handle_info({init_error, _, ClientErrMsg},
+handle_info({init_error, Tag, ClientErrMsg},
State = #state{request = Request}) ->
+ ?hcrv("init error", [{tag, Tag}, {client_error, ClientErrMsg}]),
NewState = answer_request(Request, ClientErrMsg, State),
{stop, normal, NewState};
@@ -707,9 +708,9 @@ terminate(normal,
%% And, just in case, close our side (**really** overkill)
http_transport:close(SocketType, Socket);
-terminate(Reason, #state{session = #session{id = Id,
- socket = Socket,
- socket_type = SocketType},
+terminate(Reason, #state{session = #session{id = Id,
+ socket = Socket,
+ socket_type = SocketType},
request = undefined,
profile_name = ProfileName,
timers = Timers,
@@ -1403,7 +1404,7 @@ try_to_enable_pipeline_or_keep_alive(
answer_request(#request{id = RequestId, from = From} = Request, Msg,
#state{timers = Timers, profile_name = ProfileName} = State) ->
- ?hcrt("answer request", [{request, Request}]),
+ ?hcrt("answer request", [{request, Request}, {msg, Msg}]),
httpc_response:send(From, Msg),
RequestTimers = Timers#timers.request_timers,
TimerRef =
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 7f66b477eb..9015bf1ce2 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -52,7 +52,7 @@
cancel = [], % [{RequestId, HandlerPid, ClientPid}]
handler_db, % ets() - Entry: #handler_info{}
cookie_db, % cookie_db()
- session_db, % ets() - Entry: #tcp_session{}
+ session_db, % ets() - Entry: #session{}
profile_name, % atom()
options = #options{}
}).
@@ -178,7 +178,7 @@ request_done(RequestId, ProfileName) ->
%%--------------------------------------------------------------------
%% Function: insert_session(Session, ProfileName) -> _
-%% Session - #tcp_session{}
+%% Session - #session{}
%% ProfileName - atom()
%%
%% Description: Inserts session information into the httpc manager
@@ -669,7 +669,7 @@ select_session(Method, HostPort, Scheme, SessionType,
(SessionType =:= keep_alive) of
true ->
%% Look for handlers connecting to this host (HostPort)
- %% tcp_session with record name field (tcp_session) and
+ %% session with record name field (session) and
%% socket fields ignored. The fields id (part of: HostPort),
%% client_close, scheme and type specified.
%% The fields id (part of: HandlerPid) and queue_length
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 8cabfe3c71..9b8190ebed 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -33,8 +33,8 @@
peername/2, sockname/2,
resolve/0
]).
-
-export([negotiate/3]).
+-export([ipv4_name/1, ipv6_name/1]).
-include_lib("inets/src/inets_app/inets_internal.hrl").
-include("http_internal.hrl").
@@ -142,8 +142,8 @@ connect({ossl, SslConfig}, {Host, Port}, _, Timeout) ->
ERROR
end;
-connect({essl, SslConfig}, {Host, Port}, _, Timeout) ->
- Opts = [binary, {active, false}, {ssl_imp, new}] ++ SslConfig,
+connect({essl, SslConfig}, {Host, Port}, Opts0, Timeout) ->
+ Opts = [binary, {active, false}, {ssl_imp, new} | Opts0] ++ SslConfig,
?hlrt("connect using essl",
[{host, Host},
{port, Port},
@@ -176,8 +176,8 @@ connect({essl, SslConfig}, {Host, Port}, _, Timeout) ->
listen(SocketType, Port) ->
listen(SocketType, undefined, Port).
-listen(ip_comm = SocketType, Addr, Port) ->
- listen(SocketType, Addr, Port, undefined);
+listen(ip_comm = _SocketType, Addr, Port) ->
+ listen_ip_comm(Addr, Port, undefined);
%% Wrapper for backaward compatibillity
listen({ssl, SSLConfig}, Addr, Port) ->
@@ -187,35 +187,33 @@ listen({ssl, SSLConfig}, Addr, Port) ->
{ssl_config, SSLConfig}]),
listen({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Addr, Port);
-listen({ossl, SSLConfig} = Ssl, Addr, Port) ->
+listen({ossl, SSLConfig}, Addr, Port) ->
?hlrt("listen (ossl)",
[{addr, Addr},
{port, Port},
{ssl_config, SSLConfig}]),
- Opt = sock_opt(Ssl, Addr, SSLConfig),
- ?hlrt("listen options", [{opt, Opt}]),
- ssl:listen(Port, [{ssl_imp, old} | Opt]);
+ listen_ssl(Addr, Port, [{ssl_imp, old} | SSLConfig]);
-listen({essl, SSLConfig} = Ssl, Addr, Port) ->
+listen({essl, SSLConfig}, Addr, Port) ->
?hlrt("listen (essl)",
[{addr, Addr},
{port, Port},
{ssl_config, SSLConfig}]),
- Opt = sock_opt(Ssl, Addr, SSLConfig),
- ?hlrt("listen options", [{opt, Opt}]),
- Opt2 = [{ssl_imp, new}, {reuseaddr, true} | Opt],
- ssl:listen(Port, Opt2).
+ listen_ssl(Addr, Port, [{ssl_imp, new}, {reuseaddr, true} | SSLConfig]).
+
listen(ip_comm, Addr, Port, Fd) ->
- case (catch listen_ip_comm(Addr, Port, Fd)) of
+ listen_ip_comm(Addr, Port, Fd).
+
+listen_ip_comm(Addr, Port, Fd) ->
+ case (catch do_listen_ip_comm(Addr, Port, Fd)) of
{'EXIT', Reason} ->
{error, {exit, Reason}};
Else ->
Else
end.
-
-listen_ip_comm(Addr, Port, Fd) ->
+do_listen_ip_comm(Addr, Port, Fd) ->
{NewPort, Opts, IpFamily} = get_socket_info(Addr, Port, Fd),
case IpFamily of
inet6fb4 ->
@@ -248,6 +246,41 @@ listen_ip_comm(Addr, Port, Fd) ->
gen_tcp:listen(NewPort, Opts2)
end.
+
+listen_ssl(Addr, Port, Opts0) ->
+ IpFamily = ipfamily_default(Addr, Port),
+ BaseOpts = [{backlog, 128}, {reuseaddr, true} | Opts0],
+ Opts = sock_opts(Addr, BaseOpts),
+ case IpFamily of
+ inet6fb4 ->
+ Opts2 = [inet6 | Opts],
+ ?hlrt("try ipv6 listen", [{opts, Opts2}]),
+ case (catch ssl:listen(Port, Opts2)) of
+ {error, Reason} when ((Reason =:= nxdomain) orelse
+ (Reason =:= eafnosupport)) ->
+ Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen failed - try ipv4 instead",
+ [{reason, Reason}, {opts, Opts3}]),
+ ssl:listen(Port, Opts3);
+
+ {'EXIT', Reason} ->
+ Opts3 = [inet | Opts],
+ ?hlrt("ipv6 listen exit - try ipv4 instead",
+ [{reason, Reason}, {opts, Opts3}]),
+ ssl:listen(Port, Opts3);
+
+ Other ->
+ ?hlrt("ipv6 listen done", [{other, Other}]),
+ Other
+ end;
+
+ _ ->
+ Opts2 = [IpFamily | Opts],
+ ?hlrt("listen", [{opts, Opts2}]),
+ ssl:listen(Port, Opts2)
+ end.
+
+
ipfamily_default(Addr, Port) ->
httpd_conf:lookup(Addr, Port, ipfamily, inet6fb4).
@@ -257,9 +290,9 @@ get_socket_info(Addr, Port, Fd0) ->
%% The presence of a file descriptor takes precedence
case get_fd(Port, Fd0, IpFamilyDefault) of
{Fd, IpFamily} ->
- {0, sock_opt(ip_comm, Addr, [{fd, Fd} | BaseOpts]), IpFamily};
+ {0, sock_opts(Addr, [{fd, Fd} | BaseOpts]), IpFamily};
undefined ->
- {Port, sock_opt(ip_comm, Addr, BaseOpts), IpFamilyDefault}
+ {Port, sock_opts(Addr, BaseOpts), IpFamilyDefault}
end.
get_fd(Port, undefined = _Fd, IpFamilyDefault) ->
@@ -499,44 +532,28 @@ close({essl, _}, Socket) ->
%% connection, usning either gen_tcp or ssl.
%%-------------------------------------------------------------------------
peername(ip_comm, Socket) ->
- case inet:peername(Socket) of
- {ok,{{A, B, C, D}, Port}} ->
- PeerName = integer_to_list(A)++"."++integer_to_list(B)++"."++
- integer_to_list(C)++"."++integer_to_list(D),
- {Port, PeerName};
- {ok,{{A, B, C, D, E, F, G, H}, Port}} ->
- PeerName = http_util:integer_to_hexlist(A) ++ ":"++
- http_util:integer_to_hexlist(B) ++ ":" ++
- http_util:integer_to_hexlist(C) ++ ":" ++
- http_util:integer_to_hexlist(D) ++ ":" ++
- http_util:integer_to_hexlist(E) ++ ":" ++
- http_util:integer_to_hexlist(F) ++ ":" ++
- http_util:integer_to_hexlist(G) ++":"++
- http_util:integer_to_hexlist(H),
- {Port, PeerName};
- {error, _} ->
- {-1, "unknown"}
- end;
+ do_peername(inet:peername(Socket));
%% Wrapper for backaward compatibillity
peername({ssl, SSLConfig}, Socket) ->
peername({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket);
peername({ossl, _}, Socket) ->
- peername_ssl(Socket);
+ do_peername(ssl:peername(Socket));
peername({essl, _}, Socket) ->
- peername_ssl(Socket).
-
-peername_ssl(Socket) ->
- case ssl:peername(Socket) of
- {ok,{{A, B, C, D}, Port}} ->
- PeerName = integer_to_list(A)++"."++integer_to_list(B)++"."++
- integer_to_list(C)++"."++integer_to_list(D),
- {Port, PeerName};
- {error, _} ->
- {-1, "unknown"}
- end.
+ do_peername(ssl:peername(Socket)).
+
+do_peername({ok, {Addr, Port}})
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ PeerName = ipv4_name(Addr),
+ {Port, PeerName};
+do_peername({ok, {Addr, Port}})
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ PeerName = ipv6_name(Addr),
+ {Port, PeerName};
+do_peername({error, _}) ->
+ {-1, "unknown"}.
%%-------------------------------------------------------------------------
@@ -550,44 +567,28 @@ peername_ssl(Socket) ->
%% other end of connection, using either gen_tcp or ssl.
%%-------------------------------------------------------------------------
sockname(ip_comm, Socket) ->
- case inet:sockname(Socket) of
- {ok,{{A, B, C, D}, Port}} ->
- SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
- integer_to_list(C)++"."++integer_to_list(D),
- {Port, SockName};
- {ok,{{A, B, C, D, E, F, G, H}, Port}} ->
- SockName = http_util:integer_to_hexlist(A) ++ ":"++
- http_util:integer_to_hexlist(B) ++ ":" ++
- http_util:integer_to_hexlist(C) ++ ":" ++
- http_util:integer_to_hexlist(D) ++ ":" ++
- http_util:integer_to_hexlist(E) ++ ":" ++
- http_util:integer_to_hexlist(F) ++ ":" ++
- http_util:integer_to_hexlist(G) ++":"++
- http_util:integer_to_hexlist(H),
- {Port, SockName};
- {error, _} ->
- {-1, "unknown"}
- end;
+ do_sockname(inet:sockname(Socket));
%% Wrapper for backaward compatibillity
sockname({ssl, SSLConfig}, Socket) ->
sockname({?HTTP_DEFAULT_SSL_KIND, SSLConfig}, Socket);
sockname({ossl, _}, Socket) ->
- sockname_ssl(Socket);
+ do_sockname(ssl:sockname(Socket));
sockname({essl, _}, Socket) ->
- sockname_ssl(Socket).
-
-sockname_ssl(Socket) ->
- case ssl:sockname(Socket) of
- {ok,{{A, B, C, D}, Port}} ->
- SockName = integer_to_list(A)++"."++integer_to_list(B)++"."++
- integer_to_list(C)++"."++integer_to_list(D),
- {Port, SockName};
- {error, _} ->
- {-1, "unknown"}
- end.
+ do_sockname(ssl:sockname(Socket)).
+
+do_sockname({ok, {Addr, Port}})
+ when is_tuple(Addr) andalso (size(Addr) =:= 4) ->
+ SockName = ipv4_name(Addr),
+ {Port, SockName};
+do_sockname({ok, {Addr, Port}})
+ when is_tuple(Addr) andalso (size(Addr) =:= 8) ->
+ SockName = ipv6_name(Addr),
+ {Port, SockName};
+do_sockname({error, _}) ->
+ {-1, "unknown"}.
%%-------------------------------------------------------------------------
@@ -601,29 +602,49 @@ resolve() ->
Name.
+%%-------------------------------------------------------------------------
+%% ipv4_name(Ipv4Addr) -> string()
+%% ipv6_name(Ipv6Addr) -> string()
+%% Ipv4Addr = ip4_address()
+%% Ipv6Addr = ip6_address()
+%%
+%% Description: Returns the local hostname.
+%%-------------------------------------------------------------------------
+ipv4_name({A, B, C, D}) ->
+ integer_to_list(A) ++ "." ++
+ integer_to_list(B) ++ "." ++
+ integer_to_list(C) ++ "." ++
+ integer_to_list(D).
+
+ipv6_name({A, B, C, D, E, F, G, H}) ->
+ http_util:integer_to_hexlist(A) ++ ":"++
+ http_util:integer_to_hexlist(B) ++ ":" ++
+ http_util:integer_to_hexlist(C) ++ ":" ++
+ http_util:integer_to_hexlist(D) ++ ":" ++
+ http_util:integer_to_hexlist(E) ++ ":" ++
+ http_util:integer_to_hexlist(F) ++ ":" ++
+ http_util:integer_to_hexlist(G) ++ ":" ++
+ http_util:integer_to_hexlist(H).
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
+%% -- sock_opts --
%% Address any comes from directive: BindAddress "*"
-sock_opt(ip_comm, any = Addr, Opts) ->
- sock_opt2([{ip, Addr} | Opts]);
-sock_opt(ip_comm, undefined, Opts) ->
- sock_opt2(Opts);
-sock_opt(_, any = _Addr, Opts) ->
- sock_opt2(Opts);
-sock_opt(_, undefined = _Addr, Opts) ->
- sock_opt2(Opts);
-sock_opt(_, {_,_,_,_} = Addr, Opts) ->
- sock_opt2([{ip, Addr} | Opts]);
-sock_opt(ip_comm, Addr, Opts) ->
- sock_opt2([{ip, Addr} | Opts]);
-sock_opt(_, Addr, Opts) ->
- sock_opt2([{ip, Addr} | Opts]).
-
-sock_opt2(Opts) ->
+sock_opts(undefined, Opts) ->
+ sock_opts(Opts);
+sock_opts(any = Addr, Opts) ->
+ sock_opts([{ip, Addr} | Opts]);
+sock_opts(Addr, Opts) ->
+ sock_opts([{ip, Addr} | Opts]).
+
+sock_opts(Opts) ->
[{packet, 0}, {active, false} | Opts].
+
+%% -- negotiate --
negotiate(ip_comm,_,_) ->
?hlrt("negotiate(ip_comm)", []),
ok;
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index 5e6b69ac5e..5511ed388d 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index d028a19bf0..264dc9f006 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index c1aff65d5e..c051422529 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 47f3fbba58..8b0fcb185d 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -18,6 +18,15 @@
{"%VSN%",
[
+ {"5.6",
+ [
+ {load_module, httpc, soft_purge, soft_purge, [httpc_manager]},
+ {load_module, http_transport, soft_purge, soft_purge, [http_transport]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]},
+ {update, ftp, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"5.5.2",
[
{restart_application, inets}
@@ -40,6 +49,15 @@
}
],
[
+ {"5.6",
+ [
+ {load_module, httpc, soft_purge, soft_purge, [httpc_manager]},
+ {load_module, http_transport, soft_purge, soft_purge, [http_transport]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]},
+ {update, ftp, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"5.5.2",
[
{restart_application, inets}
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index d0d07a8358..3ebd02229e 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -1129,10 +1129,16 @@ ticket_6035(Config) ->
LogFile = filename:join([PrivDir,"ticket_6035.log"]),
try
begin
+ p("ticket_6035 -> select ftpd host"),
Host = dirty_select_ftpd_host(Config),
+ p("ticket_6035 -> ftpd host selected (~p) => now spawn ftp owner", [Host]),
Pid = spawn(?MODULE, open_wait_6035, [Host, self()]),
+ p("ticket_6035 -> waiter spawned: ~p => now open error logfile (~p)",
+ [Pid, LogFile]),
error_logger:logfile({open, LogFile}),
- ok = kill_ftp_proc_6035(Pid,LogFile),
+ p("ticket_6035 -> error logfile open => now kill waiter process"),
+ true = kill_ftp_proc_6035(Pid, LogFile),
+ p("ticket_6035 -> waiter process killed => now close error logfile"),
error_logger:logfile(close),
p("ticket_6035 -> done", []),
ok
@@ -1146,7 +1152,7 @@ kill_ftp_proc_6035(Pid, LogFile) ->
p("kill_ftp_proc_6035 -> entry"),
receive
open ->
- p("kill_ftp_proc_6035 -> received open: send shutdown"),
+ p("kill_ftp_proc_6035 -> received open => now issue shutdown"),
exit(Pid, shutdown),
kill_ftp_proc_6035(Pid, LogFile);
{open_failed, Reason} ->
@@ -1159,11 +1165,11 @@ kill_ftp_proc_6035(Pid, LogFile) ->
is_error_report_6035(LogFile)
end.
-open_wait_6035(FtpServer, From) ->
- p("open_wait_6035 -> try connect to ~s", [FtpServer]),
+open_wait_6035({Tag, FtpServer}, From) ->
+ p("open_wait_6035 -> try connect to [~p] ~s for ~p", [Tag, FtpServer, From]),
case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of
{ok, Pid} ->
- p("open_wait_6035 -> connected, now login"),
+ p("open_wait_6035 -> connected (~p), now login", [Pid]),
LoginResult = ftp:user(Pid,"anonymous","kldjf"),
p("open_wait_6035 -> login result: ~p", [LoginResult]),
From ! open,
@@ -1191,22 +1197,27 @@ is_error_report_6035(LogFile) ->
Res =
case file:read_file(LogFile) of
{ok, Bin} ->
- p("is_error_report_6035 -> logfile read"),
- read_log_6035(binary_to_list(Bin));
+ Txt = binary_to_list(Bin),
+ p("is_error_report_6035 -> logfile read: ~n~p", [Txt]),
+ read_log_6035(Txt);
_ ->
- ok
+ false
end,
p("is_error_report_6035 -> logfile read result: "
"~n ~p", [Res]),
- file:delete(LogFile),
+ %% file:delete(LogFile),
Res.
read_log_6035("=ERROR REPORT===="++_Rest) ->
- error_report;
-read_log_6035([_H|T]) ->
+ p("read_log_6035 -> ERROR REPORT detected"),
+ true;
+read_log_6035([H|T]) ->
+ p("read_log_6035 -> OTHER: "
+ "~p", [H]),
read_log_6035(T);
read_log_6035([]) ->
- ok.
+ p("read_log_6035 -> done"),
+ false.
%%--------------------------------------------------------------------
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 1998bd3950..6edd5371af 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -64,16 +64,6 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[
- proxy_options,
- proxy_head,
- proxy_get,
- proxy_trace,
- proxy_post,
- proxy_put,
- proxy_delete,
- proxy_auth,
- proxy_headers,
- proxy_emulate_lower_versions,
http_options,
http_head,
http_get,
@@ -88,15 +78,6 @@ all() ->
http_headers,
http_headers_dummy,
http_bad_response,
- ssl_head,
- ossl_head,
- essl_head,
- ssl_get,
- ossl_get,
- essl_get,
- ssl_trace,
- ossl_trace,
- essl_trace,
http_redirect,
http_redirect_loop,
http_internal_server_error,
@@ -106,21 +87,44 @@ all() ->
http_emulate_lower_versions,
http_relaxed,
page_does_not_exist,
- proxy_page_does_not_exist,
- proxy_https_not_supported,
- http_stream,
- http_stream_once,
- proxy_stream,
parse_url,
options,
- ipv6,
headers_as_is,
+ {group, proxy},
+ {group, ssl},
+ {group, stream},
+ {group, ipv6},
{group, tickets},
initial_server_connect
].
groups() ->
- [{tickets, [], [hexed_query_otp_6191,
+ [
+ {proxy, [], [proxy_options,
+ proxy_head,
+ proxy_get,
+ proxy_trace,
+ proxy_post,
+ proxy_put,
+ proxy_delete,
+ proxy_auth,
+ proxy_headers,
+ proxy_emulate_lower_versions,
+ proxy_page_does_not_exist,
+ proxy_https_not_supported]},
+ {ssl, [], [ssl_head,
+ ossl_head,
+ essl_head,
+ ssl_get,
+ ossl_get,
+ essl_get,
+ ssl_trace,
+ ossl_trace,
+ essl_trace]},
+ {stream, [], [http_stream,
+ http_stream_once,
+ proxy_stream]},
+ {tickets, [], [hexed_query_otp_6191,
empty_body_otp_6243,
empty_response_header_otp_6830,
transfer_encoding_otp_6807,
@@ -139,7 +143,10 @@ groups() ->
{otp_8154, [], [otp_8154_1]},
{otp_8106, [], [otp_8106_pid,
otp_8106_fun,
- otp_8106_mfa]}].
+ otp_8106_mfa]},
+ {ipv6, [], [ipv6_ipcomm, ipv6_essl]}
+ ].
+
init_per_group(_GroupName, Config) ->
@@ -213,36 +220,38 @@ 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(otp_8154_1 = Case, Config) ->
init_per_testcase(Case, 5, Config);
-init_per_testcase(initial_server_connect, Config) ->
+init_per_testcase(initial_server_connect = Case, Config) ->
%% Try to check if crypto actually exist or not,
%% this test case does not work unless it does
- case (catch crypto:start()) of
- ok ->
- application:start(public_key),
- application:start(ssl),
+ try
+ begin
+ ensure_started(crypto),
+ ensure_started(public_key),
+ ensure_started(ssl),
inets:start(),
- Config;
- _ ->
- {skip,"Could not start crypto"}
+ Config
+ end
+ catch
+ throw:{error, {failed_starting, App, ActualError}} ->
+ tsp("init_per_testcase(~w) -> failed starting ~w: "
+ "~n ~p", [Case, App, ActualError]),
+ SkipString =
+ "Could not start " ++ atom_to_list(App),
+ {skip, SkipString};
+ _:X ->
+ SkipString =
+ lists:flatten(
+ io_lib:format("Failed starting apps: ~p", [X])),
+ {skip, SkipString}
end;
init_per_testcase(Case, Config) ->
init_per_testcase(Case, 2, Config).
-init_per_testcase_ssl(Tag, PrivDir, SslConfFile, Config) ->
- tsp("init_per_testcase_ssl -> stop ssl"),
- application:stop(ssl),
- Config2 = lists:keydelete(local_ssl_server, 1, Config),
- %% Will start inets
- tsp("init_per_testcase_ssl -> try start http server (including inets)"),
- Server = inets_test_lib:start_http_server(
- filename:join(PrivDir, SslConfFile), Tag),
- tsp("init_per_testcase -> Server: ~p", [Server]),
- [{local_ssl_server, Server} | Config2].
-
init_per_testcase(Case, Timeout, Config) ->
io:format(user, "~n~n*** INIT ~w:~w[~w] ***~n~n",
[?MODULE, Case, Timeout]),
@@ -261,13 +270,16 @@ init_per_testcase(Case, Timeout, Config) ->
NewConfig =
case atom_to_list(Case) of
[$s, $s, $l | _] ->
- init_per_testcase_ssl(ssl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]);
+ init_per_testcase_ssl(ssl, PrivDir, SslConfFile,
+ [{watchdog, Dog} | TmpConfig]);
[$o, $s, $s, $l | _] ->
- init_per_testcase_ssl(ossl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]);
+ init_per_testcase_ssl(ossl, PrivDir, SslConfFile,
+ [{watchdog, Dog} | TmpConfig]);
[$e, $s, $s, $l | _] ->
- init_per_testcase_ssl(essl, PrivDir, SslConfFile, [{watchdog, Dog} | TmpConfig]);
+ init_per_testcase_ssl(essl, PrivDir, SslConfFile,
+ [{watchdog, Dog} | TmpConfig]);
"proxy_" ++ Rest ->
io:format("init_per_testcase -> Rest: ~p~n", [Rest]),
@@ -275,16 +287,23 @@ init_per_testcase(Case, Timeout, Config) ->
"https_not_supported" ->
tsp("init_per_testcase -> [proxy case] start inets"),
inets:start(),
- tsp("init_per_testcase -> [proxy case] start ssl"),
- application:start(crypto),
- application:start(public_key),
- case (catch application:start(ssl)) of
+ tsp("init_per_testcase -> "
+ "[proxy case] start crypto, public_key and ssl"),
+ try ensure_started([crypto, public_key, ssl]) of
ok ->
- [{watchdog, Dog} | TmpConfig];
- _ ->
- [{skip, "SSL does not seem to be supported"}
- | TmpConfig]
+ [{watchdog, Dog} | TmpConfig]
+ catch
+ throw:{error, {failed_starting, App, _}} ->
+ SkipString =
+ "Could not start " ++ atom_to_list(App),
+ {skip, SkipString};
+ _:X ->
+ SkipString =
+ lists:flatten(
+ io_lib:format("Failed starting apps: ~p", [X])),
+ {skip, SkipString}
end;
+
_ ->
%% We use erlang.org for the proxy tests
%% and after the switch to erlang-web, many
@@ -321,6 +340,33 @@ init_per_testcase(Case, Timeout, Config) ->
[{skip, "proxy not responding"} | TmpConfig]
end
end;
+
+ "ipv6_" ++ _Rest ->
+ %% Ensure needed apps (crypto, public_key and ssl) started
+ try ensure_started([crypto, public_key, ssl]) of
+ ok ->
+ Profile = ipv6,
+ %% A stand-alone profile is represented by a pid()
+ {ok, ProfilePid} =
+ inets:start(httpc,
+ [{profile, Profile},
+ {data_dir, PrivDir}], stand_alone),
+ httpc:set_options([{ipfamily, inet6}], ProfilePid),
+ tsp("httpc profile pid: ~p", [ProfilePid]),
+ [{watchdog, Dog}, {profile, ProfilePid}| TmpConfig]
+ catch
+ throw:{error, {failed_starting, App, ActualError}} ->
+ tsp("init_per_testcase(~w) -> failed starting ~w: "
+ "~n ~p", [Case, App, ActualError]),
+ SkipString =
+ "Could not start " ++ atom_to_list(App),
+ {skip, SkipString};
+ _:X ->
+ SkipString =
+ lists:flatten(
+ io_lib:format("Failed starting apps: ~p", [X])),
+ {skip, SkipString}
+ end;
_ ->
TmpConfig2 = lists:keydelete(local_server, 1, TmpConfig),
Server =
@@ -330,9 +376,7 @@ init_per_testcase(Case, Timeout, Config) ->
[{watchdog, Dog}, {local_server, Server} | TmpConfig2]
end,
- %% httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
- %% ["localhost", ?IPV6_LOCAL_HOST]}}]),
-
+ %% This will fail for the ipv6_ - cases (but that is ok)
httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
["localhost", ?IPV6_LOCAL_HOST]}},
{ipfamily, inet6fb4}]),
@@ -341,6 +385,19 @@ init_per_testcase(Case, Timeout, Config) ->
NewConfig.
+init_per_testcase_ssl(Tag, PrivDir, SslConfFile, Config) ->
+ tsp("init_per_testcase_ssl(~w) -> stop ssl", [Tag]),
+ application:stop(ssl),
+ Config2 = lists:keydelete(local_ssl_server, 1, Config),
+ %% Will start inets
+ tsp("init_per_testcase_ssl(~w) -> try start http server (including inets)",
+ [Tag]),
+ Server = inets_test_lib:start_http_server(
+ filename:join(PrivDir, SslConfFile), Tag),
+ tsp("init_per_testcase(~w) -> Server: ~p", [Tag, Server]),
+ [{local_ssl_server, Server} | Config2].
+
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
%% Case - atom()
@@ -349,13 +406,36 @@ init_per_testcase(Case, Timeout, Config) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
-end_per_testcase(http_save_to_file, Config) ->
- PrivDir = ?config(priv_dir, Config),
+end_per_testcase(http_save_to_file = Case, Config) ->
+ io:format(user, "~n~n*** END ~w:~w ***~n~n",
+ [?MODULE, Case]),
+ PrivDir = ?config(priv_dir, Config),
FullPath = filename:join(PrivDir, "dummy.html"),
file:delete(FullPath),
finish(Config);
-end_per_testcase(_, Config) ->
+end_per_testcase(Case, Config) ->
+ io:format(user, "~n~n*** END ~w:~w ***~n~n",
+ [?MODULE, Case]),
+ case atom_to_list(Case) of
+ "ipv6_" ++ _Rest ->
+ tsp("end_per_testcase(~w) -> stop ssl", [Case]),
+ application:stop(ssl),
+ tsp("end_per_testcase(~w) -> stop public_key", [Case]),
+ application:stop(public_key),
+ tsp("end_per_testcase(~w) -> stop crypto", [Case]),
+ application:stop(crypto),
+ ProfilePid = ?config(profile, Config),
+ tsp("end_per_testcase(~w) -> stop httpc profile (~p)",
+ [Case, ProfilePid]),
+ unlink(ProfilePid),
+ inets:stop(stand_alone, ProfilePid),
+ tsp("end_per_testcase(~w) -> httpc profile (~p) stopped",
+ [Case, ProfilePid]),
+ ok;
+ _ ->
+ ok
+ end,
finish(Config).
finish(Config) ->
@@ -364,6 +444,7 @@ finish(Config) ->
undefined ->
ok;
_ ->
+ tsp("finish -> stop watchdog (~p)", [Dog]),
test_server:timetrap_cancel(Dog)
end.
@@ -565,7 +646,7 @@ http_relaxed(suite) ->
http_relaxed(Config) when is_list(Config) ->
ok = httpc:set_options([{ipv6, disabled}]), % also test the old option
%% ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++
"/missing_reason_phrase.html",
@@ -591,7 +672,7 @@ http_dummy_pipe(suite) ->
[];
http_dummy_pipe(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html",
@@ -905,7 +986,7 @@ http_headers_dummy(suite) ->
[];
http_headers_dummy(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html",
@@ -970,7 +1051,7 @@ http_bad_response(suite) ->
[];
http_bad_response(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html",
@@ -1089,9 +1170,9 @@ ssl_get(SslTag, Config) when is_list(Config) ->
httpc:request(get, {URL, []}, [{ssl, SSLConfig}], []),
inets_test_lib:check_body(Body);
{ok, _} ->
- {skip, "Failed to start local http-server"};
+ {skip, "local http-server not started"};
_ ->
- {skip, "Failed to start SSL"}
+ {skip, "SSL not started"}
end.
@@ -1149,9 +1230,9 @@ ssl_trace(SslTag, Config) when is_list(Config) ->
tsf({failed, Error})
end;
{ok, _} ->
- {skip, "Failed to start local http-server"};
+ {skip, "local http-server not started"};
_ ->
- {skip, "Failed to start SSL"}
+ {skip, "SSL not started"}
end.
@@ -1170,7 +1251,7 @@ http_redirect(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
tsp("http_redirect -> start dummy server inet"),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
tsp("http_redirect -> server port = ~p", [Port]),
URL300 = ?URL_START ++ integer_to_list(Port) ++ "/300.html",
@@ -1282,7 +1363,7 @@ http_redirect_loop(suite) ->
[];
http_redirect_loop(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html",
@@ -1299,7 +1380,7 @@ http_internal_server_error(suite) ->
[];
http_internal_server_error(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html",
@@ -1335,7 +1416,7 @@ http_userinfo(suite) ->
http_userinfo(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URLAuth = "http://alladin:sesame@localhost:"
++ integer_to_list(Port) ++ "/userinfo.html",
@@ -1361,7 +1442,7 @@ http_cookie(suite) ->
[];
http_cookie(Config) when is_list(Config) ->
ok = httpc:set_options([{cookies, enabled}, {ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URLStart = ?URL_START
++ integer_to_list(Port),
@@ -1735,7 +1816,7 @@ http_stream_once(Config) when is_list(Config) ->
p("http_stream_once -> set ipfamily to inet", []),
ok = httpc:set_options([{ipfamily, inet}]),
p("http_stream_once -> start dummy server", []),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
PortStr = integer_to_list(Port),
p("http_stream_once -> once", []),
@@ -1871,28 +1952,79 @@ parse_url(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
-ipv6() ->
- [{require,ipv6_hosts}].
-ipv6(doc) ->
- ["Test ipv6."];
-ipv6(suite) ->
- [];
-ipv6(Config) when is_list(Config) ->
- {ok, Hostname} = inet:gethostname(),
-
- case lists:member(list_to_atom(Hostname),
- ct:get_config(ipv6_hosts)) of
- true ->
- {DummyServerPid, Port} = dummy_server(self(), ipv6),
-
- URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++
+
+ipv6_ipcomm() ->
+ [{require, ipv6_hosts}].
+ipv6_ipcomm(doc) ->
+ ["Test ip_comm ipv6."];
+ipv6_ipcomm(suite) ->
+ [];
+ipv6_ipcomm(Config) when is_list(Config) ->
+ HTTPOptions = [],
+ SocketType = ip_comm,
+ Scheme = "http",
+ Extra = [],
+ ipv6(SocketType, Scheme, HTTPOptions, Extra, Config).
+
+
+%%-------------------------------------------------------------------------
+
+ipv6_essl() ->
+ [{require, ipv6_hosts}].
+ipv6_essl(doc) ->
+ ["Test essl ipv6."];
+ipv6_essl(suite) ->
+ [];
+ipv6_essl(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ CertFile = filename:join(DataDir, "ssl_client_cert.pem"),
+ SSLOptions = [{certfile, CertFile}, {keyfile, CertFile}],
+ SSLConfig = {essl, SSLOptions},
+ tsp("ssl_ipv6 -> make request using: "
+ "~n SSLOptions: ~p", [SSLOptions]),
+ HTTPOptions = [{ssl, SSLConfig}],
+ SocketType = essl,
+ Scheme = "https",
+ Extra = SSLOptions,
+ ipv6(SocketType, Scheme, HTTPOptions, Extra, Config).
+
+
+%%-------------------------------------------------------------------------
+
+ipv6(SocketType, Scheme, HTTPOptions, Extra, Config) ->
+ %% Check if we are a IPv6 host
+ tsp("ipv6 -> verify ipv6 support", []),
+ case inets_test_lib:has_ipv6_support(Config) of
+ {ok, Addr} ->
+ tsp("ipv6 -> ipv6 supported: ~p", [Addr]),
+ {DummyServerPid, Port} = dummy_server(SocketType, ipv6, Extra),
+ Profile = ?config(profile, Config),
+ URL =
+ Scheme ++
+ "://[" ++ http_transport:ipv6_name(Addr) ++ "]:" ++
integer_to_list(Port) ++ "/foobar.html",
- {ok, {{_,200,_}, [_ | _], [_|_]}} =
- httpc:request(get, {URL, []}, [], []),
-
- DummyServerPid ! stop,
+ tsp("ipv6 -> issue request with: "
+ "~n URL: ~p"
+ "~n HTTPOptions: ~p", [URL, HTTPOptions]),
+ case httpc:request(get, {URL, []}, HTTPOptions, [], Profile) of
+ {ok, {{_,200,_}, [_ | _], [_|_]}} ->
+ tsp("ipv6 -> expected result"),
+ DummyServerPid ! stop,
+ ok;
+ {ok, Unexpected} ->
+ tsp("ipv6 -> unexpected result: "
+ "~n ~p", [Unexpected]),
+ DummyServerPid ! stop,
+ tsf({unexpected_result, Unexpected});
+ {error, Reason} ->
+ tsp("ipv6 -> error: "
+ "~n Reason: ~p", [Reason]),
+ DummyServerPid ! stop,
+ tsf(Reason)
+ end,
ok;
- false ->
+ _ ->
+ tsp("ipv6 -> ipv6 not supported", []),
{skip, "Host does not support IPv6"}
end.
@@ -1945,7 +2077,7 @@ http_invalid_http(suite) ->
[];
http_invalid_http(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html",
@@ -2002,7 +2134,7 @@ transfer_encoding_otp_6807(suite) ->
[];
transfer_encoding_otp_6807(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++
"/capital_transfer_encoding.html",
@@ -2035,7 +2167,7 @@ empty_response_header_otp_6830(suite) ->
[];
empty_response_header_otp_6830(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html",
{ok, {{_,200,_}, [], [_ | _]}} = httpc:request(URL),
@@ -2052,7 +2184,7 @@ no_content_204_otp_6982(suite) ->
[];
no_content_204_otp_6982(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html",
{ok, {{_,204,_}, [], []}} = httpc:request(URL),
@@ -2070,7 +2202,7 @@ missing_CR_otp_7304(suite) ->
[];
missing_CR_otp_7304(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html",
{ok, {{_,200,_}, _, [_ | _]}} = httpc:request(URL),
@@ -2089,7 +2221,7 @@ otp_7883_1(suite) ->
otp_7883_1(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
{error, socket_closed_remotely} = httpc:request(URL),
@@ -2105,7 +2237,7 @@ otp_7883_2(suite) ->
otp_7883_2(Config) when is_list(Config) ->
ok = httpc:set_options([{ipfamily, inet}]),
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
Method = get,
@@ -2626,7 +2758,7 @@ otp_8371(suite) ->
[];
otp_8371(Config) when is_list(Config) ->
ok = httpc:set_options([{ipv6, disabled}]), % also test the old option
- {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++
"/ensure_host_header_with_port.html",
@@ -2864,75 +2996,179 @@ receive_streamed_body(RequestId, Body, Pid) ->
test_server:fail(Msg)
end.
+%% Perform a synchronous stop
+dummy_server_stop(Pid) ->
+ Pid ! {stop, self()},
+ receive
+ {stopped, Pid} ->
+ ok
+ end.
+
+dummy_server(IpV) ->
+ dummy_server(self(), ip_comm, IpV, []).
+dummy_server(SocketType, IpV, Extra) ->
+ dummy_server(self(), SocketType, IpV, Extra).
-dummy_server(Caller, IpV) ->
- Pid = spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]),
+dummy_server(Caller, SocketType, IpV, Extra) ->
+ Args = [Caller, SocketType, IpV, Extra],
+ Pid = spawn(httpc_SUITE, dummy_server_init, Args),
receive
{port, Port} ->
{Pid, Port}
end.
-dummy_server_init(Caller, IpV) ->
+dummy_server_init(Caller, ip_comm, IpV, _) ->
+ BaseOpts = [binary, {packet, 0}, {reuseaddr,true}, {active, false}],
{ok, ListenSocket} =
case IpV of
ipv4 ->
- gen_tcp:listen(0, [binary, inet, {packet, 0},
- {reuseaddr,true},
- {active, false}]);
+ tsp("ip_comm ipv4 listen", []),
+ gen_tcp:listen(0, [inet | BaseOpts]);
ipv6 ->
- gen_tcp:listen(0, [binary, inet6, {packet, 0},
- {reuseaddr,true},
- {active, false}])
+ tsp("ip_comm ipv6 listen", []),
+ gen_tcp:listen(0, [inet6 | BaseOpts])
end,
{ok, Port} = inet:port(ListenSocket),
- tsp("dummy_server_init -> Port: ~p", [Port]),
+ tsp("dummy_server_init(ip_comm) -> Port: ~p", [Port]),
Caller ! {port, Port},
- dummy_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
- [], ListenSocket).
+ dummy_ipcomm_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
+ [], ListenSocket);
+dummy_server_init(Caller, essl, IpV, SSLOptions) ->
+ BaseOpts = [{ssl_imp, new},
+ {backlog, 128}, binary, {reuseaddr,true}, {active, false} |
+ SSLOptions],
+ dummy_ssl_server_init(Caller, BaseOpts, IpV);
+dummy_server_init(Caller, ossl, IpV, SSLOptions) ->
+ BaseOpts = [{ssl_imp, old},
+ {backlog, 128}, binary, {active, false} | SSLOptions],
+ dummy_ssl_server_init(Caller, BaseOpts, IpV).
+
+dummy_ssl_server_init(Caller, BaseOpts, IpV) ->
+ {ok, ListenSocket} =
+ case IpV of
+ ipv4 ->
+ tsp("dummy_ssl_server_init -> ssl ipv4 listen", []),
+ ssl:listen(0, [inet | BaseOpts]);
+ ipv6 ->
+ tsp("dummy_ssl_server_init -> ssl ipv6 listen", []),
+ ssl:listen(0, [inet6 | BaseOpts])
+ end,
+ tsp("dummy_ssl_server_init -> ListenSocket: ~p", [ListenSocket]),
+ {ok, {_, Port}} = ssl:sockname(ListenSocket),
+ tsp("dummy_ssl_server_init -> Port: ~p", [Port]),
+ Caller ! {port, Port},
+ dummy_ssl_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
+ [], ListenSocket).
-dummy_server_loop(MFA, Handlers, ListenSocket) ->
+dummy_ipcomm_server_loop(MFA, Handlers, ListenSocket) ->
receive
stop ->
- lists:foreach(fun(Handler) -> Handler ! stop end, Handlers)
+ tsp("dummy_ipcomm_server_loop -> stop handlers", []),
+ lists:foreach(fun(Handler) -> Handler ! stop end, Handlers);
+ {stop, From} ->
+ tsp("dummy_ipcomm_server_loop -> "
+ "stop command from ~p for handlers (~p)", [From, Handlers]),
+ Stopper = fun(Handler) -> Handler ! stop end,
+ lists:foreach(Stopper, Handlers),
+ From ! {stopped, self()}
after 0 ->
+ tsp("dummy_ipcomm_server_loop -> await accept", []),
{ok, Socket} = gen_tcp:accept(ListenSocket),
+ tsp("dummy_ipcomm_server_loop -> accepted: ~p", [Socket]),
HandlerPid = dummy_request_handler(MFA, Socket),
+ tsp("dummy_icomm_server_loop -> handler created: ~p", [HandlerPid]),
gen_tcp:controlling_process(Socket, HandlerPid),
- HandlerPid ! controller,
- dummy_server_loop(MFA, [HandlerPid | Handlers],
+ tsp("dummy_ipcomm_server_loop -> "
+ "control transfered to handler", []),
+ HandlerPid ! ipcomm_controller,
+ tsp("dummy_ipcomm_server_loop -> "
+ "handler informed about control transfer", []),
+ dummy_ipcomm_server_loop(MFA, [HandlerPid | Handlers],
ListenSocket)
end.
+dummy_ssl_server_loop(MFA, Handlers, ListenSocket) ->
+ receive
+ stop ->
+ tsp("dummy_ssl_server_loop -> stop handlers", []),
+ lists:foreach(fun(Handler) -> Handler ! stop end, Handlers);
+ {stop, From} ->
+ tsp("dummy_ssl_server_loop -> "
+ "stop command from ~p for handlers (~p)", [From, Handlers]),
+ Stopper = fun(Handler) -> Handler ! stop end,
+ lists:foreach(Stopper, Handlers),
+ From ! {stopped, self()}
+ after 0 ->
+ tsp("dummy_ssl_server_loop -> await accept", []),
+ {ok, Socket} = ssl:transport_accept(ListenSocket),
+ tsp("dummy_ssl_server_loop -> accepted: ~p", [Socket]),
+ HandlerPid = dummy_request_handler(MFA, Socket),
+ tsp("dummy_ssl_server_loop -> handler created: ~p", [HandlerPid]),
+ ssl:controlling_process(Socket, HandlerPid),
+ tsp("dummy_ssl_server_loop -> control transfered to handler", []),
+ HandlerPid ! ssl_controller,
+ tsp("dummy_ssl_server_loop -> "
+ "handler informed about control transfer", []),
+ dummy_ssl_server_loop(MFA, [HandlerPid | Handlers],
+ ListenSocket)
+ end.
+
dummy_request_handler(MFA, Socket) ->
+ tsp("spawn request handler", []),
spawn(httpc_SUITE, dummy_request_handler_init, [MFA, Socket]).
dummy_request_handler_init(MFA, Socket) ->
- receive
- controller ->
- inet:setopts(Socket, [{active, true}])
- end,
- dummy_request_handler_loop(MFA, Socket).
+ SockType =
+ receive
+ ipcomm_controller ->
+ tsp("dummy_request_handler_init -> "
+ "received ip_comm controller - activate", []),
+ inet:setopts(Socket, [{active, true}]),
+ ip_comm;
+ ssl_controller ->
+ tsp("dummy_request_handler_init -> "
+ "received ssl controller - activate", []),
+ ssl:setopts(Socket, [{active, true}]),
+ ssl
+ end,
+ dummy_request_handler_loop(MFA, SockType, Socket).
-dummy_request_handler_loop({Module, Function, Args}, Socket) ->
+dummy_request_handler_loop({Module, Function, Args}, SockType, Socket) ->
tsp("dummy_request_handler_loop -> entry with"
"~n Module: ~p"
"~n Function: ~p"
"~n Args: ~p", [Module, Function, Args]),
receive
- {tcp, _, Data} ->
- tsp("dummy_request_handler_loop -> Data ~p", [Data]),
- case handle_request(Module, Function, [Data | Args], Socket) of
- stop ->
+ {Proto, _, Data} when (Proto =:= tcp) orelse (Proto =:= ssl) ->
+ tsp("dummy_request_handler_loop -> [~w] Data ~p", [Proto, Data]),
+ case handle_request(Module, Function, [Data | Args], Socket, Proto) of
+ stop when Proto =:= tcp ->
gen_tcp:close(Socket);
+ stop when Proto =:= ssl ->
+ ssl:close(Socket);
NewMFA ->
- dummy_request_handler_loop(NewMFA, Socket)
+ dummy_request_handler_loop(NewMFA, SockType, Socket)
end;
- stop ->
- gen_tcp:close(Socket)
+ stop when SockType =:= ip_comm ->
+ gen_tcp:close(Socket);
+ stop when SockType =:= ssl ->
+ ssl:close(Socket)
end.
-handle_request(Module, Function, Args, Socket) ->
+
+mk_close(tcp) -> fun(Sock) -> gen_tcp:close(Sock) end;
+mk_close(ssl) -> fun(Sock) -> ssl:close(Sock) end.
+
+mk_send(tcp) -> fun(Sock, Data) -> gen_tcp:send(Sock, Data) end;
+mk_send(ssl) -> fun(Sock, Data) -> ssl:send(Sock, Data) end.
+
+handle_request(Module, Function, Args, Socket, Proto) ->
+ Close = mk_close(Proto),
+ Send = mk_send(Proto),
+ handle_request(Module, Function, Args, Socket, Close, Send).
+
+handle_request(Module, Function, Args, Socket, Close, Send) ->
tsp("handle_request -> entry with"
"~n Module: ~p"
"~n Function: ~p"
@@ -2941,7 +3177,7 @@ handle_request(Module, Function, Args, Socket) ->
{ok, Result} ->
tsp("handle_request -> ok"
"~n Result: ~p", [Result]),
- case (catch handle_http_msg(Result, Socket)) of
+ case (catch handle_http_msg(Result, Socket, Close, Send)) of
stop ->
stop;
<<>> ->
@@ -2949,7 +3185,8 @@ handle_request(Module, Function, Args, Socket) ->
{httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]};
Data ->
handle_request(httpd_request, parse,
- [Data |[?HTTP_MAX_HEADER_SIZE]], Socket)
+ [Data |[?HTTP_MAX_HEADER_SIZE]], Socket,
+ Close, Send)
end;
NewMFA ->
tsp("handle_request -> "
@@ -2957,7 +3194,7 @@ handle_request(Module, Function, Args, Socket) ->
NewMFA
end.
-handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
+handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket, Close, Send) ->
tsp("handle_http_msg -> entry with: "
"~n RelUri: ~p"
"~n Headers: ~p"
@@ -3114,16 +3351,16 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
"Expires:Sat, 29 Oct 1994 19:43:31 GMT\r\n" ++
"Proxy-Authenticate:#1Basic" ++
"\r\n\r\n",
- gen_tcp:send(Socket, Head),
- gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
- gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ Send(Socket, Head),
+ Send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ Send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
"/capital_transfer_encoding.html" ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n",
- gen_tcp:send(Socket, Head),
- gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
- gen_tcp:send(Socket, http_chunk:encode("obar</BODY></HTML>")),
+ Send(Socket, Head),
+ Send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ Send(Socket, http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
"/cookie.html" ->
"HTTP/1.1 200 ok\r\n" ++
@@ -3142,20 +3379,20 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
"/once_chunked.html" ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Transfer-Encoding:Chunked\r\n\r\n",
- gen_tcp:send(Socket, Head),
- gen_tcp:send(Socket, http_chunk:encode("<HTML><BODY>fo")),
- gen_tcp:send(Socket,
+ Send(Socket, Head),
+ Send(Socket, http_chunk:encode("<HTML><BODY>fo")),
+ Send(Socket,
http_chunk:encode("obar</BODY></HTML>")),
http_chunk:encode_last();
"/once.html" ->
Head = "HTTP/1.1 200 ok\r\n" ++
"Content-Length:32\r\n\r\n",
- gen_tcp:send(Socket, Head),
- gen_tcp:send(Socket, "<HTML><BODY>fo"),
+ Send(Socket, Head),
+ Send(Socket, "<HTML><BODY>fo"),
test_server:sleep(1000),
- gen_tcp:send(Socket, "ob"),
+ Send(Socket, "ob"),
test_server:sleep(1000),
- gen_tcp:send(Socket, "ar</BODY></HTML>");
+ Send(Socket, "ar</BODY></HTML>");
"/invalid_http.html" ->
"HTTP/1.1 301\r\nDate:Sun, 09 Dec 2007 13:04:18 GMT\r\n" ++
"Transfer-Encoding:chunked\r\n\r\n";
@@ -3178,9 +3415,9 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
ok;
close ->
%% Nothing to send, just close
- gen_tcp:close(Socket);
+ Close(Socket);
_ when is_list(Msg) orelse is_binary(Msg) ->
- gen_tcp:send(Socket, Msg)
+ Send(Socket, Msg)
end,
tsp("handle_http_msg -> done"),
NextRequest.
@@ -3316,3 +3553,20 @@ dummy_ssl_server_hang_loop(_) ->
stop ->
ok
end.
+
+
+ensure_started([]) ->
+ ok;
+ensure_started([App|Apps]) ->
+ ensure_started(App),
+ ensure_started(Apps);
+ensure_started(App) when is_atom(App) ->
+ case (catch application:start(App)) of
+ ok ->
+ ok;
+ {error, {already_started, _}} ->
+ ok;
+ Error ->
+ throw({error, {failed_starting, App, Error}})
+ end.
+
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index fde5178879..c4d4bf969b 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -207,8 +207,11 @@
-export([ticket_5775/1,ticket_5865/1,ticket_5913/1,ticket_6003/1,
ticket_7304/1]).
-%%% Misc
--export([ipv6_hostname/1, ipv6_address/1]).
+%%% IPv6 tests
+-export([ipv6_hostname_ipcomm/0, ipv6_hostname_ipcomm/1,
+ ipv6_address_ipcomm/0, ipv6_address_ipcomm/1,
+ ipv6_hostname_essl/0, ipv6_hostname_essl/1,
+ ipv6_address_essl/0, ipv6_address_essl/1]).
%% Help functions
-export([cleanup_mnesia/0, setup_mnesia/0, setup_mnesia/1]).
@@ -241,9 +244,15 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [{group, ip}, {group, ssl}, {group, http_1_1_ip},
- {group, http_1_0_ip}, {group, http_0_9_ip},
- {group, tickets}].
+ [
+ {group, ip},
+ {group, ssl},
+ {group, http_1_1_ip},
+ {group, http_1_0_ip},
+ {group, http_0_9_ip},
+ {group, ipv6},
+ {group, tickets}
+ ].
groups() ->
[{ip, [],
@@ -329,7 +338,8 @@ groups() ->
{http_1_0_ip, [],
[ip_head_1_0, ip_get_1_0, ip_post_1_0]},
{http_0_9_ip, [], [ip_get_0_9]},
- {ipv6, [], [ipv6_hostname, ipv6_address]},
+ {ipv6, [], [ipv6_hostname_ipcomm, ipv6_address_ipcomm,
+ ipv6_hostname_essl, ipv6_address_essl]},
{tickets, [],
[ticket_5775, ticket_5865, ticket_5913, ticket_6003,
ticket_7304]}].
@@ -408,10 +418,10 @@ init_per_testcase2(Case, Config) ->
"~n Config: ~p"
"~n", [?MODULE, Case, Config]),
- IpNormal = integer_to_list(?IP_PORT) ++ ".conf",
- IpHtacess = integer_to_list(?IP_PORT) ++ "htacess.conf",
- SslNormal = integer_to_list(?SSL_PORT) ++ ".conf",
- SslHtacess = integer_to_list(?SSL_PORT) ++ "htacess.conf",
+ IpNormal = integer_to_list(?IP_PORT) ++ ".conf",
+ IpHtaccess = integer_to_list(?IP_PORT) ++ "htaccess.conf",
+ SslNormal = integer_to_list(?SSL_PORT) ++ ".conf",
+ SslHtaccess = integer_to_list(?SSL_PORT) ++ "htaccess.conf",
DataDir = ?config(data_dir, Config),
SuiteTopDir = ?config(suite_top_dir, Config),
@@ -471,9 +481,9 @@ init_per_testcase2(Case, Config) ->
io:format(user, "~w:init_per_testcase2(~w) -> ip testcase setups~n",
[?MODULE, Case]),
create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
- normal_acess, IpNormal),
+ normal_access, IpNormal),
create_config([{port, ?IP_PORT}, {sock_type, ip_comm} | NewConfig],
- mod_htaccess, IpHtacess),
+ mod_htaccess, IpHtaccess),
%% To be used by SSL test cases
io:format(user, "~w:init_per_testcase2(~w) -> ssl testcase setups~n",
@@ -491,9 +501,9 @@ init_per_testcase2(Case, Config) ->
end,
create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig],
- normal_acess, SslNormal),
+ normal_access, SslNormal),
create_config([{port, ?SSL_PORT}, {sock_type, SocketType} | NewConfig],
- mod_htaccess, SslHtacess),
+ mod_htaccess, SslHtaccess),
%% To be used by IPv6 test cases. Case-clause is so that
%% you can do ts:run(inets, httpd_SUITE, <test case>)
@@ -501,22 +511,52 @@ init_per_testcase2(Case, Config) ->
%% on 'test_host_ipv6_only' that will only be present
%% when you run the whole test suite due to shortcomings
%% of the test server.
- %% case (catch ?config(test_host_ipv6_only, Config)) of
- %% {_,IPv6Host,IPv6Adress,_,_} ->
- %% create_ipv6_config([{port, ?IP_PORT},
- %% {sock_type, ip_comm} | NewConfig],
- %% "ipv6_hostname.conf", IPv6Host),
- %% create_ipv6_config([{port, ?IP_PORT},
- %% {sock_type, ip_comm} | NewConfig],
- %% "ipv6_address.conf", IPv6Adress);
- %% _ ->
- %% ok
- %% end,
-
+
+ io:format(user, "~w:init_per_testcase2(~w) -> "
+ "maybe generate IPv6 config file(s)", [?MODULE, Case]),
+ NewConfig2 =
+ case atom_to_list(Case) of
+ "ipv6_" ++ _ ->
+ case (catch inets_test_lib:has_ipv6_support(NewConfig)) of
+ {ok, IPv6Address0} ->
+ {ok, Hostname} = inet:gethostname(),
+ IPv6Address = http_transport:ipv6_name(IPv6Address0),
+ create_ipv6_config([{port, ?IP_PORT},
+ {sock_type, ip_comm},
+ {ipv6_host, IPv6Address} |
+ NewConfig],
+ "ipv6_hostname_ipcomm.conf",
+ Hostname),
+ create_ipv6_config([{port, ?IP_PORT},
+ {sock_type, ip_comm},
+ {ipv6_host, IPv6Address} |
+ NewConfig],
+ "ipv6_address_ipcomm.conf",
+ IPv6Address),
+ create_ipv6_config([{port, ?SSL_PORT},
+ {sock_type, essl},
+ {ipv6_host, IPv6Address} |
+ NewConfig],
+ "ipv6_hostname_essl.conf",
+ Hostname),
+ create_ipv6_config([{port, ?SSL_PORT},
+ {sock_type, essl},
+ {ipv6_host, IPv6Address} |
+ NewConfig],
+ "ipv6_address_essl.conf",
+ IPv6Address),
+ [{ipv6_host, IPv6Address} | NewConfig];
+ _ ->
+ NewConfig
+ end;
+ _ ->
+ NewConfig
+ end,
+
io:format(user, "~w:init_per_testcase2(~w) -> done~n",
[?MODULE, Case]),
- NewConfig.
+ NewConfig2.
init_per_testcase3(Case, Config) ->
@@ -547,10 +587,10 @@ init_per_testcase3(Case, Config) ->
[?MODULE, Case]),
inets:disable_trace();
_ ->
- %% TraceLevel = max,
io:format(user, "~w:init_per_testcase3(~w) -> enabling trace",
[?MODULE, Case]),
- TraceLevel = 70,
+ %% TraceLevel = 70,
+ TraceLevel = max,
TraceDest = io,
inets:enable_trace(TraceLevel, TraceDest, httpd)
end,
@@ -569,7 +609,7 @@ init_per_testcase3(Case, Config) ->
inets_test_lib:start_http_server(
filename:join(TcTopDir,
integer_to_list(?IP_PORT) ++
- "htacess.conf")),
+ "htaccess.conf")),
"mod_htaccess";
"ip_" ++ Rest ->
inets_test_lib:start_http_server(
@@ -602,7 +642,7 @@ init_per_testcase3(Case, Config) ->
case inets_test_lib:start_http_server_ssl(
filename:join(TcTopDir,
integer_to_list(?SSL_PORT) ++
- "htacess.conf"), SslTag) of
+ "htaccess.conf"), SslTag) of
ok ->
"mod_htaccess";
Other ->
@@ -627,16 +667,13 @@ init_per_testcase3(Case, Config) ->
{skip, "SSL does not seem to be supported"}
end;
"ipv6_" ++ _ = TestCaseStr ->
- {ok, Hostname} = inet:gethostname(),
-
- case lists:member(list_to_atom(Hostname),
- ?config(ipv6_hosts, Config)) of
- true ->
+ case inets_test_lib:has_ipv6_support() of
+ {ok, _} ->
inets_test_lib:start_http_server(
filename:join(TcTopDir,
TestCaseStr ++ ".conf"));
- false ->
+ _ ->
{skip, "Host does not support IPv6"}
end
end,
@@ -650,8 +687,8 @@ init_per_testcase3(Case, Config) ->
"mod_htaccess" ->
ServerRoot = ?config(server_root, Config),
Path = filename:join([ServerRoot, "htdocs"]),
- catch remove_htacess(Path),
- create_htacess_data(Path, ?config(address, Config)),
+ catch remove_htaccess(Path),
+ create_htaccess_data(Path, ?config(address, Config)),
[{watchdog, Dog} | NewConfig];
"range" ->
ServerRoot = ?config(server_root, Config),
@@ -2409,30 +2446,76 @@ ip_mod_cgi_chunked_encoding_test(Config) when is_list(Config) ->
ok.
%-------------------------------------------------------------------------
-ipv6_hostname(doc) ->
+
+ipv6_hostname_ipcomm() ->
+ [{require, ipv6_hosts}].
+ipv6_hostname_ipcomm(X) ->
+ SocketType = ip_comm,
+ Port = ?IP_PORT,
+ ipv6_hostname(SocketType, Port, X).
+
+ipv6_hostname_essl() ->
+ [{require, ipv6_hosts}].
+ipv6_hostname_essl(X) ->
+ SocketType = essl,
+ Port = ?SSL_PORT,
+ ipv6_hostname(SocketType, Port, X).
+
+ipv6_hostname(_SocketType, _Port, doc) ->
["Test standard ipv6 address"];
-ipv6_hostname(suite)->
+ipv6_hostname(_SocketType, _Port, suite)->
[];
-ipv6_hostname(Config) when is_list(Config) ->
+ipv6_hostname(SocketType, Port, Config) when is_list(Config) ->
+ tsp("ipv6_hostname -> entry with"
+ "~n SocketType: ~p"
+ "~n Port: ~p"
+ "~n Config: ~p", [SocketType, Port, Config]),
Host = ?config(host, Config),
- httpd_test_lib:verify_request(ip_comm, Host, ?IP_PORT, node(),
- "GET / HTTP/1.1\r\n\r\n",
- [{statuscode, 200},
- {version, "HTTP/1.1"}]),
+ URI = "GET HTTP://" ++
+ Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n",
+ tsp("ipv6_hostname -> Host: ~p", [Host]),
+ httpd_test_lib:verify_request(SocketType, Host, Port, [inet6],
+ node(),
+ URI,
+ [{statuscode, 200}, {version, "HTTP/1.1"}]),
ok.
%%-------------------------------------------------------------------------
-ipv6_address(doc) ->
+
+ipv6_address_ipcomm() ->
+ [{require, ipv6_hosts}].
+ipv6_address_ipcomm(X) ->
+ SocketType = ip_comm,
+ Port = ?IP_PORT,
+ ipv6_address(SocketType, Port, X).
+
+ipv6_address_essl() ->
+ [{require, ipv6_hosts}].
+ipv6_address_essl(X) ->
+ SocketType = essl,
+ Port = ?SSL_PORT,
+ ipv6_address(SocketType, Port, X).
+
+ipv6_address(_SocketType, _Port, doc) ->
["Test standard ipv6 address"];
-ipv6_address(suite)->
+ipv6_address(_SocketType, _Port, suite)->
[];
-ipv6_address(Config) when is_list(Config) ->
- httpd_test_lib:verify_request(ip_comm, ?IPV6_LOCAL_HOST, ?IP_PORT,
- node(), "GET / HTTP/1.1\r\n\r\n",
- [{statuscode, 200},
- {version, "HTTP/1.1"}]),
+ipv6_address(SocketType, Port, Config) when is_list(Config) ->
+ tsp("ipv6_address -> entry with"
+ "~n SocketType: ~p"
+ "~n Port: ~p"
+ "~n Config: ~p", [SocketType, Port, Config]),
+ Host = ?config(host, Config),
+ tsp("ipv6_address -> Host: ~p", [Host]),
+ URI = "GET HTTP://" ++
+ Host ++ ":" ++ integer_to_list(Port) ++ "/ HTTP/1.1\r\n\r\n",
+ httpd_test_lib:verify_request(SocketType, Host, Port, [inet6],
+ node(),
+ URI,
+ [{statuscode, 200}, {version, "HTTP/1.1"}]),
ok.
+
%%--------------------------------------------------------------------
ticket_5775(doc) ->
["Tests that content-length is correct"];
@@ -2805,22 +2888,22 @@ cleanup_mnesia() ->
mnesia:delete_schema([node()]),
ok.
-create_htacess_data(Path, IpAddress)->
- create_htacess_dirs(Path),
+create_htaccess_data(Path, IpAddress)->
+ create_htaccess_dirs(Path),
create_html_file(filename:join([Path,"ht/open/dummy.html"])),
create_html_file(filename:join([Path,"ht/blocknet/dummy.html"])),
create_html_file(filename:join([Path,"ht/secret/dummy.html"])),
create_html_file(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
- create_htacess_file(filename:join([Path,"ht/open/.htaccess"]),
+ create_htaccess_file(filename:join([Path,"ht/open/.htaccess"]),
Path, "user one Aladdin"),
- create_htacess_file(filename:join([Path,"ht/secret/.htaccess"]),
+ create_htaccess_file(filename:join([Path,"ht/secret/.htaccess"]),
Path, "group group1 group2"),
- create_htacess_file(filename:join([Path,
+ create_htaccess_file(filename:join([Path,
"ht/secret/top_secret/.htaccess"]),
Path, "user four"),
- create_htacess_file(filename:join([Path,"ht/blocknet/.htaccess"]),
+ create_htaccess_file(filename:join([Path,"ht/blocknet/.htaccess"]),
Path, nouser, IpAddress),
create_user_group_file(filename:join([Path,"ht","users.file"]),
@@ -2835,7 +2918,7 @@ create_html_file(PathAndFileName)->
"<html><head><title>test</title></head>
<body>testar</body></html>")).
-create_htacess_file(PathAndFileName, BaseDir, RequireData)->
+create_htaccess_file(PathAndFileName, BaseDir, RequireData)->
file:write_file(PathAndFileName,
list_to_binary(
"AuthUserFile "++ BaseDir ++
@@ -2844,7 +2927,7 @@ create_htacess_file(PathAndFileName, BaseDir, RequireData)->
" Basic\n<Limit>\nrequire " ++ RequireData ++
"\n</Limit>")).
-create_htacess_file(PathAndFileName, BaseDir, nouser, IpAddress)->
+create_htaccess_file(PathAndFileName, BaseDir, nouser, IpAddress)->
file:write_file(PathAndFileName,list_to_binary(
"AuthUserFile "++ BaseDir ++
"/ht/users.file\nAuthGroupFile " ++
@@ -2858,14 +2941,14 @@ create_htacess_file(PathAndFileName, BaseDir, nouser, IpAddress)->
create_user_group_file(PathAndFileName, Data)->
file:write_file(PathAndFileName, list_to_binary(Data)).
-create_htacess_dirs(Path)->
+create_htaccess_dirs(Path)->
ok = file:make_dir(filename:join([Path,"ht"])),
ok = file:make_dir(filename:join([Path,"ht/open"])),
ok = file:make_dir(filename:join([Path,"ht/blocknet"])),
ok = file:make_dir(filename:join([Path,"ht/secret"])),
ok = file:make_dir(filename:join([Path,"ht/secret/top_secret"])).
-remove_htacess_dirs(Path)->
+remove_htaccess_dirs(Path)->
file:del_dir(filename:join([Path,"ht/secret/top_secret"])),
file:del_dir(filename:join([Path,"ht/secret"])),
file:del_dir(filename:join([Path,"ht/blocknet"])),
@@ -2888,7 +2971,7 @@ format_ip(IpAddress,Pos)when Pos > 0->
format_ip(IpAddress, _Pos)->
"1" ++ IpAddress.
-remove_htacess(Path)->
+remove_htaccess(Path)->
file:delete(filename:join([Path,"ht/open/dummy.html"])),
file:delete(filename:join([Path,"ht/secret/dummy.html"])),
file:delete(filename:join([Path,"ht/secret/top_secret/dummy.html"])),
@@ -2899,7 +2982,7 @@ remove_htacess(Path)->
file:delete(filename:join([Path,"ht/secret/top_secret/.htaccess"])),
file:delete(filename:join([Path,"ht","users.file"])),
file:delete(filename:join([Path,"ht","groups.file"])),
- remove_htacess_dirs(Path).
+ remove_htaccess_dirs(Path).
dos_hostname_poll(Type, Host, Port, Node, Hosts) ->
@@ -2939,35 +3022,66 @@ create_range_data(Path) ->
"12345678901234567890",
"12345678901234567890"])).
-%% create_ipv6_config(Config, FileName, Ipv6Address) ->
-%% ServerRoot = ?config(server_root, Config),
-%% TcTopDir = ?config(tc_top_dir, Config),
-%% Port = ?config(port, Config),
-%% SockType = ?config(sock_type, Config),
-%%
-%% MaxHdrSz = io_lib:format("~p", [256]),
-%% MaxHdrAct = io_lib:format("~p", [close]),
-%%
-%% Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
-%% " mod_include mod_dir mod_get mod_head"
-%% " mod_log mod_disk_log mod_trace",
-%%
-%% HttpConfig = [cline(["BindAddress ", "[" ++ Ipv6Address ++"]|inet6"]),
-%% cline(["Port ", integer_to_list(Port)]),
-%% cline(["ServerName ", "httpc_test"]),
-%% cline(["SocketType ", atom_to_list(SockType)]),
-%% cline([Mod_order]),
-%% cline(["ServerRoot ", ServerRoot]),
-%% cline(["DocumentRoot ",
-%% filename:join(ServerRoot, "htdocs")]),
-%% cline(["MaxHeaderSize ",MaxHdrSz]),
-%% cline(["MaxHeaderAction ",MaxHdrAct]),
-%% cline(["DirectoryIndex ", "index.html "]),
-%% cline(["DefaultType ", "text/plain"])],
-%% ConfigFile = filename:join([TcTopDir,FileName]),
-%% {ok, Fd} = file:open(ConfigFile, [write]),
-%% ok = file:write(Fd, lists:flatten(HttpConfig)),
-%% ok = file:close(Fd).
+create_ipv6_config(Config, FileName, Ipv6Address) ->
+ ServerRoot = ?config(server_root, Config),
+ TcTopDir = ?config(tc_top_dir, Config),
+ Port = ?config(port, Config),
+ SockType = ?config(sock_type, Config),
+ Mods = io_lib:format("~p", [httpd_mod]),
+ Funcs = io_lib:format("~p", [ssl_password_cb]),
+ Host = ?config(ipv6_host, Config),
+
+ MaxHdrSz = io_lib:format("~p", [256]),
+ MaxHdrAct = io_lib:format("~p", [close]),
+
+ Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
+ " mod_include mod_dir mod_get mod_head"
+ " mod_log mod_disk_log mod_trace",
+
+ SSL =
+ if
+ (SockType =:= ssl) orelse
+ (SockType =:= ossl) orelse
+ (SockType =:= essl) ->
+ [cline(["SSLCertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCertificateKeyFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLCACertificateFile ",
+ filename:join(ServerRoot, "ssl/ssl_server.pem")]),
+ cline(["SSLPasswordCallbackModule ", Mods]),
+ cline(["SSLPasswordCallbackFunction ", Funcs]),
+ cline(["SSLVerifyClient 0"]),
+ cline(["SSLVerifyDepth 1"])];
+ true ->
+ []
+ end,
+
+ BindAddress = "[" ++ Ipv6Address ++"]|inet6",
+
+ HttpConfig =
+ [cline(["BindAddress ", BindAddress]),
+ cline(["Port ", integer_to_list(Port)]),
+ cline(["ServerName ", Host]),
+ cline(["SocketType ", atom_to_list(SockType)]),
+ cline([Mod_order]),
+ cline(["ServerRoot ", ServerRoot]),
+ cline(["DocumentRoot ", filename:join(ServerRoot, "htdocs")]),
+ cline(["MaxHeaderSize ",MaxHdrSz]),
+ cline(["MaxHeaderAction ",MaxHdrAct]),
+ cline(["DirectoryIndex ", "index.html "]),
+ cline(["DefaultType ", "text/plain"]),
+ SSL],
+ ConfigFile = filename:join([TcTopDir,FileName]),
+ {ok, Fd} = file:open(ConfigFile, [write]),
+ ok = file:write(Fd, lists:flatten(HttpConfig)),
+ ok = file:close(Fd).
+
+
+%% tsp(F) ->
+%% inets_test_lib:tsp(F).
+tsp(F, A) ->
+ inets_test_lib:tsp(F, A).
tsf(Reason) ->
- test_server:fail(Reason).
+ inets_test_lib:tsf(Reason).
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 3189a758a5..2903aaafa5 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -22,7 +22,7 @@
-include("inets_test_lib.hrl").
%% Poll functions
--export([verify_request/6, verify_request/7, is_expect/1]).
+-export([verify_request/6, verify_request/7, verify_request/8, is_expect/1]).
-record(state, {request, % string()
socket, % socket()
@@ -81,33 +81,57 @@
%%------------------------------------------------------------------
verify_request(SocketType, Host, Port, Node, RequestStr, Options) ->
verify_request(SocketType, Host, Port, Node, RequestStr, Options, 30000).
-verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) ->
- {ok, Socket} = inets_test_lib:connect_bin(SocketType, Host, Port),
+verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options)
+ when is_list(TranspOpts) ->
+ verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options, 30000);
+verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut)
+ when (is_integer(TimeOut) orelse (TimeOut =:= infinity)) ->
+ verify_request(SocketType, Host, Port, [], Node, RequestStr, Options, TimeOut).
+verify_request(SocketType, Host, Port, TranspOpts, Node, RequestStr, Options, TimeOut) ->
+ tsp("verify_request -> entry with"
+ "~n SocketType: ~p"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n TranspOpts: ~p"
+ "~n Node: ~p"
+ "~n Options: ~p"
+ "~n TimeOut: ~p",
+ [SocketType, Host, Port, TranspOpts, Node, Options, TimeOut]),
+ case (catch inets_test_lib:connect_bin(SocketType, Host, Port, TranspOpts)) of
+ {ok, Socket} ->
+ tsp("verify_request -> connected - now send message"),
+ SendRes = inets_test_lib:send(SocketType, Socket, RequestStr),
+ tsp("verify_request -> send result: "
+ "~n ~p", [SendRes]),
+ State = case inets_regexp:match(RequestStr, "printenv") of
+ nomatch ->
+ #state{};
+ _ ->
+ #state{print = true}
+ end,
+
+ case request(State#state{request = RequestStr,
+ socket = Socket}, TimeOut) of
+ {error, Reason} ->
+ tsp("request failed: "
+ "~n Reason: ~p", [Reason]),
+ {error, Reason};
+ NewState ->
+ tsp("validate reply: "
+ "~n NewState: ~p", [NewState]),
+ ValidateResult =
+ validate(RequestStr, NewState, Options, Node, Port),
+ tsp("validation result: "
+ "~n ~p", [ValidateResult]),
+ inets_test_lib:close(SocketType, Socket),
+ ValidateResult
+ end;
- _SendRes = inets_test_lib:send(SocketType, Socket, RequestStr),
-
- State = case inets_regexp:match(RequestStr, "printenv") of
- nomatch ->
- #state{};
- _ ->
- #state{print = true}
- end,
-
- case request(State#state{request = RequestStr,
- socket = Socket}, TimeOut) of
- {error, Reason} ->
- tsp("request failed: "
- "~n Reason: ~p", [Reason]),
- {error, Reason};
- NewState ->
- tsp("validate reply: "
- "~n NewState: ~p", [NewState]),
- ValidateResult = validate(RequestStr, NewState, Options,
- Node, Port),
- tsp("validation result: "
- "~n ~p", [ValidateResult]),
- inets_test_lib:close(SocketType, Socket),
- ValidateResult
+ ConnectError ->
+ tsp("verify_request -> connect failed: "
+ "~n ~p"
+ "~n", [ConnectError]),
+ tsf({connect_failure, ConnectError})
end.
request(#state{mfa = {Module, Function, Args},
@@ -214,7 +238,10 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
headers = Headers,
body = Body}, Options, N, P) ->
- %io:format("Status~p: H:~p B:~p~n", [StatusCode, Headers, Body]),
+ %% tsp("validate -> entry with"
+ %% "~n StatusCode: ~p"
+ %% "~n Headers: ~p"
+ %% "~n Body: ~p", [StatusCode, Headers, Body]),
check_version(Version, Options),
case lists:keysearch(statuscode, 1, Options) of
{value, _} ->
@@ -342,8 +369,10 @@ print(_, _, #state{print = false}) ->
ok.
-%% tsp(F) ->
-%% tsp(F, []).
+tsp(F) ->
+ inets_test_lib:tsp(F).
tsp(F, A) ->
- test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+ inets_test_lib:tsp(F, A).
+tsf(Reason) ->
+ inets_test_lib:tsf(Reason).
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
index 49ea18501f..9d7202e087 100644
--- a/lib/inets/test/inets_app_test.erl
+++ b/lib/inets/test/inets_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index c837326bb5..2e19c41f16 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -26,18 +26,64 @@
-export([start_http_server/1, start_http_server/2]).
-export([start_http_server_ssl/1, start_http_server_ssl/2]).
-export([hostname/0]).
--export([connect_bin/3, connect_byte/3, send/3, close/2]).
+-export([connect_bin/3, connect_bin/4,
+ connect_byte/3, connect_byte/4,
+ send/3, close/2]).
-export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]).
-export([info/4, log/4, debug/4, print/4]).
+-export([tsp/1, tsp/2, tsf/1]).
-export([check_body/1]).
-export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]).
--export([oscmd/1]).
+-export([oscmd/1, has_ipv6_support/1]).
-export([non_pc_tc_maybe_skip/4, os_based_skip/1, skip/3, fail/3]).
-export([flush/0]).
-export([start_node/1, stop_node/1]).
%% -- Misc os command and stuff
+has_ipv6_support(Config) ->
+ case lists:keysearch(ipv6_hosts, 1, Config) of
+ false ->
+ %% Do a basic check to se if
+ %% our own host has a working IPv6 address...
+ tsp("has_ipv6_support -> no ipv6_hosts config"),
+ {ok, Hostname} = inet:gethostname(),
+ case inet:getaddrs(Hostname, inet6) of
+ {ok, [Addr|_]} when is_tuple(Addr) andalso
+ (element(1, Addr) =/= 0) ->
+ %% We actually need to test that the addr can be used,
+ %% this is done by attempting to create a (tcp)
+ %% listen socket
+ tsp("has_ipv6_support -> check Addr: ~p", [Addr]),
+ case (catch gen_tcp:listen(0, [inet6, {ip, Addr}])) of
+ {ok, LSock} ->
+ tsp("has_ipv6_support -> we are ipv6 host"),
+ gen_tcp:close(LSock),
+ {ok, Addr};
+ _ ->
+ undefined
+ end;
+ _ ->
+ undefined
+ end;
+ {value, {_, Hosts}} when is_list(Hosts) ->
+ %% Check if our host is in the list of *known* IPv6 hosts
+ tsp("has_ipv6_support -> Hosts: ~p", [Hosts]),
+ {ok, Hostname} = inet:gethostname(),
+ case lists:member(list_to_atom(Hostname), Hosts) of
+ true ->
+ tsp("has_ipv6_support -> we are known ipv6 host"),
+ {ok, [Addr|_]} = inet:getaddrs(Hostname, inet6),
+ {ok, Addr};
+ false ->
+ undefined
+ end;
+
+ _ ->
+ undefined
+
+ end.
+
oscmd(Cmd) ->
string:strip(os:cmd(Cmd), right, $\n).
@@ -87,31 +133,34 @@ start_http_server(Conf) ->
start_http_server(Conf, ?HTTP_DEFAULT_SSL_KIND).
start_http_server(Conf, essl = _SslTag) ->
+ tsp("start_http_server(essl) -> entry - try start crypto and public_key"),
application:start(crypto),
+ application:start(public_key),
do_start_http_server(Conf);
-start_http_server(Conf, _SslTag) ->
+start_http_server(Conf, SslTag) ->
+ tsp("start_http_server(~w) -> entry", [SslTag]),
do_start_http_server(Conf).
do_start_http_server(Conf) ->
- tsp("start http server with "
+ tsp("do_start_http_server -> entry with"
"~n Conf: ~p"
"~n", [Conf]),
application:load(inets),
case application:set_env(inets, services, [{httpd, Conf}]) of
ok ->
+ tsp("start_http_server -> httpd conf stored in inets app env"),
case application:start(inets) of
ok ->
+ tsp("start_http_server -> inets started"),
ok;
Error1 ->
- test_server:format("<ERROR> Failed starting application: "
- "~n Error: ~p"
- "~n", [Error1]),
+ tsp("<ERROR> Failed starting application: "
+ "~n Error1: ~p", [Error1]),
Error1
end;
Error2 ->
- test_server:format("<ERROR> Failed set application env: "
- "~n Error: ~p"
- "~n", [Error2]),
+ tsp("<ERROR> Failed set application env: "
+ "~n Error: ~p", [Error2]),
Error2
end.
@@ -285,29 +334,45 @@ os_based_skip(_) ->
%% Host -> atom() | string() | {A, B, C, D}
%% Port -> integer()
-connect_bin(ssl, Host, Port) ->
- connect(ssl, Host, Port, [binary, {packet,0}]);
-connect_bin(ossl, Host, Port) ->
- connect(ssl, Host, Port, [{ssl_imp, old}, binary, {packet,0}]);
-connect_bin(essl, Host, Port) ->
- connect(ssl, Host, Port, [{ssl_imp, new}, binary, {packet,0}, {reuseaddr, true}]);
-connect_bin(ip_comm, Host, Port) ->
- Opts = [inet6, binary, {packet,0}],
+connect_bin(SockType, Host, Port) ->
+ connect_bin(SockType, Host, Port, []).
+
+connect_bin(ssl, Host, Port, Opts0) ->
+ Opts = [binary, {packet,0} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_bin(ossl, Host, Port, Opts0) ->
+ Opts = [{ssl_imp, old}, binary, {packet,0} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_bin(essl, Host, Port, Opts0) ->
+ Opts = [{ssl_imp, new}, binary, {packet,0}, {reuseaddr, true} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_bin(ip_comm, Host, Port, Opts0) ->
+ Opts = [binary, {packet, 0} | Opts0],
connect(ip_comm, Host, Port, Opts).
+
+connect_byte(SockType, Host, Port) ->
+ connect_byte(SockType, Host, Port, []).
-connect_byte(ssl, Host, Port) ->
- connect(ssl, Host, Port, [{packet,0}]);
-connect_byte(ossl, Host, Port) ->
- connect(ssl, Host, Port, [{ssl_imp, old}, {packet,0}]);
-connect_byte(essl, Host, Port) ->
- connect(ssl, Host, Port, [{ssl_imp, new}, {packet,0}]);
-connect_byte(ip_comm, Host, Port) ->
- Opts = [inet6, {packet,0}],
+connect_byte(ssl, Host, Port, Opts0) ->
+ Opts = [{packet,0} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_byte(ossl, Host, Port, Opts0) ->
+ Opts = [{ssl_imp, old}, {packet,0} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_byte(essl, Host, Port, Opts0) ->
+ Opts = [{ssl_imp, new}, {packet,0} | Opts0],
+ connect(ssl, Host, Port, Opts);
+connect_byte(ip_comm, Host, Port, Opts0) ->
+ Opts = [{packet,0} | Opts0],
connect(ip_comm, Host, Port, Opts).
connect(ssl, Host, Port, Opts) ->
+ tsp("connect(ssl) -> entry with"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Opts: ~p", [Host, Port, Opts]),
ssl:start(),
%% Does not support ipv6 in old ssl
case ssl:connect(Host, Port, Opts) of
@@ -319,21 +384,28 @@ connect(ssl, Host, Port, Opts) ->
Error
end;
connect(ip_comm, Host, Port, Opts) ->
+ tsp("connect(ip_comm) -> entry with"
+ "~n Host: ~p"
+ "~n Port: ~p"
+ "~n Opts: ~p", [Host, Port, Opts]),
case gen_tcp:connect(Host,Port, Opts) of
{ok, Socket} ->
- %% tsp("connect success"),
+ tsp("connect success"),
{ok, Socket};
{error, nxdomain} ->
- tsp("nxdomain opts: ~p", [Opts]),
+ tsp("connect error nxdomain when opts: ~p", [Opts]),
connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
{error, eafnosupport} ->
- tsp("eafnosupport opts: ~p", [Opts]),
+ tsp("connect error eafnosupport when opts: ~p", [Opts]),
+ connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
+ {error, econnreset} ->
+ tsp("connect error econnreset when opts: ~p", [Opts]),
connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
{error, enetunreach} ->
- tsp("eafnosupport opts: ~p", [Opts]),
+ tsp("connect error eafnosupport when opts: ~p", [Opts]),
connect(ip_comm, Host, Port, lists:delete(inet6, Opts));
{error, {enfile,_}} ->
- tsp("Error enfile"),
+ tsp("connect error enfile when opts: ~p", [Opts]),
{error, enfile};
Error ->
tsp("Unexpected error: "
@@ -414,7 +486,22 @@ flush() ->
tsp(F) ->
tsp(F, []).
tsp(F, A) ->
- test_server:format("~p ~p ~p:" ++ F ++ "~n", [node(), self(), ?MODULE | A]).
+ Timestamp = formated_timestamp(),
+ test_server:format("*** ~s ~p ~p ~w:" ++ F ++ "~n",
+ [Timestamp, node(), self(), ?MODULE | A]).
tsf(Reason) ->
test_server:fail(Reason).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
diff --git a/lib/inets/test/inets_test_lib.hrl b/lib/inets/test/inets_test_lib.hrl
index cc83a309b5..4dd81093a2 100644
--- a/lib/inets/test/inets_test_lib.hrl
+++ b/lib/inets/test/inets_test_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index c0e25a30e3..4abc1733d3 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.6
+INETS_VSN = 5.7
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index de10e31d36..214e994889 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -104,6 +104,8 @@ TOP_SPECS_FILE = specs.xml
# ----------------------------------------------------
XML_FLAGS +=
+SPECS_ESRC = ../../src
+
SPECS_FLAGS = -I../../include
# ----------------------------------------------------
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 6f85388c22..98cdd416b0 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -288,196 +288,156 @@
<datatypes>
<datatype>
+ <name name="load_ret"/>
+ </datatype>
+ <datatype>
<name name="load_error_rsn"/>
</datatype>
</datatypes>
<funcs>
<func>
- <name>set_path(Path) -> true | {error, What}</name>
+ <name name="set_path" arity="1"/>
<fsummary>Set the code server search path</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>Dir = string()</v>
- <v>What = bad_directory | bad_path</v>
- </type>
<desc>
- <p>Sets the code path to the list of directories <c>Path</c>.</p>
+ <p>Sets the code path to the list of directories <c><anno>Path</anno></c>.</p>
<p>Returns <c>true</c> if successful, or
- <c>{error, bad_directory}</c> if any <c>Dir</c> is not
+ <c>{error, bad_directory}</c> if any <c><anno>Dir</anno></c> is not
the name of a directory, or <c>{error, bad_path}</c> if
the argument is invalid.</p>
</desc>
</func>
<func>
- <name>get_path() -> Path</name>
+ <name name="get_path" arity="0"/>
<fsummary>Return the code server search path</fsummary>
- <type>
- <v>Path = [Dir]</v>
- <v>Dir = string()</v>
- </type>
<desc>
<p>Returns the code path</p>
</desc>
</func>
<func>
- <name>add_path(Dir) -> true | {error, What}</name>
- <name>add_pathz(Dir) -> true | {error, What}</name>
+ <name name="add_path" arity="1"/>
+ <name name="add_pathz" arity="1"/>
<fsummary>Add a directory to the end of the code path</fsummary>
- <type>
- <v>Dir = string()</v>
- <v>What = bad_directory</v>
- </type>
+ <type name="add_path_ret"/>
<desc>
- <p>Adds <c>Dir</c> to the code path. The directory is added as
- the last directory in the new path. If <c>Dir</c> already
+ <p>Adds <c><anno>Dir</anno></c> to the code path. The directory is added as
+ the last directory in the new path. If <c><anno>Dir</anno></c> already
exists in the path, it is not added.</p>
<p>Returns <c>true</c> if successful, or
- <c>{error, bad_directory}</c> if <c>Dir</c> is not the name
+ <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> is not the name
of a directory.</p>
</desc>
</func>
<func>
- <name>add_patha(Dir) -> true | {error, What}</name>
+ <name name="add_patha" arity="1"/>
<fsummary>Add a directory to the beginning of the code path</fsummary>
- <type>
- <v>Dir = string()</v>
- <v>What = bad_directory</v>
- </type>
+ <type name="add_path_ret"/>
<desc>
- <p>Adds <c>Dir</c> to the beginning of the code path. If
- <c>Dir</c> already exists, it is removed from the old
+ <p>Adds <c><anno>Dir</anno></c> to the beginning of the code path. If
+ <c><anno>Dir</anno></c> already exists, it is removed from the old
position in the code path.</p>
<p>Returns <c>true</c> if successful, or
- <c>{error, bad_directory}</c> if <c>Dir</c> is not the name
+ <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> is not the name
of a directory.</p>
</desc>
</func>
<func>
- <name>add_paths(Dirs) -> ok</name>
- <name>add_pathsz(Dirs) -> ok</name>
+ <name name="add_paths" arity="1"/>
+ <name name="add_pathsz" arity="1"/>
<fsummary>Add directories to the end of the code path</fsummary>
- <type>
- <v>Dirs = [Dir]</v>
- <v>Dir = string()</v>
- </type>
<desc>
- <p>Adds the directories in <c>Dirs</c> to the end of the code
- path. If a <c>Dir</c> already exists, it is not added. This
+ <p>Adds the directories in <c><anno>Dirs</anno></c> to the end of the code
+ path. If a <c><anno>Dir</anno></c> already exists, it is not added. This
function always returns <c>ok</c>, regardless of the validity
- of each individual <c>Dir</c>.</p>
+ of each individual <c><anno>Dir</anno></c>.</p>
</desc>
</func>
<func>
- <name>add_pathsa(Dirs) -> ok</name>
+ <name name="add_pathsa" arity="1"/>
<fsummary>Add directories to the beginning of the code path</fsummary>
- <type>
- <v>Dirs = [Dir]</v>
- <v>Dir = string()</v>
- </type>
<desc>
- <p>Adds the directories in <c>Dirs</c> to the beginning of
- the code path. If a <c>Dir</c> already exists, it is removed
+ <p>Adds the directories in <c><anno>Dirs</anno></c> to the beginning of
+ the code path. If a <c><anno>Dir</anno></c> already exists, it is removed
from the old position in the code path. This function always
returns <c>ok</c>, regardless of the validity of each
- individual <c>Dir</c>.</p>
+ individual <c><anno>Dir</anno></c>.</p>
</desc>
</func>
<func>
- <name>del_path(Name | Dir) -> true | false | {error, What}</name>
+ <name name="del_path" arity="1"/>
<fsummary>Delete a directory from the code path</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Dir = string()</v>
- <v>What = bad_name</v>
- </type>
<desc>
<p>Deletes a directory from the code path. The argument can be
- an atom <c>Name</c>, in which case the directory with
- the name <c>.../Name[-Vsn][/ebin]</c> is deleted from the code
+ an atom <c><anno>Name</anno></c>, in which case the directory with
+ the name <c>.../<anno>Name</anno>[-Vsn][/ebin]</c> is deleted from the code
path. It is also possible to give the complete directory name
- <c>Dir</c> as argument.</p>
+ <c><anno>Dir</anno></c> as argument.</p>
<p>Returns <c>true</c> if successful, or <c>false</c> if
the directory is not found, or <c>{error, bad_name}</c> if
the argument is invalid.</p>
</desc>
</func>
<func>
- <name>replace_path(Name, Dir) -> true | {error, What}</name>
+ <name name="replace_path" arity="2"/>
<fsummary>Replace a directory with another in the code path</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>Dir = string()</v>
- <v>What = bad_name | bad_directory | {badarg, term()}</v>
- </type>
<desc>
<p>This function replaces an old occurrence of a directory
- named <c>.../Name[-Vsn][/ebin]</c>, in the code path, with
- <c>Dir</c>. If <c>Name</c> does not exist, it adds the new
- directory <c>Dir</c> last in the code path. The new directory
- must also be named <c>.../Name[-Vsn][/ebin]</c>. This function
+ named <c>.../<anno>Name</anno>[-Vsn][/ebin]</c>, in the code path, with
+ <c><anno>Dir</anno></c>. If <c><anno>Name</anno></c> does not exist, it adds the new
+ directory <c><anno>Dir</anno></c> last in the code path. The new directory
+ must also be named <c>.../<anno>Name</anno>[-Vsn][/ebin]</c>. This function
should be used if a new version of the directory (library) is
added to a running system.</p>
<p>Returns <c>true</c> if successful, or
- <c>{error, bad_name}</c> if <c>Name</c> is not found, or
- <c>{error, bad_directory}</c> if <c>Dir</c> does not exist, or
- <c>{error, {badarg, [Name, Dir]}}</c> if <c>Name</c> or
- <c>Dir</c> is invalid.</p>
+ <c>{error, bad_name}</c> if <c><anno>Name</anno></c> is not found, or
+ <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> does not exist, or
+ <c>{error, {badarg, [<anno>Name</anno>, <anno>Dir</anno>]}}</c> if <c><anno>Name</anno></c> or
+ <c><anno>Dir</anno></c> is invalid.</p>
</desc>
</func>
<func>
- <name>load_file(Module) -> {module, Module} | {error, What}</name>
+ <name name="load_file" arity="1"/>
<fsummary>Load a module</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>What = nofile | sticky_directory | badarg | term()</v>
- </type>
+ <type name="load_ret"/>
<desc>
- <p>Tries to load the Erlang module <c>Module</c>, using
+ <p>Tries to load the Erlang module <c><anno>Module</anno></c>, using
the code path. It looks for the object code file with an
extension that corresponds to the Erlang machine used, for
- example <c>Module.beam</c>. The loading fails if the module
+ example <c><anno>Module</anno>.beam</c>. The loading fails if the module
name found in the object code differs from the name
- <c>Module</c>.
+ <c><anno>Module</anno></c>.
<seealso marker="#load_binary/3">load_binary/3</seealso> must
be used to load object code with a module name that is
different from the file name.</p>
- <p>Returns <c>{module, Module}</c> if successful, or
+ <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, or <c>{error, badarg}</c> if the argument
- is invalid. Also if the loading fails, an error tuple is
+ 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>What</c>.</p>
+ for possible values of <c><anno>What</anno></c>.</p>
</desc>
</func>
<func>
- <name>load_abs(Filename) -> {module, Module} | {error, What}</name>
+ <name name="load_abs" arity="1"/>
<fsummary>Load a module, residing in a given file</fsummary>
- <type>
- <v>Filename = string()</v>
- <v>Module = atom()</v>
- <v>What = nofile | sticky_directory | badarg | term()</v>
- </type>
+ <type name="load_ret"/>
+ <type name="loaded_filename"/>
+ <type name="loaded_ret_atoms"/>
<desc>
- <p>Does the same as <c>load_file(Module)</c>, but
- <c>Filename</c> is either an absolute file name, or a
+ <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
a value in the same way as
<seealso marker="#load_file/1">load_file/1</seealso>. Note
- that <c>Filename</c> should not contain the extension (for
+ that <c><anno>Filename</anno></c> should not contain the extension (for
example <c>".beam"</c>); <c>load_abs/1</c> adds the correct
extension itself.</p>
</desc>
</func>
<func>
- <name>ensure_loaded(Module) -> {module, Module} | {error, What}</name>
+ <name name="ensure_loaded" arity="1"/>
<fsummary>Ensure that a module is loaded</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>What = nofile | sticky_directory | embedded | badarg | term()</v>
- </type>
<desc>
<p>Tries to to load a module in the same way as
<seealso marker="#load_file/1">load_file/1</seealso>,
@@ -487,54 +447,45 @@
</desc>
</func>
<func>
- <name>load_binary(Module, Filename, Binary) -> {module, Module} | {error, What}</name>
+ <name name="load_binary" arity="3"/>
<fsummary>Load object code for a module</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Filename = string()</v>
- <v>What = sticky_directory | badarg | term()</v>
- </type>
+ <type name="loaded_filename"/>
+ <type name="loaded_ret_atoms"/>
<desc>
<p>This function can be used to load object code on remote
- Erlang nodes. The argument <c>Binary</c> must contain
- object code for <c>Module</c>.
- <c>Filename</c> is only used by the code server to keep a
- record of from which file the object code for <c>Module</c>
- comes. Accordingly, <c>Filename</c> is not opened and read by
+ Erlang nodes. The argument <c><anno>Binary</anno></c> must contain
+ object code for <c><anno>Module</anno></c>.
+ <c><anno>Filename</anno></c> is only used by the code server to keep a
+ record of from which file the object code for <c><anno>Module</anno></c>
+ comes. Accordingly, <c><anno>Filename</anno></c> is not opened and read by
the code server.</p>
- <p>Returns <c>{module, Module}</c> if successful, or
+ <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>What</c>.</p>
+ for possible values of <c><anno>What</anno></c>.</p>
</desc>
</func>
<func>
- <name>delete(Module) -> true | false</name>
+ <name name="delete" arity="1"/>
<fsummary>Removes current code for a module</fsummary>
- <type>
- <v>Module = atom()</v>
- </type>
<desc>
- <p>Removes the current code for <c>Module</c>, that is,
- the current code for <c>Module</c> is made old. This means
+ <p>Removes the current code for <c><anno>Module</anno></c>, that is,
+ the current code for <c><anno>Module</anno></c> is made old. This means
that processes can continue to execute the code in the module,
but that no external function calls can be made to it.</p>
<p>Returns <c>true</c> if successful, or <c>false</c> if there
- is old code for <c>Module</c> which must be purged first, or
- if <c>Module</c> is not a (loaded) module.</p>
+ is old code for <c><anno>Module</anno></c> which must be purged first, or
+ if <c><anno>Module</anno></c> is not a (loaded) module.</p>
</desc>
</func>
<func>
- <name>purge(Module) -> true | false</name>
+ <name name="purge" arity="1"/>
<fsummary>Removes old code for a module</fsummary>
- <type>
- <v>Module = atom()</v>
- </type>
<desc>
- <p>Purges the code for <c>Module</c>, that is, removes code
+ <p>Purges the code for <c><anno>Module</anno></c>, that is, removes code
marked as old. If some processes still linger in the old code,
these processes are killed before the code is removed.</p>
<p>Returns <c>true</c> if successful and any process needed to
@@ -542,31 +493,26 @@
</desc>
</func>
<func>
- <name>soft_purge(Module) -> true | false</name>
+ <name name="soft_purge" arity="1"/>
<fsummary>Removes old code for a module, unless no process uses it</fsummary>
- <type>
- <v>Module = atom()</v>
- </type>
<desc>
- <p>Purges the code for <c>Module</c>, that is, removes code
+ <p>Purges the code for <c><anno>Module</anno></c>, that is, removes code
marked as old, but only if no processes linger in it.</p>
<p>Returns <c>false</c> if the module could not be purged due
to processes lingering in old code, otherwise <c>true</c>.</p>
</desc>
</func>
<func>
- <name>is_loaded(Module) -> {file, Loaded} | false</name>
+ <name name="is_loaded" arity="1"/>
<fsummary>Check if a module is loaded</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Loaded = Absname | preloaded | cover_compiled</v>
- <v>Absname = string()</v>
- </type>
- <desc>
- <p>Checks if <c>Module</c> is loaded. If it is,
- <c>{file, Loaded}</c> is returned, otherwise <c>false</c>.</p>
- <p>Normally, <c>Loaded</c> is the absolute file name
- <c>Absname</c> from which the code was obtained. If the module
+ <type name="loaded_filename"/>
+ <type name="loaded_ret_atoms"/>
+ <type_desc name="loaded_filename"><c><anno>Filename</anno></c> is an absolute filename</type_desc>
+ <desc>
+ <p>Checks if <c><anno>Module</anno></c> is loaded. If it is,
+ <c>{file, <anno>Loaded</anno>}</c> is returned, otherwise <c>false</c>.</p>
+ <p>Normally, <c><anno>Loaded</anno></c> is the absolute file name
+ <c>Filename</c> from which the code was obtained. If the module
is preloaded (see
<seealso marker="sasl:script">script(4)</seealso>),
<c>Loaded==preloaded</c>. If the module is Cover compiled (see
@@ -575,32 +521,26 @@
</desc>
</func>
<func>
- <name>all_loaded() -> [{Module, Loaded}]</name>
+ <name name="all_loaded" arity="0"/>
<fsummary>Get all loaded modules</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Loaded = Absname | preloaded | cover_compiled</v>
- <v>Absname = string()</v>
- </type>
+ <type name="loaded_filename"/>
+ <type name="loaded_ret_atoms"/>
+ <type_desc name="loaded_filename"><c><anno>Filename</anno></c> is an absolute filename</type_desc>
<desc>
- <p>Returns a list of tuples <c>{Module, Loaded}</c> for all
- loaded modules. <c>Loaded</c> is normally the absolute file
+ <p>Returns a list of tuples <c>{<anno>Module</anno>, <anno>Loaded</anno>}</c> for all
+ loaded modules. <c><anno>Loaded</anno></c> is normally the absolute file
name, as described for
<seealso marker="#is_loaded/1">is_loaded/1</seealso>.</p>
</desc>
</func>
<func>
- <name>which(Module) -> Which</name>
+ <name name="which" arity="1"/>
<fsummary>The object code file of a module</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Which = Filename | non_existing | preloaded | cover_compiled</v>
- <v>Filename = string()</v>
- </type>
+ <type name="loaded_ret_atoms"/>
<desc>
<p>If the module is not loaded, this function searches the code
path for the first file which contains object code for
- <c>Module</c> and returns the absolute file name. If
+ <c><anno>Module</anno></c> and returns the absolute file name. If
the module is loaded, it returns the name of the file which
contained the loaded object code. If the module is pre-loaded,
<c>preloaded</c> is returned. If the module is Cover compiled,
@@ -609,21 +549,16 @@
</desc>
</func>
<func>
- <name>get_object_code(Module) -> {Module, Binary, Filename} | error</name>
+ <name name="get_object_code" arity="1"/>
<fsummary>Get the object code for a module</fsummary>
- <type>
- <v>Module = atom()</v>
- <v>Binary = binary()</v>
- <v>Filename = string()</v>
- </type>
<desc>
<p>Searches the code path for the object code of the module
- <c>Module</c>. It returns <c>{Module, Binary, Filename}</c>
- if successful, and <c>error</c> if not. <c>Binary</c> is a
+ <c><anno>Module</anno></c>. It returns <c>{<anno>Module</anno>, <anno>Binary</anno>, <anno>Filename</anno>}</c>
+ if successful, and <c>error</c> if not. <c><anno>Binary</anno></c> is a
binary data object which contains the object code for
the module. This can be useful if code is to be loaded on a
remote node in a distributed system. For example, loading
- module <c>Module</c> on a node <c>Node</c> is done as
+ module <c><anno>Module</anno></c> on a node <c>Node</c> is done as
follows:</p>
<code type="none">
...
@@ -633,7 +568,7 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>root_dir() -> string()</name>
+ <name name="root_dir" arity="0"/>
<fsummary>Root directory of Erlang/OTP</fsummary>
<desc>
<p>Returns the root directory of Erlang/OTP, which is
@@ -644,7 +579,7 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>lib_dir() -> string()</name>
+ <name name="lib_dir" arity="0"/>
<fsummary>Library directory of Erlang/OTP</fsummary>
<desc>
<p>Returns the library directory, <c>$OTPROOT/lib</c>, where
@@ -655,19 +590,16 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>lib_dir(Name) -> string() | {error, bad_name}</name>
+ <name name="lib_dir" arity="1"/>
<fsummary>Library directory for an application</fsummary>
- <type>
- <v>Name = atom()</v>
- </type>
<desc>
<p>This function is mainly intended for finding out the path
for the "library directory", the top directory, for an
- application <c>Name</c> located under <c>$OTPROOT/lib</c> or
+ application <c><anno>Name</anno></c> located under <c>$OTPROOT/lib</c> or
on a directory referred to via the <c>ERL_LIBS</c>
environment variable.</p>
- <p>If there is a regular directory called <c>Name</c> or
- <c>Name-Vsn</c> in the code path with an <c>ebin</c>
+ <p>If there is a regular directory called <c><anno>Name</anno></c> or
+ <c><anno>Name</anno>-Vsn</c> in the code path with an <c>ebin</c>
subdirectory, the path to this directory is returned (not
the <c>ebin</c> directory). If the directory refers to a
directory in an archive, the archive name is stripped away
@@ -681,23 +613,19 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
<pre>
> <input>code:lib_dir(mnesia).</input>
"/usr/local/otp/lib/mnesia-4.2.2"</pre>
- <p>Returns <c>{error, bad_name}</c> if <c>Name</c>
+ <p>Returns <c>{error, bad_name}</c> if <c><anno>Name</anno></c>
is not the name of an application under <c>$OTPROOT/lib</c> or
on a directory referred to via the <c>ERL_LIBS</c>
environment variable. Fails with an exception if <c>Name</c>
has the wrong type.</p>
- <warning><p>For backward compatibility, <c>Name</c> is also allowed to
+ <warning><p>For backward compatibility, <c><anno>Name</anno></c> is also allowed to
be a string. That will probably change in a future release.</p></warning>
</desc>
</func>
<func>
- <name>lib_dir(Name, SubDir) -> string() | {error, bad_name}</name>
+ <name name="lib_dir" arity="2"/>
<fsummary>subdirectory for an application</fsummary>
- <type>
- <v>Name = atom()</v>
- <v>SubDir = atom()</v>
- </type>
<desc>
<p>Returns the path to a subdirectory directly under the top
directory of an application. Normally the subdirectories
@@ -711,12 +639,12 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
> <input>code:lib_dir(megaco, priv).</input>
"/usr/local/otp/lib/megaco-3.9.1.1/priv"</pre>
- <p>Fails with an exception if <c>Name</c> or <c>SubDir</c> has
+ <p>Fails with an exception if <c><anno>Name</anno></c> or <c><anno>SubDir</anno></c> has
the wrong type.</p>
</desc>
</func>
<func>
- <name>compiler_dir() -> string()</name>
+ <name name="compiler_dir" arity="0"/>
<fsummary>Library directory for the compiler</fsummary>
<desc>
<p>Returns the compiler library directory. Equivalent to
@@ -724,21 +652,18 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>priv_dir(Name) -> string() | {error, bad_name}</name>
+ <name name="priv_dir" arity="1"/>
<fsummary>Priv directory for an application</fsummary>
- <type>
- <v>Name = atom()</v>
- </type>
<desc>
<p>Returns the path to the <c>priv</c> directory in an
- application. Equivalent to <c>code:lib_dir(Name,priv).</c>.</p>
+ application. Equivalent to <c>code:lib_dir(<anno>Name</anno>, priv).</c>.</p>
- <warning><p>For backward compatibility, <c>Name</c> is also allowed to
+ <warning><p>For backward compatibility, <c><anno>Name</anno></c> is also allowed to
be a string. That will probably change in a future release.</p></warning>
</desc>
</func>
<func>
- <name>objfile_extension() -> ".beam"</name>
+ <name name="objfile_extension" arity="0"/>
<fsummary>Object code file extension</fsummary>
<desc>
<p>Returns the object code file extension that corresponds to
@@ -746,24 +671,16 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>stick_dir(Dir) -> ok | error</name>
+ <name name="stick_dir" arity="1"/>
<fsummary>Mark a directory as sticky</fsummary>
- <type>
- <v>Dir = string()</v>
- <v>What = term()</v>
- </type>
<desc>
- <p>This function marks <c>Dir</c> as sticky.</p>
+ <p>This function marks <c><anno>Dir</anno></c> as sticky.</p>
<p>Returns <c>ok</c> if successful or <c>error</c> if not.</p>
</desc>
</func>
<func>
- <name>unstick_dir(Dir) -> ok | error</name>
+ <name name="unstick_dir" arity="1"/>
<fsummary>Remove a sticky directory mark</fsummary>
- <type>
- <v>Dir = string()</v>
- <v>What = term()</v>
- </type>
<desc>
<p>This function unsticks a directory which has been marked as
sticky.</p>
@@ -771,45 +688,39 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>is_sticky(Module) -> true | false</name>
+ <name name="is_sticky" arity="1"/>
<fsummary>Test whether a module is sticky</fsummary>
- <type>
- <v>Module = atom()</v>
- </type>
<desc>
- <p>This function returns <c>true</c> if <c>Module</c> is the
+ <p>This function returns <c>true</c> if <c><anno>Module</anno></c> is the
name of a module that has been loaded from a sticky directory
(or in other words: an attempt to reload the module will fail),
- or <c>false</c> if <c>Module</c> is not a loaded module or is
+ or <c>false</c> if <c><anno>Module</anno></c> is not a loaded module or is
not sticky.</p>
</desc>
</func>
<func>
- <name>rehash() -> ok</name>
+ <name name="rehash" arity="0"/>
<fsummary>Rehash or create code path cache</fsummary>
<desc>
<p>This function creates or rehashes the code path cache.</p>
</desc>
</func>
<func>
- <name>where_is_file(Filename) -> Absname | non_existing</name>
+ <name name="where_is_file" arity="1"/>
<fsummary>Full name of a file located in the code path</fsummary>
- <type>
- <v>Filename = Absname = string()</v>
- </type>
<desc>
- <p>Searches the code path for <c>Filename</c>, a file of
+ <p>Searches the code path for <c><anno>Filename</anno></c>, a file of
arbitrary type. If found, the full name is returned.
<c>non_existing</c> is returned if the file cannot be found.
The function can be useful, for example, to locate
application resource files. If the code path cache is used,
the code server will efficiently read the full name from
- the cache, provided that <c>Filename</c> is an object code
+ the cache, provided that <c><anno>Filename</anno></c> is an object code
file or an <c>.app</c> file.</p>
</desc>
</func>
<func>
- <name>clash() -> ok</name>
+ <name name="clash" arity="0"/>
<fsummary>Search for modules with identical names.</fsummary>
<desc>
<p>Searches the entire code space for module names with
@@ -817,10 +728,10 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
</desc>
</func>
<func>
- <name>is_module_native(Module) -> true | false | undefined</name>
+ <name>is_module_native(Module) -> boolean() | undefined</name>
<fsummary>Test whether a module has native code</fsummary>
<type>
- <v>Module = atom()</v>
+ <v>Module = module()</v>
</type>
<desc>
<p>This function returns <c>true</c> if <c>Module</c> is
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index e0feaf6ee7..861c582211 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -95,9 +95,6 @@
<datatypes>
<datatype>
- <name name="bindings"/>
- </datatype>
- <datatype>
<name name="deep_list"/>
</datatype>
<datatype>
@@ -136,12 +133,6 @@
</desc>
</datatype>
<datatype>
- <name name="date"/>
- </datatype>
- <datatype>
- <name name="time"/>
- </datatype>
- <datatype>
<name name="date_time"/>
<desc>
<p>Must denote a valid date and time.</p>
@@ -1220,15 +1211,15 @@ f.txt: {person, "kalle", 25}.
<item>
<p>The current system access to the file.</p>
</item>
- <tag><c>atime = time()</c></tag>
+ <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso></c></tag>
<item>
<p>The last (local) time the file was read.</p>
</item>
- <tag><c>mtime = time()</c></tag>
+ <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso></c></tag>
<item>
<p>The last (local) time the file was written.</p>
</item>
- <tag><c>ctime = time()</c></tag>
+ <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso></c></tag>
<item>
<p>The interpretation of this time field depends on
the operating system. On Unix, it is the last time
@@ -1669,15 +1660,15 @@ f.txt: {person, "kalle", 25}.
<p>The following fields are used from the record, if they are
given.</p>
<taglist>
- <tag><c>atime = time()</c></tag>
+ <tag><c>atime = <seealso marker="#type-date_time">date_time()</seealso></c></tag>
<item>
<p>The last (local) time the file was read.</p>
</item>
- <tag><c>mtime = time()</c></tag>
+ <tag><c>mtime = <seealso marker="#type-date_time">date_time()</seealso></c></tag>
<item>
<p>The last (local) time the file was written.</p>
</item>
- <tag><c>ctime = time()</c></tag>
+ <tag><c>ctime = <seealso marker="#type-date_time">date_time()</seealso></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 5ceb82ae41..c0126ed8c1 100644
--- a/lib/kernel/doc/src/gen_sctp.xml
+++ b/lib/kernel/doc/src/gen_sctp.xml
@@ -63,7 +63,6 @@
<item><seealso marker="#options">SCTP SOCKET OPTIONS</seealso></item>
<item><seealso marker="#examples">SCTP EXAMPLES</seealso></item>
<item><seealso marker="#seealso">SEE ALSO</seealso></item>
- <item><seealso marker="#authors">AUTHORS</seealso></item>
</list>
<marker id="types"></marker>
</section>
@@ -80,36 +79,18 @@
</desc>
</datatype>
<datatype>
- <name name="hostname"/>
- </datatype>
- <datatype>
- <name name="ip_address"/>
- <desc>
- <p>Represents an address of an SCTP socket.
- It is a tuple as explained in
- <seealso marker="inet">inet(3)</seealso>.</p>
- </desc>
- </datatype>
- <datatype>
- <name name="port_number"/>
- </datatype>
- <datatype>
- <name name="posix"/>
- <desc>
- <p>See <seealso marker="inet#error_codes">
- inet(3); POSIX Error Codes</seealso>.</p>
- </desc>
- </datatype>
- <datatype>
- <name name="sctp_option"/>
+ <name name="option"/>
<desc>
<p>One of the
<seealso marker="#options">SCTP Socket Options.</seealso></p>
- <marker id="type-sctp_socket"></marker>
</desc>
</datatype>
<datatype>
- <name name="sctp_socket"/>
+ <name name="option_name"/>
+ <desc><marker id="type-sctp_socket"></marker></desc>
+ </datatype>
+ <datatype>
+ <name><marker id="type-sctp_socket">sctp_socket()</marker></name>
<desc>
<p>Socket identifier returned from <c>open/*</c>.</p>
<marker id="exports"></marker>
@@ -175,8 +156,8 @@
#sctp_assoc_change{
state = atom(),
error = atom(),
- outbound_streams = int(),
- inbound_streams = int(),
+ outbound_streams = integer(),
+ inbound_streams = integer(),
assoc_id = assoc_id()
} </pre>
<p>The number of outbound and inbound streams can be set by
@@ -300,6 +281,19 @@
The default <c><anno>IP</anno></c> and <c><anno>Port</anno></c> are <c>any</c>
and <c>0</c>, meaning bind to all local addresses on any
one free port.</p>
+
+ <p>Other options are:</p>
+ <taglist>
+ <tag><c>inet6</c></tag>
+ <item>
+ <p>Set up the socket for IPv6.</p>
+ </item>
+ <tag><c>inet</c></tag>
+ <item>
+ <p>Set up the socket for IPv4. This is the default.</p>
+ </item>
+ </taglist>
+
<p>A default set of socket <seealso marker="#options">options</seealso>
is used. In particular, the socket is opened in
<seealso marker="#option-binary">binary</seealso> and
@@ -350,7 +344,7 @@
#sctp_paddr_change{
addr = {ip_address(),port()},
state = atom(),
- error = int(),
+ error = integer(),
assoc_id = assoc_id()
} </pre>
<p>Indicates change of the status of the peer's IP address given by
@@ -387,7 +381,7 @@
<pre>
#sctp_send_failed{
flags = true | false,
- error = int(),
+ error = integer(),
info = #sctp_sndrcvinfo{},
assoc_id = assoc_id()
data = binary()
@@ -407,7 +401,7 @@
<item>
<pre>
#sctp_adaptation_event{
- adaptation_ind = int(),
+ adaptation_ind = integer(),
assoc_id = assoc_id()
} </pre>
<p>Delivered when a peer sends an Adaptation Layer Indication
@@ -505,7 +499,7 @@
</list>
<marker id="option-buffer"></marker>
</item>
- <tag><c>{buffer, int()}</c></tag>
+ <tag><c>{buffer, integer()}</c></tag>
<item>
<p>Determines the size of the user-level software buffer used by
the SCTP driver. Not to be confused with <c>sndbuf</c>
@@ -515,7 +509,7 @@
In fact, the <c>val(buffer)</c> is automatically set to
the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p>
</item>
- <tag><c>{tos, int()}</c></tag>
+ <tag><c>{tos, integer()}</c></tag>
<item>
<p>Sets the Type-Of-Service field on the IP datagrams being sent,
to the given value, which effectively determines a prioritization
@@ -523,7 +517,7 @@
are system-dependent. TODO: we do not provide
symbolic names for these values yet.</p>
</item>
- <tag><c>{priority, int()}</c></tag>
+ <tag><c>{priority, integer()}</c></tag>
<item>
<p>A protocol-independent equivalent of <c>tos</c> above. Setting
priority implies setting tos as well.</p>
@@ -542,7 +536,7 @@
required for high-throughput servers).</p>
<marker id="option-linger"></marker>
</item>
- <tag><c>{linger, {true|false, int()}</c></tag>
+ <tag><c>{linger, {true|false, integer()}</c></tag>
<item>
<p>Determines the timeout in seconds for flushing unsent data in the
<c>gen_sctp:close/1</c> socket call. If the 1st component of the value
@@ -552,14 +546,14 @@
the flushing time-out in seconds.</p>
<marker id="option-sndbuf"></marker>
</item>
- <tag><c>{sndbuf, int()}</c></tag>
+ <tag><c>{sndbuf, integer()}</c></tag>
<item>
<p>The size, in bytes, of the *kernel* send buffer for this socket.
Sending errors would occur for datagrams larger than
<c>val(sndbuf)</c>. Setting this option also adjusts
the size of the driver buffer (see <c>buffer</c> above).</p>
</item>
- <tag><c>{recbuf, int()}</c></tag>
+ <tag><c>{recbuf, integer()}</c></tag>
<item>
<p>The size, in bytes, of the *kernel* recv buffer for this socket.
Sending errors would occur for datagrams larger than
@@ -571,9 +565,9 @@
<pre>
#sctp_rtoinfo{
assoc_id = assoc_id(),
- initial = int(),
- max = int(),
- min = int()
+ initial = integer(),
+ max = integer(),
+ min = integer()
} </pre>
<p>Determines re-transmission time-out parameters, in milliseconds,
for the association(s) given by <c>assoc_id</c>.
@@ -586,11 +580,11 @@
<pre>
#sctp_assocparams{
assoc_id = assoc_id(),
- asocmaxrxt = int(),
- number_peer_destinations = int(),
- peer_rwnd = int(),
- local_rwnd = int(),
- cookie_life = int()
+ asocmaxrxt = integer(),
+ number_peer_destinations = integer(),
+ peer_rwnd = integer(),
+ local_rwnd = integer(),
+ cookie_life = integer()
} </pre>
<p>Determines association parameters for the association(s) given by
<c>assoc_id</c>. <c>assoc_id = 0</c> (default) indicates
@@ -601,10 +595,10 @@
<item>
<pre>
#sctp_initmsg{
- num_ostreams = int(),
- max_instreams = int(),
- max_attempts = int(),
- max_init_timeo = int()
+ num_ostreams = integer(),
+ max_instreams = integer(),
+ max_attempts = integer(),
+ max_init_timeo = integer()
} </pre>
<p>Determines the default parameters which this socket attempts
to negotiate with its peer while establishing an association with it.
@@ -630,10 +624,11 @@
</list>
<p></p>
</item>
- <tag><c>{sctp_autoclose, int()|infinity}</c></tag>
+ <tag><c>{sctp_autoclose, integer() >= 0}</c></tag>
<item>
<p>Determines the time (in seconds) after which an idle association is
- automatically closed.</p>
+ automatically closed. <c>0</c> means that the association is
+ never automatically closed.</p>
</item>
<tag><c>{sctp_nodelay, true|false}</c></tag>
<item>
@@ -655,7 +650,7 @@
<p>Turns on|off automatic mapping of IPv4 addresses into IPv6 ones
(if the socket address family is AF_INET6).</p>
</item>
- <tag><c>{sctp_maxseg, int()}</c></tag>
+ <tag><c>{sctp_maxseg, integer()}</c></tag>
<item>
<p>Determines the maximum chunk size if message fragmentation is used.
If <c>0</c>, the chunk size is limited by the Path MTU only.</p>
@@ -693,7 +688,7 @@
<marker id="record-sctp_setadaptation"></marker>
<pre>
#sctp_setadaptation{
- adaptation_ind = int()
+ adaptation_ind = integer()
} </pre>
<p>When set, requests that the local endpoint uses the value given by
<c>adaptation_ind</c> as the Adaptation Indication parameter for
@@ -707,10 +702,10 @@
#sctp_paddrparams{
assoc_id = assoc_id(),
address = {IP, Port},
- hbinterval = int(),
- pathmaxrxt = int(),
- pathmtu = int(),
- sackdelay = int(),
+ hbinterval = integer(),
+ pathmaxrxt = integer(),
+ pathmtu = integer(),
+ sackdelay = integer(),
flags = list()
}
IP = ip_address()
@@ -771,14 +766,14 @@
<marker id="record-sctp_sndrcvinfo"></marker>
<pre>
#sctp_sndrcvinfo{
- stream = int(),
- ssn = int(),
+ stream = integer(),
+ ssn = integer(),
flags = list(),
- ppid = int(),
- context = int(),
- timetolive = int(),
- tsn = int(),
- cumtsn = int(),
+ ppid = integer(),
+ context = integer(),
+ timetolive = integer(),
+ tsn = integer(),
+ cumtsn = integer(),
assoc_id = assoc_id()
} </pre>
<p><c>#sctp_sndrcvinfo{}</c> is used both in this socket option, and as
@@ -853,7 +848,7 @@
<pre>
#sctp_assoc_value{
assoc_id = assoc_id(),
- assoc_value = int()
+ assoc_value = integer()
} </pre>
<p>Rarely used. Determines the ACK time
(given by <c>assoc_value</c> in milliseconds) for
@@ -866,12 +861,12 @@
#sctp_status{
assoc_id = assoc_id(),
state = atom(),
- rwnd = int(),
- unackdata = int(),
- penddata = int(),
- instrms = int(),
- outstrms = int(),
- fragmentation_point = int(),
+ rwnd = integer(),
+ unackdata = integer(),
+ penddata = integer(),
+ instrms = integer(),
+ outstrms = integer(),
+ fragmentation_point = integer(),
primary = #sctp_paddrinfo{}
} </pre>
<p>This option is read-only. It determines the status of
@@ -946,10 +941,10 @@
assoc_id = assoc_id(),
address = {IP, Port},
state = inactive | active,
- cwnd = int(),
- srtt = int(),
- rto = int(),
- mtu = int()
+ cwnd = integer(),
+ srtt = integer(),
+ rto = integer(),
+ mtu = integer()
}
IP = ip_address()
Port = port_number() </pre>
@@ -990,7 +985,7 @@
server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback,
is_integer(Port) -&gt;
- {ok,S} = gen_sctp:open([{ip,IP},{port,Port}],[{recbuf,65536}]),
+ {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]),
io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]),
ok = gen_sctp:listen(S, true),
server_loop(S).
@@ -1119,7 +1114,6 @@ client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) -&gt;
<seealso marker="gen_udp">gen_udp(3)</seealso>,
<url href="http://www.rfc-archive.org/getrfc.php?rfc=2960">RFC2960</url> (Stream Control Transmission Protocol),
<url href="http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-13">Sockets API Extensions for SCTP.</url></p>
- <marker id="authors"></marker>
</section>
</erlref>
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index f1d42d9faa..8a5d40bb16 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -37,7 +37,7 @@
binary and closing the connection:</p>
<code type="none">
client() ->
- SomeHostInNet = "localhost" % to make it runnable on one machine
+ SomeHostInNet = "localhost", % to make it runnable on one machine
{ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
[binary, {packet, 0}]),
ok = gen_tcp:send(Sock, "Some Data"),
@@ -65,25 +65,16 @@ do_recv(Sock, Bs) ->
<datatypes>
<datatype>
- <name name="hostname"/>
+ <name name="option"/>
</datatype>
<datatype>
- <name name="ip_address"/>
- <desc>
- <p>Represents an address of a TCP socket.
- It is a tuple as explained in
- <seealso marker="inet">inet(3)</seealso>.</p>
- </desc>
+ <name name="option_name"/>
</datatype>
<datatype>
- <name name="port_number"/>
+ <name name="connect_option"/>
</datatype>
<datatype>
- <name name="posix"/>
- <desc>
- <p>See <seealso marker="inet#error_codes">
- inet(3); POSIX Error Codes</seealso>.</p>
- </desc>
+ <name name="listen_option"/>
</datatype>
<datatype>
<name><marker id="type-socket">socket()</marker></name>
@@ -122,7 +113,7 @@ do_recv(Sock, Bs) ->
<item>
<p>Specify which local port number to use.</p>
</item>
- <tag><c>{fd, int()}</c></tag>
+ <tag><c>{fd, integer() >= 0}</c></tag>
<item>
<p>If a socket has somehow been connected without using
<c>gen_tcp</c>, use this option to pass the file
@@ -196,6 +187,10 @@ do_recv(Sock, Bs) ->
<p>If the host has several network interfaces, this option
specifies which one to listen on.</p>
</item>
+ <tag><c>{port, Port}</c></tag>
+ <item>
+ <p>Specify which local port number to use.</p>
+ </item>
<tag><c>{fd, Fd}</c></tag>
<item>
<p>If a socket has somehow been connected without using
diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml
index c0e783f508..daa9b7d887 100644
--- a/lib/kernel/doc/src/gen_udp.xml
+++ b/lib/kernel/doc/src/gen_udp.xml
@@ -36,25 +36,10 @@
<datatypes>
<datatype>
- <name name="hostname"/>
+ <name name="option"/>
</datatype>
<datatype>
- <name name="ip_address"/>
- <desc>
- <p>Represents an address of a TCP socket.
- It is a tuple as explained in
- <seealso marker="inet">inet(3)</seealso>.</p>
- </desc>
- </datatype>
- <datatype>
- <name name="port_number"/>
- </datatype>
- <datatype>
- <name name="posix"/>
- <desc>
- <p>See <seealso marker="inet#error_codes">
- inet(3); POSIX Error Codes</seealso>.</p>
- </desc>
+ <name name="option_name"/>
</datatype>
<datatype>
<name><marker id="type-socket">socket()</marker></name>
@@ -87,7 +72,7 @@
<p>If the host has several network interfaces, this option
specifies which one to use.</p>
</item>
- <tag><c>{fd, int()}</c></tag>
+ <tag><c>{fd, integer() >= 0}</c></tag>
<item>
<p>If a socket has somehow been opened without using
<c>gen_udp</c>, use this option to pass the file
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index fd843b00d9..b36c28e027 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -105,6 +105,9 @@ fe80::204:acff:fe17:bf38
<name name="ip6_address"/>
</datatype>
<datatype>
+ <name name="port_number"/>
+ </datatype>
+ <datatype>
<name name="posix"/>
<desc><p>An atom which is named from the Posix error codes
used in Unix, and in the runtime libraries of most
@@ -119,7 +122,7 @@ fe80::204:acff:fe17:bf38
</desc>
</datatype>
<datatype>
- <name name="family_option"/>
+ <name name="address_family"/>
</datatype>
</datatypes>
@@ -250,26 +253,15 @@ fe80::204:acff:fe17:bf38
</func>
<func>
- <name>getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name>
+ <name name="getopts" arity="2"/>
<fsummary>Get one or more options for a socket</fsummary>
- <type>
- <v>Socket = term()</v>
- <v>Options = [Opt | RawOptReq]</v>
- <v>Opt = atom()</v>
- <v>RawOptReq = {raw, Protocol, OptionNum, ValueSpec}</v>
- <v>Protocol = integer()</v>
- <v>OptionNum = integer()</v>
- <v>ValueSpec = ValueSize | ValueBin</v>
- <v>ValueSize = integer()</v>
- <v>ValueBin = binary()</v>
- <v>OptionValues = [{Opt, Val} | {raw, Protocol, OptionNum, ValueBin}]</v>
- </type>
<type name="socket_getopt"/>
+ <type name="socket_setopt"/>
<desc>
<p>Gets one or more options for a socket.
See <seealso marker="#setopts/2">setopts/2</seealso>
for a list of available options.</p>
- <p>The number of elements in the returned <c>OptionValues</c>
+ <p>The number of elements in the returned <c><anno>OptionValues</anno></c>
list does not necessarily correspond to the number of options
asked for. If the operating system fails to support an option,
it is simply left out in the returned list. An error tuple is only
@@ -277,12 +269,12 @@ fe80::204:acff:fe17:bf38
(i.e. the socket is closed or the buffer size in a raw request
is too large). This behavior is kept for backward
compatibility reasons.</p>
- <p>A <c>RawOptReq</c> can be used to get information about
+ <p>A raw option request <c>RawOptReq = {raw, Protocol, OptionNum, ValueSpec}</c> can be used to get information about
socket options not (explicitly) supported by the emulator. The
use of raw socket options makes the code non portable, but
allows the Erlang programmer to take advantage of unusual features
present on the current platform.</p>
- <p>The <c>RawOptReq</c> consists of the tag <c>raw</c> followed
+ <p>The <c>RawOptReq</c> consists of the tag <c>raw</c> followed
by the protocol level, the option number and either a binary
or the size, in bytes, of the
buffer in which the option value is to be stored. A binary
@@ -325,19 +317,14 @@ fe80::204:acff:fe17:bf38
</func>
<func>
- <name>getstat(Socket)</name>
- <name>getstat(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name>
+ <name name="getstat" arity="1"/>
+ <name name="getstat" arity="2"/>
<fsummary>Get one or more statistic options for a socket</fsummary>
- <type>
- <v>Socket = term()</v>
- <v>Options = [Opt]</v>
- <v>OptionValues = [{Opt, Val}]</v>
- <v>&nbsp;Opt, Val -- see below</v>
- </type>
+ <type name="stat_option"/>
<desc>
<p>Gets one or more statistic options for a socket.</p>
- <p><c>getstat(Socket)</c> is equivalent to
- <c>getstat(Socket,&nbsp;[recv_avg,&nbsp;recv_cnt,&nbsp;recv_dvi,&nbsp;recv_max,&nbsp;recv_oct,&nbsp;send_avg,&nbsp;send_cnt,&nbsp;send_dvi,&nbsp;send_max,&nbsp;send_oct])</c></p>
+ <p><c>getstat(<anno>Socket</anno>)</c> is equivalent to
+ <c>getstat(<anno>Socket</anno>,&nbsp;[recv_avg,&nbsp;recv_cnt,&nbsp;recv_dvi,&nbsp;recv_max,&nbsp;recv_oct,&nbsp;send_avg,&nbsp;send_cnt,&nbsp;send_dvi,&nbsp;send_max,&nbsp;send_oct])</c></p>
<p>The following options are available:</p>
<taglist>
<tag><c>recv_avg</c></tag>
@@ -394,12 +381,8 @@ fe80::204:acff:fe17:bf38
</desc>
</func>
<func>
- <name>port(Socket) -> {ok, Port} | {error, any()}</name>
+ <name name="port" arity="1"/>
<fsummary>Return the local port number for a socket</fsummary>
- <type>
- <v>Socket = socket()</v>
- <v>Port = integer()</v>
- </type>
<desc>
<p>Returns the local port number for a socket.</p>
</desc>
@@ -412,16 +395,9 @@ fe80::204:acff:fe17:bf38
</desc>
</func>
<func>
- <name>setopts(Socket, Options) -> ok | {error, posix()}</name>
+ <name name="setopts" arity="2"/>
<fsummary>Set one or more options for a socket</fsummary>
- <type>
- <v>Socket = term()</v>
- <v>Options = [{Opt, Val} | {raw, Protocol, Option, ValueBin}]</v>
- <v>Protocol = integer()</v>
- <v>OptionNum = integer()</v>
- <v>ValueBin = binary()</v>
- <v>&nbsp;Opt, Val -- see below</v>
- </type>
+ <type name="socket_setopt"/>
<desc>
<p>Sets one or more options for a socket. The following options
are available:</p>
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index f92837dfe5..e325443f6c 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -30,6 +30,71 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 2.14.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The send_timeout option in gen_tcp did not work properly
+ in active mode or with {active,once} options. This is now
+ corrected.</p>
+ <p>
+ Own Id: OTP-9145</p>
+ </item>
+ <item>
+ <p>
+ Fixed various typos across the documentation (Thanks to
+ Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9154</p>
+ </item>
+ <item>
+ <p>
+ Fix typo in doc of rpc:pmap/3 (Thanks to Ricardo
+ Catalinas Jim�nez)</p>
+ <p>
+ Own Id: OTP-9168</p>
+ </item>
+ <item>
+ <p>
+ A bug in inet_res, the specialized DNS resolver, has been
+ corrected. A late answer with unfortunate timing could
+ cause a runtime exception. Some code cleanup and
+ improvements also tagged along. Thanks to Evegeniy
+ Khramtsov for a pinpointing bug report and bug fix
+ testing.</p>
+ <p>
+ Own Id: OTP-9221 Aux Id: OTP-8712 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Types and specifications have been added. </p>
+ <p>
+ Own Id: OTP-9268</p>
+ </item>
+ <item>
+ <p> Erlang types and specifications are used for
+ documentation. </p>
+ <p>
+ Own Id: OTP-9272</p>
+ </item>
+ <item>
+ <p> Two opaque types that could cause warnings when
+ running Dialyzer have been modified. </p>
+ <p>
+ Own Id: OTP-9337</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 2.14.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/kernel/doc/src/os.xml b/lib/kernel/doc/src/os.xml
index 56fc1834ec..e94119845a 100644
--- a/lib/kernel/doc/src/os.xml
+++ b/lib/kernel/doc/src/os.xml
@@ -126,9 +126,10 @@ DirOut = os:cmd("dir"), % on Win32 platform</code>
</desc>
</func>
<func>
- <name>timestamp() -> {MegaSecs, Secs, MicroSecs}</name>
+ <name>timestamp() -> Timestamp</name>
<fsummary>Returna a timestamp from the OS in the erlang:now/0 format</fsummary>
<type>
+ <v>Timestamp = {MegaSecs, Secs, MicroSecs} = <seealso marker="erts:erlang#type-timestamp">erlang:timestamp()</seealso></v>
<v>MegaSecs = Secs = MicroSecs = integer() >= 0</v>
</type>
<desc>
diff --git a/lib/kernel/src/auth.erl b/lib/kernel/src/auth.erl
index 25c88a4e1d..ac25ab958c 100644
--- a/lib/kernel/src/auth.erl
+++ b/lib/kernel/src/auth.erl
@@ -58,7 +58,7 @@ start_link() ->
%%--Deprecated interface------------------------------------------------
-spec is_auth(Node) -> 'yes' | 'no' when
- Node :: Node :: node().
+ Node :: node().
is_auth(Node) ->
case net_adm:ping(Node) of
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index b0f99305f2..882e9625fe 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -82,7 +82,8 @@
%% add_pathsa([Dir]) -> ok
%% add_pathsz([Dir]) -> ok
%% del_path(Dir) -> boolean() | {error, bad_name}
-%% replace_path(Name, Dir) -> true | replace_path_error()
+%% replace_path(Name, Dir) -> true | {error, bad_directory | bad_name
+%% | {badarg,_}}
%% load_file(Module) -> {module, Module} | {error, What :: atom()}
%% load_abs(File) -> {module, Module} | {error, What :: atom()}
%% load_abs(File, Module) -> {module, Module} | {error, What :: atom()}
@@ -113,11 +114,16 @@
%% Some types for basic exported functions of this module
%%----------------------------------------------------------------------------
--type load_error_rsn() :: 'badfile' | 'native_code' | 'nofile' | 'not_purged'
- | 'sticky_directory'. % for some functions only
--type load_ret() :: {'error', load_error_rsn()} | {'module', atom()}.
+-type load_error_rsn() :: 'badfile'
+ | 'native_code'
+ | 'nofile'
+ | 'not_purged'
+ | 'on_load'
+ | 'sticky_directory'.
+-type load_ret() :: {'error', What :: load_error_rsn()}
+ | {'module', Module :: module()}.
-type loaded_ret_atoms() :: 'cover_compiled' | 'preloaded'.
--type loaded_filename() :: file:filename() | loaded_ret_atoms().
+-type loaded_filename() :: (Filename :: file:filename()) | loaded_ret_atoms().
%%----------------------------------------------------------------------------
%% User interface
@@ -127,55 +133,74 @@
objfile_extension() ->
init:objfile_extension().
--spec load_file(Module :: atom()) -> load_ret().
+-spec load_file(Module) -> load_ret() when
+ Module :: module().
load_file(Mod) when is_atom(Mod) ->
call({load_file,Mod}).
--spec ensure_loaded(Module :: atom()) -> load_ret().
+-spec ensure_loaded(Module) -> {module, Module} | {error, What} when
+ Module :: module(),
+ What :: embedded | badfile | native_code | nofile | on_load.
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 :: file:filename()) -> load_ret().
+-spec load_abs(Filename) -> load_ret() when
+ Filename :: file:filename().
load_abs(File) when is_list(File); is_atom(File) -> call({load_abs,File,[]}).
%% XXX Filename is also an atom(), e.g. 'cover_compiled'
--spec load_abs(Filename :: loaded_filename(), Module :: atom()) -> load_ret().
+-spec load_abs(Filename :: loaded_filename(), Module :: module()) -> load_ret().
load_abs(File, M) when (is_list(File) orelse is_atom(File)), is_atom(M) ->
call({load_abs,File,M}).
%% XXX Filename is also an atom(), e.g. 'cover_compiled'
--spec load_binary(Module :: atom(), Filename :: loaded_filename(), Binary :: binary()) -> load_ret().
+-spec load_binary(Module, Filename, Binary) ->
+ {module, Module} | {error, What} when
+ Module :: module(),
+ Filename :: loaded_filename(),
+ Binary :: binary(),
+ What :: badarg | load_error_rsn().
load_binary(Mod, File, Bin)
when is_atom(Mod), (is_list(File) orelse is_atom(File)), is_binary(Bin) ->
call({load_binary,Mod,File,Bin}).
--spec load_native_partial(Module :: atom(), Binary :: binary()) -> load_ret().
+-spec load_native_partial(Module :: module(), Binary :: binary()) -> load_ret().
load_native_partial(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
call({load_native_partial,Mod,Bin}).
--spec load_native_sticky(Module :: atom(), Binary :: binary(), WholeModule :: 'false' | binary()) -> load_ret().
+-spec load_native_sticky(Module :: module(), Binary :: binary(), WholeModule :: 'false' | binary()) -> load_ret().
load_native_sticky(Mod, Bin, WholeModule)
when is_atom(Mod), is_binary(Bin),
(is_binary(WholeModule) orelse WholeModule =:= false) ->
call({load_native_sticky,Mod,Bin,WholeModule}).
--spec delete(Module :: atom()) -> boolean().
+-spec delete(Module) -> boolean() when
+ Module :: module().
delete(Mod) when is_atom(Mod) -> call({delete,Mod}).
--spec purge(Module :: atom()) -> boolean().
+-spec purge(Module) -> boolean() when
+ Module :: module().
purge(Mod) when is_atom(Mod) -> call({purge,Mod}).
--spec soft_purge(Module :: atom()) -> boolean().
+-spec soft_purge(Module) -> boolean() when
+ Module :: module().
soft_purge(Mod) when is_atom(Mod) -> call({soft_purge,Mod}).
--spec is_loaded(Module :: atom()) -> {'file', loaded_filename()} | 'false'.
+-spec is_loaded(Module) -> {'file', Loaded} | false when
+ Module :: module(),
+ Loaded :: loaded_filename().
is_loaded(Mod) when is_atom(Mod) -> call({is_loaded,Mod}).
--spec get_object_code(Module :: atom()) -> {atom(), binary(), file:filename()} | 'error'.
+-spec get_object_code(Module) -> {Module, Binary, Filename} | error when
+ Module :: module(),
+ Binary :: binary(),
+ Filename :: file:filename().
get_object_code(Mod) when is_atom(Mod) -> call({get_object_code, Mod}).
--spec all_loaded() -> [{atom(), loaded_filename()}].
+-spec all_loaded() -> [{Module, Loaded}] when
+ Module :: module(),
+ Loaded :: loaded_filename().
all_loaded() -> call(all_loaded).
-spec stop() -> no_return().
@@ -188,65 +213,86 @@ root_dir() -> call({dir,root_dir}).
lib_dir() -> call({dir,lib_dir}).
%% XXX is_list() is for backwards compatibility -- take out in future version
--spec lib_dir(App :: atom()) -> file:filename() | {'error', 'bad_name'}.
+-spec lib_dir(Name) -> file:filename() | {'error', 'bad_name'} when
+ Name :: atom().
lib_dir(App) when is_atom(App) ; is_list(App) -> call({dir,{lib_dir,App}}).
--spec lib_dir(App :: atom(), SubDir :: atom()) -> file:filename() | {'error', 'bad_name'}.
+-spec lib_dir(Name, SubDir) -> file:filename() | {'error', 'bad_name'} when
+ Name :: atom(),
+ SubDir :: atom().
lib_dir(App, SubDir) when is_atom(App), is_atom(SubDir) -> call({dir,{lib_dir,App,SubDir}}).
-spec compiler_dir() -> file:filename().
compiler_dir() -> call({dir,compiler_dir}).
%% XXX is_list() is for backwards compatibility -- take out in future version
--spec priv_dir(App :: atom()) -> file:filename() | {'error', 'bad_name'}.
+-spec priv_dir(Name) -> file:filename() | {'error', 'bad_name'} when
+ Name :: atom().
priv_dir(App) when is_atom(App) ; is_list(App) -> call({dir,{priv_dir,App}}).
--spec stick_dir(Directory :: file:filename()) -> 'ok' | 'error'.
+-spec stick_dir(Dir) -> 'ok' | 'error' when
+ Dir :: file:filename().
stick_dir(Dir) when is_list(Dir) -> call({stick_dir,Dir}).
--spec unstick_dir(Directory :: file:filename()) -> 'ok' | 'error'.
+-spec unstick_dir(Dir) -> 'ok' | 'error' when
+ Dir :: file:filename().
unstick_dir(Dir) when is_list(Dir) -> call({unstick_dir,Dir}).
--spec stick_mod(Module :: atom()) -> 'true'.
+-spec stick_mod(Module :: module()) -> 'true'.
stick_mod(Mod) when is_atom(Mod) -> call({stick_mod,Mod}).
--spec unstick_mod(Module :: atom()) -> 'true'.
+-spec unstick_mod(Module :: module()) -> 'true'.
unstick_mod(Mod) when is_atom(Mod) -> call({unstick_mod,Mod}).
--spec is_sticky(Module :: atom()) -> boolean().
+-spec is_sticky(Module) -> boolean() when
+ Module :: module().
is_sticky(Mod) when is_atom(Mod) -> call({is_sticky,Mod}).
--spec set_path(Directories :: [file:filename()]) ->
- 'true' | {'error', 'bad_directory' | 'bad_path'}.
+-spec set_path(Path) -> 'true' | {'error', What} when
+ Path :: [Dir :: file:filename()],
+ What :: 'bad_directory' | 'bad_path'.
set_path(PathList) when is_list(PathList) -> call({set_path,PathList}).
--spec get_path() -> [file:filename()].
+-spec get_path() -> Path when
+ Path :: [Dir :: file:filename()].
get_path() -> call(get_path).
-type add_path_ret() :: 'true' | {'error', 'bad_directory'}.
--spec add_path(Directory :: file:filename()) -> add_path_ret().
+-spec add_path(Dir) -> add_path_ret() when
+ Dir :: file:filename().
add_path(Dir) when is_list(Dir) -> call({add_path,last,Dir}).
--spec add_pathz(Directory :: file:filename()) -> add_path_ret().
+-spec add_pathz(Dir) -> add_path_ret() when
+ Dir :: file:filename().
add_pathz(Dir) when is_list(Dir) -> call({add_path,last,Dir}).
--spec add_patha(Directory :: file:filename()) -> add_path_ret().
+-spec add_patha(Dir) -> add_path_ret() when
+ Dir :: file:filename().
add_patha(Dir) when is_list(Dir) -> call({add_path,first,Dir}).
--spec add_paths(Directories :: [file:filename()]) -> 'ok'.
+-spec add_paths(Dirs) -> 'ok' when
+ Dirs :: [Dir :: file:filename()].
add_paths(Dirs) when is_list(Dirs) -> call({add_paths,last,Dirs}).
--spec add_pathsz(Directories :: [file:filename()]) -> 'ok'.
+-spec add_pathsz(Dirs) -> 'ok' when
+ Dirs :: [Dir :: file:filename()].
add_pathsz(Dirs) when is_list(Dirs) -> call({add_paths,last,Dirs}).
--spec add_pathsa(Directories :: [file:filename()]) -> 'ok'.
+-spec add_pathsa(Dirs) -> 'ok' when
+ Dirs :: [Dir :: file:filename()].
add_pathsa(Dirs) when is_list(Dirs) -> call({add_paths,first,Dirs}).
--spec del_path(Name :: file:filename() | atom()) -> boolean() | {'error', 'bad_name'}.
+-spec del_path(NameOrDir) -> boolean() | {'error', What} when
+ NameOrDir :: Name | Dir,
+ Name :: atom(),
+ Dir :: file:filename(),
+ What :: 'bad_name'.
del_path(Name) when is_list(Name) ; is_atom(Name) -> call({del_path,Name}).
--type replace_path_error() :: {'error', 'bad_directory' | 'bad_name' | {'badarg',_}}.
--spec replace_path(Name:: atom(), Dir :: file:filename()) -> 'true' | replace_path_error().
+-spec replace_path(Name, Dir) -> 'true' | {'error', What} when
+ Name:: atom(),
+ Dir :: file:filename(),
+ What :: 'bad_directory' | 'bad_name' | {'badarg',_}.
replace_path(Name, Dir) when (is_atom(Name) orelse is_list(Name)),
(is_atom(Dir) orelse is_list(Dir)) ->
call({replace_path,Name,Dir}).
@@ -351,10 +397,9 @@ get_mode(Flags) ->
%% In that case return the name of the file which contains
%% the loaded object code
--type which_ret_atoms() :: loaded_ret_atoms() | 'non_existing'.
-
--spec which(Module :: atom()) -> file:filename() | which_ret_atoms().
-
+-spec which(Module) -> Which when
+ Module :: module(),
+ Which :: file:filename() | loaded_ret_atoms() | non_existing.
which(Module) when is_atom(Module) ->
case is_loaded(Module) of
false ->
@@ -394,9 +439,9 @@ which(File, Base, [Directory|Tail]) ->
%% Search the code path for a specific file. Try to locate
%% it in the code path cache if possible.
--spec where_is_file(Filename :: file:filename()) ->
- 'non_existing' | file:filename().
-
+-spec where_is_file(Filename) -> non_existing | Absname when
+ Filename :: file:filename(),
+ Absname :: file:filename().
where_is_file(File) when is_list(File) ->
case call({is_cached,File}) of
no ->
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 4a1fc7df34..85bbff9cc3 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1379,8 +1379,12 @@ absname_vr([[X, $:]|Name], _, _AbsBase) ->
%% Kill all processes running code from *old* Module, and then purge the
%% module. Return true if any processes killed, else false.
-do_purge(Mod) ->
- do_purge(processes(), to_atom(Mod), false).
+do_purge(Mod0) ->
+ Mod = to_atom(Mod0),
+ case erlang:check_old_code(Mod) of
+ false -> false;
+ true -> do_purge(processes(), Mod, false)
+ end.
do_purge([P|Ps], Mod, Purged) ->
case erlang:check_process_code(P, Mod) of
@@ -1399,16 +1403,19 @@ do_purge([], Mod, Purged) ->
Purged.
%% do_soft_purge(Module)
-%% Purge old code only if no procs remain that run old code
+%% Purge old code only if no procs remain that run old code.
%% Return true in that case, false if procs remain (in this
%% case old code is not purged)
do_soft_purge(Mod) ->
- catch do_soft_purge(processes(), Mod).
+ case erlang:check_old_code(Mod) of
+ false -> true;
+ true -> do_soft_purge(processes(), Mod)
+ end.
do_soft_purge([P|Ps], Mod) ->
case erlang:check_process_code(P, Mod) of
- true -> throw(false);
+ true -> false;
false -> do_soft_purge(Ps, Mod)
end;
do_soft_purge([], Mod) ->
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index f1a8aa9f77..5e4e1b0ba8 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -100,15 +100,7 @@
| 'enotblk' | 'enotdir' | 'enotsup' | 'enxio' | 'eperm'
| 'epipe' | 'erofs' | 'espipe' | 'esrch' | 'estale'
| 'exdev'.
--type bindings() :: erl_eval:binding_struct().
-
--type date() :: {Year :: pos_integer(),
- Month :: pos_integer(),
- Day ::pos_integer()}.
--type time() :: {Hour :: non_neg_integer(),
- Minute :: non_neg_integer(),
- Second :: non_neg_integer()}.
--type date_time() :: {date(), time()}.
+-type date_time() :: calendar:datetime().
-type posix_file_advise() :: 'normal' | 'sequential' | 'random'
| 'no_reuse' | 'will_need' | 'dont_need'.
@@ -920,7 +912,7 @@ eval(File) ->
-spec eval(Filename, Bindings) -> ok | {error, Reason} when
Filename :: name(),
- Bindings :: bindings(),
+ Bindings :: erl_eval:binding_struct(),
Reason :: posix() | badarg | terminated | system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}.
@@ -948,7 +940,7 @@ path_eval(Path, File) ->
{ok, FullName} | {error, Reason} when
Path :: [Dir :: name()],
Filename :: name(),
- Bindings :: bindings(),
+ Bindings :: erl_eval:binding_struct(),
FullName :: filename(),
Reason :: posix() | badarg | terminated | system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}.
@@ -979,7 +971,7 @@ script(File) ->
-spec script(Filename, Bindings) -> {ok, Value} | {error, Reason} when
Filename :: name(),
- Bindings :: bindings(),
+ Bindings :: erl_eval:binding_struct(),
Value :: term(),
Reason :: posix() | badarg | terminated | system_limit
| {Line :: integer(), Mod :: module(), Term :: term()}.
@@ -1010,7 +1002,7 @@ path_script(Path, File) ->
{ok, Value, FullName} | {error, Reason} when
Path :: [Dir :: name()],
Filename :: name(),
- Bindings :: bindings(),
+ Bindings :: erl_eval:binding_struct(),
Value :: term(),
FullName :: filename(),
Reason :: posix() | badarg | terminated | system_limit
diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl
index 004f03f231..c9a849eca7 100644
--- a/lib/kernel/src/gen_sctp.erl
+++ b/lib/kernel/src/gen_sctp.erl
@@ -34,54 +34,84 @@
-export([controlling_process/2]).
-opaque assoc_id() :: term().
--type hostname() :: inet:hostname().
--type ip_address() :: inet:ip_address().
--type port_number() :: 0..65535.
--type posix() :: inet:posix().
--type sctp_option() ::
- {mode, list | binary} | list | binary
- | {active, true | false | once}
- | {buffer, non_neg_integer()}
- | {tos, integer()}
- | {priority, integer()}
- | {dontroute, boolean()}
- | {reuseaddr, boolean()}
- | {linger, {boolean(), non_neg_integer()}}
- | {sndbuf, non_neg_integer()}
- | {recbuf, non_neg_integer()}
- | {sctp_rtoinfo, #sctp_rtoinfo{}}
- | {sctp_associnfo, #sctp_assocparams{}}
- | {sctp_initmsg, #sctp_initmsg{}}
- | {sctp_autoclose, timeout()}
- | {sctp_nodelay, boolean()}
- | {sctp_disable_fragments, boolean()}
- | {sctp_i_want_mapped_v4_addr, boolean()}
- | {sctp_maxseg, non_neg_integer()}
- | {sctp_primary_addr, #sctp_prim{}}
- | {sctp_set_peer_primary_addr, #sctp_setpeerprim{}}
- | {sctp_adaptation_layer, #sctp_setadaptation{}}
- | {sctp_peer_addr_params, #sctp_paddrparams{}}
- | {sctp_default_send_param, #sctp_sndrcvinfo{}}
- | {sctp_events, #sctp_event_subscribe{}}
- | {sctp_delayed_ack_time, #sctp_assoc_value{}}
- | {sctp_status, #sctp_status{}}
- | {sctp_get_peer_addr_info, #sctp_paddrinfo{}}.
--opaque sctp_socket() :: port().
-
--spec open() -> {ok, Socket} | {error, posix()} when
+-type option() ::
+ {active, true | false | once} |
+ {buffer, non_neg_integer()} |
+ {dontroute, boolean()} |
+ {linger, {boolean(), non_neg_integer()}} |
+ {mode, list | binary} | list | binary |
+ {priority, non_neg_integer()} |
+ {recbuf, non_neg_integer()} |
+ {reuseaddr, boolean()} |
+ {sctp_adaptation_layer, #sctp_setadaptation{}} |
+ {sctp_associnfo, #sctp_assocparams{}} |
+ {sctp_autoclose, non_neg_integer()} |
+ {sctp_default_send_param, #sctp_sndrcvinfo{}} |
+ {sctp_delayed_ack_time, #sctp_assoc_value{}} |
+ {sctp_disable_fragments, boolean()} |
+ {sctp_events, #sctp_event_subscribe{}} |
+ {sctp_get_peer_addr_info, #sctp_paddrinfo{}} |
+ {sctp_i_want_mapped_v4_addr, boolean()} |
+ {sctp_initmsg, #sctp_initmsg{}} |
+ {sctp_maxseg, non_neg_integer()} |
+ {sctp_nodelay, boolean()} |
+ {sctp_peer_addr_params, #sctp_paddrparams{}} |
+ {sctp_primary_addr, #sctp_prim{}} |
+ {sctp_rtoinfo, #sctp_rtoinfo{}} |
+ {sctp_set_peer_primary_addr, #sctp_setpeerprim{}} |
+ {sctp_status, #sctp_status{}} |
+ {sndbuf, non_neg_integer()} |
+ {tos, non_neg_integer()}.
+-type option_name() ::
+ active |
+ buffer |
+ dontroute |
+ linger |
+ mode |
+ priority |
+ recbuf |
+ reuseaddr |
+ sctp_adaptation_layer |
+ sctp_associnfo |
+ sctp_autoclose |
+ sctp_default_send_param |
+ sctp_delayed_ack_time |
+ sctp_disable_fragments |
+ sctp_events |
+ sctp_get_peer_addr_info |
+ sctp_i_want_mapped_v4_addr |
+ sctp_initmsg |
+ sctp_maxseg |
+ sctp_nodelay |
+ sctp_peer_addr_params |
+ sctp_primary_addr |
+ sctp_rtoinfo |
+ sctp_set_peer_primary_addr |
+ sctp_status |
+ sndbuf |
+ tos.
+-type sctp_socket() :: port().
+
+-export_type([option/0, option_name/0]).
+
+-spec open() -> {ok, Socket} | {error, inet:posix()} when
Socket :: sctp_socket().
open() ->
open([]).
--spec open(Port) -> {ok, Socket} | {error, posix()} when
- Port :: port_number(),
+-spec open(Port) -> {ok, Socket} | {error, inet:posix()} when
+ Port :: inet:port_number(),
Socket :: sctp_socket();
- (Opts) -> {ok, Socket} | {error, posix()} when
+ (Opts) -> {ok, Socket} | {error, inet:posix()} when
Opts :: [Opt],
- Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(),
- IP :: ip_address() | any | loopback,
- Port :: port_number(),
+ Opt :: {ip,IP}
+ | {ifaddr,IP}
+ | inet:address_family()
+ | {port,Port}
+ | option(),
+ IP :: inet:ip_address() | any | loopback,
+ Port :: inet:port_number(),
Socket :: sctp_socket().
open(Opts) when is_list(Opts) ->
@@ -98,11 +128,15 @@ open(Port) when is_integer(Port) ->
open(X) ->
erlang:error(badarg, [X]).
--spec open(Port, Opts) -> {ok, Socket} | {error, posix()} when
+-spec open(Port, Opts) -> {ok, Socket} | {error, inet:posix()} when
Opts :: [Opt],
- Opt :: {ip,IP} | {ifaddr,IP} | {port,Port} | sctp_option(),
- IP :: ip_address() | any | loopback,
- Port :: port_number(),
+ Opt :: {ip,IP}
+ | {ifaddr,IP}
+ | inet:address_family()
+ | {port,Port}
+ | option(),
+ IP :: inet:ip_address() | any | loopback,
+ Port :: inet:port_number(),
Socket :: sctp_socket().
open(Port, Opts) when is_integer(Port), is_list(Opts) ->
@@ -110,7 +144,7 @@ open(Port, Opts) when is_integer(Port), is_list(Opts) ->
open(Port, Opts) ->
erlang:error(badarg, [Port,Opts]).
--spec close(Socket) -> ok | {error, posix()} when
+-spec close(Socket) -> ok | {error, inet:posix()} when
Socket :: sctp_socket().
close(S) when is_port(S) ->
@@ -138,22 +172,22 @@ listen(S, Flag) when is_port(S), is_boolean(Flag) ->
listen(S, Flag) ->
erlang:error(badarg, [S,Flag]).
--spec connect(Socket, Addr, Port, Opts) -> {ok, Assoc} | {error, posix()} when
+-spec connect(Socket, Addr, Port, Opts) -> {ok, Assoc} | {error, inet:posix()} when
Socket :: sctp_socket(),
- Addr :: ip_address() | hostname(),
- Port :: port_number(),
- Opts :: [Opt :: sctp_option()],
+ Addr :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Opts :: [Opt :: option()],
Assoc :: #sctp_assoc_change{}.
connect(S, Addr, Port, Opts) ->
connect(S, Addr, Port, Opts, infinity).
-spec connect(Socket, Addr, Port, Opts, Timeout) ->
- {ok, Assoc} | {error, posix()} when
+ {ok, Assoc} | {error, inet:posix()} when
Socket :: sctp_socket(),
- Addr :: ip_address() | hostname(),
- Port :: port_number(),
- Opts :: [Opt :: sctp_option()],
+ Addr :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Opts :: [Opt :: option()],
Timeout :: timeout(),
Assoc :: #sctp_assoc_change{}.
@@ -166,21 +200,21 @@ connect(S, Addr, Port, Opts, Timeout) ->
end.
-spec connect_init(Socket, Addr, Port, Opts) ->
- ok | {error, posix()} when
+ ok | {error, inet:posix()} when
Socket :: sctp_socket(),
- Addr :: ip_address() | hostname(),
- Port :: port_number(),
- Opts :: [sctp_option()].
+ Addr :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Opts :: [option()].
connect_init(S, Addr, Port, Opts) ->
connect_init(S, Addr, Port, Opts, infinity).
-spec connect_init(Socket, Addr, Port, Opts, Timeout) ->
- ok | {error, posix()} when
+ ok | {error, inet:posix()} when
Socket :: sctp_socket(),
- Addr :: ip_address() | hostname(),
- Port :: port_number(),
- Opts :: [sctp_option()],
+ Addr :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Opts :: [option()],
Timeout :: timeout().
connect_init(S, Addr, Port, Opts, Timeout) ->
@@ -232,7 +266,7 @@ eof(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
eof(S, Assoc) ->
erlang:error(badarg, [S,Assoc]).
--spec abort(Socket, Assoc) -> ok | {error, posix()} when
+-spec abort(Socket, Assoc) -> ok | {error, inet:posix()} when
Socket :: sctp_socket(),
Assoc :: #sctp_assoc_change{}.
@@ -294,13 +328,13 @@ send(S, AssocChange, Stream, Data) ->
-spec recv(Socket) -> {ok, {FromIP, FromPort, AncData, Data}}
| {error, Reason} when
Socket :: sctp_socket(),
- FromIP :: ip_address(),
- FromPort :: port_number(),
+ FromIP :: inet:ip_address(),
+ FromPort :: inet:port_number(),
AncData :: [#sctp_sndrcvinfo{}],
Data :: binary() | string() | #sctp_sndrcvinfo{}
| #sctp_assoc_change{} | #sctp_paddr_change{}
| #sctp_adaptation_event{},
- Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{}
+ Reason :: inet:posix() | #sctp_send_failed{} | #sctp_paddr_change{}
| #sctp_pdapi_event{} | #sctp_remote_error{}
| #sctp_shutdown_event{}.
@@ -311,13 +345,13 @@ recv(S) ->
| {error, Reason} when
Socket :: sctp_socket(),
Timeout :: timeout(),
- FromIP :: ip_address(),
- FromPort :: port_number(),
+ FromIP :: inet:ip_address(),
+ FromPort :: inet:port_number(),
AncData :: [#sctp_sndrcvinfo{}],
Data :: binary() | string() | #sctp_sndrcvinfo{}
| #sctp_assoc_change{} | #sctp_paddr_change{}
| #sctp_adaptation_event{},
- Reason :: posix() | #sctp_send_failed{} | #sctp_paddr_change{}
+ Reason :: inet:posix() | #sctp_send_failed{} | #sctp_paddr_change{}
| #sctp_pdapi_event{} | #sctp_remote_error{}
| #sctp_shutdown_event{}.
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index bee61ca84a..df326b59d6 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -28,34 +28,108 @@
-include("inet_int.hrl").
--type hostname() :: inet:hostname().
--type ip_address() :: inet:ip_address().
--type port_number() :: 0..65535.
--type posix() :: inet:posix().
+-type option() ::
+ {active, true | false | once} |
+ {bit8, clear | set | on | off} |
+ {buffer, non_neg_integer()} |
+ {delay_send, boolean()} |
+ {deliver, port | term} |
+ {dontroute, boolean()} |
+ {exit_on_close, boolean()} |
+ {header, non_neg_integer()} |
+ {high_watermark, non_neg_integer()} |
+ {keepalive, boolean()} |
+ {linger, {boolean(), non_neg_integer()}} |
+ {low_watermark, non_neg_integer()} |
+ {mode, list | binary} | list | binary |
+ {nodelay, boolean()} |
+ {packet,
+ 0 | 1 | 2 | 4 | raw | sunrm | asn1 |
+ cdr | fcgi | line | tpkt | http | httph | http_bin | httph_bin } |
+ {packet_size, non_neg_integer()} |
+ {priority, non_neg_integer()} |
+ {raw,
+ Protocol :: non_neg_integer(),
+ OptionNum :: non_neg_integer(),
+ ValueBin :: binary()} |
+ {recbuf, non_neg_integer()} |
+ {reuseaddr, boolean()} |
+ {send_timeout, non_neg_integer() | infinity} |
+ {send_timeout_close, boolean()} |
+ {sndbuf, non_neg_integer()} |
+ {tos, non_neg_integer()}.
+-type option_name() ::
+ active |
+ bit8 |
+ buffer |
+ delay_send |
+ deliver |
+ dontroute |
+ exit_on_close |
+ header |
+ high_watermark |
+ keepalive |
+ linger |
+ low_watermark |
+ mode |
+ nodelay |
+ packet |
+ packet_size |
+ priority |
+ {raw,
+ Protocol :: non_neg_integer(),
+ OptionNum :: non_neg_integer(),
+ ValueSpec :: (ValueSize :: non_neg_integer()) |
+ (ValueBin :: binary())} |
+ recbuf |
+ reuseaddr |
+ send_timeout |
+ send_timeout_close |
+ sndbuf |
+ tos.
+-type connect_option() ::
+ {ip, inet:ip_address()} |
+ {fd, Fd :: non_neg_integer()} |
+ {ifaddr, inet:ip_address()} |
+ inet:address_family() |
+ {port, inet:port_number()} |
+ {tcp_module, module()} |
+ option().
+-type listen_option() ::
+ {ip, inet:ip_address()} |
+ {fd, Fd :: non_neg_integer()} |
+ {ifaddr, inet:ip_address()} |
+ inet:address_family() |
+ {port, inet:port_number()} |
+ {backlog, B :: non_neg_integer()} |
+ {tcp_module, module()} |
+ option().
-type socket() :: port().
+-export_type([option/0, option_name/0, connect_option/0, listen_option/0]).
+
%%
%% Connect a socket
%%
-spec connect(Address, Port, Options) -> {ok, Socket} | {error, Reason} when
- Address :: ip_address() | hostname(),
- Port :: port_number(),
- Options :: [Opt :: term()],
+ Address :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Options :: [connect_option()],
Socket :: socket(),
- Reason :: posix().
+ Reason :: inet:posix().
connect(Address, Port, Opts) ->
connect(Address,Port,Opts,infinity).
-spec connect(Address, Port, Options, Timeout) ->
{ok, Socket} | {error, Reason} when
- Address :: ip_address() | hostname(),
- Port :: port_number(),
- Options :: [Opt :: term()],
+ Address :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
+ Options :: [connect_option()],
Timeout :: timeout(),
Socket :: socket(),
- Reason :: posix().
+ Reason :: inet:posix().
connect(Address, Port, Opts, Time) ->
Timer = inet:start_timer(Time),
@@ -97,10 +171,10 @@ try_connect([], _Port, _Opts, _Timer, _Mod, Err) ->
%%
-spec listen(Port, Options) -> {ok, ListenSocket} | {error, Reason} when
- Port :: port_number(),
- Options :: [Opt :: term()],
+ Port :: inet:port_number(),
+ Options :: [listen_option()],
ListenSocket :: socket(),
- Reason :: posix().
+ Reason :: inet:posix().
listen(Port, Opts) ->
Mod = mod(Opts, undefined),
@@ -119,7 +193,7 @@ listen(Port, Opts) ->
-spec accept(ListenSocket) -> {ok, Socket} | {error, Reason} when
ListenSocket :: socket(),
Socket :: socket(),
- Reason :: closed | timeout | posix().
+ Reason :: closed | timeout | inet:posix().
accept(S) ->
case inet_db:lookup_socket(S) of
@@ -133,7 +207,7 @@ accept(S) ->
ListenSocket :: socket(),
Timeout :: timeout(),
Socket :: socket(),
- Reason :: closed | timeout | posix().
+ Reason :: closed | timeout | inet:posix().
accept(S, Time) when is_port(S) ->
case inet_db:lookup_socket(S) of
@@ -150,7 +224,7 @@ accept(S, Time) when is_port(S) ->
-spec shutdown(Socket, How) -> ok | {error, Reason} when
Socket :: socket(),
How :: read | write | read_write,
- Reason :: posix().
+ Reason :: inet:posix().
shutdown(S, How) when is_port(S) ->
case inet_db:lookup_socket(S) of
@@ -177,7 +251,7 @@ close(S) ->
-spec send(Socket, Packet) -> ok | {error, Reason} when
Socket :: socket(),
Packet :: string() | binary(),
- Reason :: posix().
+ Reason :: inet:posix().
send(S, Packet) when is_port(S) ->
case inet_db:lookup_socket(S) of
@@ -195,7 +269,7 @@ send(S, Packet) when is_port(S) ->
Socket :: socket(),
Length :: non_neg_integer(),
Packet :: string() | binary() | HttpPacket,
- Reason :: closed | posix(),
+ Reason :: closed | inet:posix(),
HttpPacket :: term().
recv(S, Length) when is_port(S) ->
@@ -211,7 +285,7 @@ recv(S, Length) when is_port(S) ->
Length :: non_neg_integer(),
Timeout :: timeout(),
Packet :: string() | binary() | HttpPacket,
- Reason :: closed | posix(),
+ Reason :: closed | inet:posix(),
HttpPacket :: term().
recv(S, Length, Time) when is_port(S) ->
@@ -237,7 +311,7 @@ unrecv(S, Data) when is_port(S) ->
-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when
Socket :: socket(),
Pid :: pid(),
- Reason :: closed | not_owner | posix().
+ Reason :: closed | not_owner | inet:posix().
controlling_process(S, NewOwner) ->
case inet_db:lookup_socket(S) of
diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl
index 7d14615c04..554f4ece4a 100644
--- a/lib/kernel/src/gen_udp.erl
+++ b/lib/kernel/src/gen_udp.erl
@@ -25,25 +25,74 @@
-include("inet_int.hrl").
--type hostname() :: inet:hostname().
--type ip_address() :: inet:ip_address().
--type port_number() :: 0..65535.
--type posix() :: inet:posix().
+-type option() ::
+ {active, true | false | once} |
+ {add_membership, {inet:ip_address(), inet:ip_address()}} |
+ {broadcast, boolean()} |
+ {buffer, non_neg_integer()} |
+ {deliver, port | term} |
+ {dontroute, boolean()} |
+ {drop_membership, {inet:ip_address(), inet:ip_address()}} |
+ {header, non_neg_integer()} |
+ {mode, list | binary} | list | binary |
+ {multicast_if, inet:ip_address()} |
+ {multicast_loop, boolean()} |
+ {multicast_ttl, non_neg_integer()} |
+ {priority, non_neg_integer()} |
+ {raw,
+ Protocol :: non_neg_integer(),
+ OptionNum :: non_neg_integer(),
+ ValueBin :: binary()} |
+ {read_packets, non_neg_integer()} |
+ {recbuf, non_neg_integer()} |
+ {reuseaddr, boolean()} |
+ {sndbuf, non_neg_integer()} |
+ {tos, non_neg_integer()}.
+-type option_name() ::
+ active |
+ broadcast |
+ buffer |
+ deliver |
+ dontroute |
+ header |
+ mode |
+ multicast_if |
+ multicast_loop |
+ multicast_ttl |
+ priority |
+ {raw,
+ Protocol :: non_neg_integer(),
+ OptionNum :: non_neg_integer(),
+ ValueSpec :: (ValueSize :: non_neg_integer()) |
+ (ValueBin :: binary())} |
+ read_packets |
+ recbuf |
+ reuseaddr |
+ sndbuf |
+ tos.
-type socket() :: port().
+-export_type([option/0, option_name/0]).
+
-spec open(Port) -> {ok, Socket} | {error, Reason} when
- Port :: port_number(),
+ Port :: inet:port_number(),
Socket :: socket(),
- Reason :: posix().
+ Reason :: inet:posix().
open(Port) ->
open(Port, []).
-spec open(Port, Opts) -> {ok, Socket} | {error, Reason} when
- Port :: port_number(),
- Opts :: [Opt :: term()],
+ Port :: inet:port_number(),
+ Opts :: [Option],
+ Option :: {ip, inet:ip_address()}
+ | {fd, non_neg_integer()}
+ | {ifaddr, inet:ip_address()}
+ | inet:address_family()
+ | {port, inet:port_number()}
+ | option(),
Socket :: socket(),
- Reason :: posix().
+ Reason :: inet:posix().
open(Port, Opts) ->
Mod = mod(Opts, undefined),
@@ -58,10 +107,10 @@ close(S) ->
-spec send(Socket, Address, Port, Packet) -> ok | {error, Reason} when
Socket :: socket(),
- Address :: ip_address() | hostname(),
- Port :: port_number(),
+ Address :: inet:ip_address() | inet:hostname(),
+ Port :: inet:port_number(),
Packet :: string() | binary(),
- Reason :: not_owner | posix().
+ Reason :: not_owner | inet:posix().
send(S, Address, Port, Packet) when is_port(S) ->
case inet_db:lookup_socket(S) of
@@ -92,10 +141,10 @@ send(S, Packet) when is_port(S) ->
{ok, {Address, Port, Packet}} | {error, Reason} when
Socket :: socket(),
Length :: non_neg_integer(),
- Address :: ip_address(),
- Port :: port_number(),
+ Address :: inet:ip_address(),
+ Port :: inet:port_number(),
Packet :: string() | binary(),
- Reason :: not_owner | posix().
+ Reason :: not_owner | inet:posix().
recv(S,Len) when is_port(S), is_integer(Len) ->
case inet_db:lookup_socket(S) of
@@ -110,10 +159,10 @@ recv(S,Len) when is_port(S), is_integer(Len) ->
Socket :: socket(),
Length :: non_neg_integer(),
Timeout :: timeout(),
- Address :: ip_address(),
- Port :: port_number(),
+ Address :: inet:ip_address(),
+ Port :: inet:port_number(),
Packet :: string() | binary(),
- Reason :: not_owner | posix().
+ Reason :: not_owner | inet:posix().
recv(S,Len,Time) when is_port(S) ->
case inet_db:lookup_socket(S) of
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 5649188c38..48a6f3db65 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -63,8 +63,9 @@
%% timer interface
-export([start_timer/1, timeout/1, timeout/2, stop_timer/1]).
--export_type([family_option/0, hostent/0, hostname/0, ip4_address/0,
- ip6_address/0, ip_address/0, posix/0, socket/0]).
+-export_type([address_family/0, hostent/0, hostname/0, ip4_address/0,
+ ip6_address/0, ip_address/0, posix/0, socket/0,
+ port_number/0]).
%% imports
-import(lists, [append/1, duplicate/2, filter/2, foldl/3]).
@@ -87,98 +88,15 @@
-type ip6_address() :: {0..65535,0..65535,0..65535,0..65535,
0..65535,0..65535,0..65535,0..65535}.
-type ip_address() :: ip4_address() | ip6_address().
--type ip_port() :: 0..65535.
+-type port_number() :: 0..65535.
-type posix() :: exbadport | exbadseq | file:posix().
-type socket() :: port().
-type socket_setopt() ::
- {'raw', non_neg_integer(), non_neg_integer(), binary()} |
- %% TCP/UDP options
- {'reuseaddr', boolean()} |
- {'keepalive', boolean()} |
- {'dontroute', boolean()} |
- {'linger', {boolean(), non_neg_integer()}} |
- {'broadcast', boolean()} |
- {'sndbuf', non_neg_integer()} |
- {'recbuf', non_neg_integer()} |
- {'priority', non_neg_integer()} |
- {'tos', non_neg_integer()} |
- {'nodelay', boolean()} |
- {'multicast_ttl', non_neg_integer()} |
- {'multicast_loop', boolean()} |
- {'multicast_if', ip_address()} |
- {'add_membership', {ip_address(), ip_address()}} |
- {'drop_membership', {ip_address(), ip_address()}} |
- {'header', non_neg_integer()} |
- {'buffer', non_neg_integer()} |
- {'active', boolean() | 'once'} |
- {'packet',
- 0 | 1 | 2 | 4 | 'raw' | 'sunrm' | 'asn1' |
- 'cdr' | 'fcgi' | 'line' | 'tpkt' | 'http' | 'httph' | 'http_bin' | 'httph_bin' } |
- {'mode', 'list' | 'binary'} |
- {'port', 'port', 'term'} |
- {'exit_on_close', boolean()} |
- {'low_watermark', non_neg_integer()} |
- {'high_watermark', non_neg_integer()} |
- {'bit8', 'clear' | 'set' | 'on' | 'off'} |
- {'send_timeout', non_neg_integer() | 'infinity'} |
- {'send_timeout_close', boolean()} |
- {'delay_send', boolean()} |
- {'packet_size', non_neg_integer()} |
- {'read_packets', non_neg_integer()} |
- %% SCTP options
- {'sctp_rtoinfo', #sctp_rtoinfo{}} |
- {'sctp_associnfo', #sctp_assocparams{}} |
- {'sctp_initmsg', #sctp_initmsg{}} |
- {'sctp_nodelay', boolean()} |
- {'sctp_autoclose', non_neg_integer()} |
- {'sctp_disable_fragments', boolean()} |
- {'sctp_i_want_mapped_v4_addr', boolean()} |
- {'sctp_maxseg', non_neg_integer()} |
- {'sctp_primary_addr', #sctp_prim{}} |
- {'sctp_set_peer_primary_addr', #sctp_setpeerprim{}} |
- {'sctp_adaptation_layer', #sctp_setadaptation{}} |
- {'sctp_peer_addr_params', #sctp_paddrparams{}} |
- {'sctp_default_send_param', #sctp_sndrcvinfo{}} |
- {'sctp_events', #sctp_event_subscribe{}} |
- {'sctp_delayed_ack_time', #sctp_assoc_value{}}.
+ gen_sctp:option() | gen_tcp:option() | gen_udp:option().
-type socket_getopt() ::
- {'raw',
- non_neg_integer(), non_neg_integer(), binary()|non_neg_integer()} |
- %% TCP/UDP options
- 'reuseaddr' | 'keepalive' | 'dontroute' | 'linger' |
- 'broadcast' | 'sndbuf' | 'recbuf' | 'priority' | 'tos' | 'nodelay' |
- 'multicast_ttl' | 'multicast_loop' | 'multicast_if' |
- 'add_membership' | 'drop_membership' |
- 'header' | 'buffer' | 'active' | 'packet' | 'mode' | 'port' |
- 'exit_on_close' | 'low_watermark' | 'high_watermark' | 'bit8' |
- 'send_timeout' | 'send_timeout_close' |
- 'delay_send' | 'packet_size' | 'read_packets' |
- %% SCTP options
- {'sctp_status', #sctp_status{}} |
- 'sctp_get_peer_addr_info' |
- {'sctp_get_peer_addr_info', #sctp_status{}} |
- 'sctp_rtoinfo' |
- {'sctp_rtoinfo', #sctp_rtoinfo{}} |
- 'sctp_associnfo' |
- {'sctp_associnfo', #sctp_assocparams{}} |
- 'sctp_initmsg' |
- {'sctp_initmsg', #sctp_initmsg{}} |
- 'sctp_nodelay' | 'sctp_autoclose' | 'sctp_disable_fragments' |
- 'sctp_i_want_mapped_v4_addr' | 'sctp_maxseg' |
- {'sctp_primary_addr', #sctp_prim{}} |
- {'sctp_set_peer_primary_addr', #sctp_setpeerprim{}} |
- 'sctp_adaptation_layer' |
- {'sctp_adaptation_layer', #sctp_setadaptation{}} |
- {'sctp_peer_addr_params', #sctp_paddrparams{}} |
- 'sctp_default_send_param' |
- {'sctp_default_send_param', #sctp_sndrcvinfo{}} |
- 'sctp_events' |
- {'sctp_events', #sctp_event_subscribe{}} |
- 'sctp_delayed_ack_time' |
- {'sctp_delayed_ack_time', #sctp_assoc_value{}}.
-
+ gen_sctp:option_name() | gen_tcp:option_name() | gen_udp:option_name().
-type ether_address() :: [0..255].
-type if_setopt() ::
@@ -196,7 +114,7 @@
'addr' | 'broadaddr' | 'dstaddr' |
'mtu' | 'netmask' | 'flags' |'hwaddr'.
--type family_option() :: 'inet' | 'inet6'.
+-type address_family() :: 'inet' | 'inet6'.
-type protocol_option() :: 'tcp' | 'udp' | 'sctp'.
-type stat_option() ::
'recv_cnt' | 'recv_max' | 'recv_avg' | 'recv_oct' | 'recv_dvi' |
@@ -229,7 +147,7 @@ close(Socket) ->
peername(Socket) ->
prim_inet:peername(Socket).
--spec setpeername(Socket :: socket(), Address :: {ip_address(), ip_port()}) ->
+-spec setpeername(Socket :: socket(), Address :: {ip_address(), port_number()}) ->
'ok' | {'error', any()}.
setpeername(Socket, {IP,Port}) ->
@@ -246,7 +164,7 @@ setpeername(Socket, undefined) ->
sockname(Socket) ->
prim_inet:sockname(Socket).
--spec setsockname(Socket :: socket(), Address :: {ip_address(), ip_port()}) ->
+-spec setsockname(Socket :: socket(), Address :: {ip_address(), port_number()}) ->
'ok' | {'error', any()}.
setsockname(Socket, {IP,Port}) ->
@@ -254,7 +172,9 @@ setsockname(Socket, {IP,Port}) ->
setsockname(Socket, undefined) ->
prim_inet:setsockname(Socket, undefined).
--spec port(Socket :: socket()) -> {'ok', ip_port()} | {'error', any()}.
+-spec port(Socket) -> {'ok', Port} | {'error', any()} when
+ Socket :: socket(),
+ Port :: port_number().
port(Socket) ->
case prim_inet:sockname(Socket) of
@@ -268,16 +188,18 @@ port(Socket) ->
send(Socket, Packet) ->
prim_inet:send(Socket, Packet).
--spec setopts(Socket :: socket(), Opts :: [socket_setopt()]) ->
- 'ok' | {'error', posix()}.
+-spec setopts(Socket, Options) -> ok | {error, posix()} when
+ Socket :: socket(),
+ Options :: [socket_setopt()].
setopts(Socket, Opts) ->
prim_inet:setopts(Socket, Opts).
-spec getopts(Socket, Options) ->
- {'ok', [socket_setopt()]} | {'error', posix()} when
+ {'ok', OptionValues} | {'error', posix()} when
Socket :: socket(),
- Options :: [socket_getopt()].
+ Options :: [socket_getopt()],
+ OptionValues :: [socket_setopt()].
getopts(Socket, Opts) ->
prim_inet:getopts(Socket, Opts).
@@ -419,14 +341,19 @@ gethostname() ->
gethostname(Socket) ->
prim_inet:gethostname(Socket).
--spec getstat(Socket :: socket()) ->
- {'ok', [{stat_option(), integer()}]} | {'error', posix()}.
+-spec getstat(Socket) ->
+ {ok, OptionValues} | {error, posix()} when
+ Socket :: socket(),
+ OptionValues :: [{stat_option(), integer()}].
getstat(Socket) ->
prim_inet:getstat(Socket, stats()).
--spec getstat(Socket :: socket(), Statoptions :: [stat_option()]) ->
- {'ok', [{stat_option(), integer()}]} | {'error', posix()}.
+-spec getstat(Socket, Options) ->
+ {ok, OptionValues} | {error, posix()} when
+ Socket :: socket(),
+ Options :: [stat_option()],
+ OptionValues :: [{stat_option(), integer()}].
getstat(Socket,What) ->
prim_inet:getstat(Socket, What).
@@ -441,14 +368,14 @@ gethostbyname(Name) ->
-spec gethostbyname(Hostname, Family) ->
{ok, Hostent} | {error, posix()} when
Hostname :: hostname(),
- Family :: family_option(),
+ Family :: address_family(),
Hostent :: hostent().
gethostbyname(Name,Family) ->
gethostbyname_tm(Name, Family, false).
-spec gethostbyname(Name :: hostname(),
- Family :: family_option(),
+ Family :: address_family(),
Timeout :: non_neg_integer() | 'infinity') ->
{'ok', #hostent{}} | {'error', posix()}.
@@ -527,14 +454,14 @@ getfd(Socket) ->
-spec getaddr(Host, Family) -> {ok, Address} | {error, posix()} when
Host :: ip_address() | hostname(),
- Family :: family_option(),
+ Family :: address_family(),
Address :: ip_address().
getaddr(Address, Family) ->
getaddr(Address, Family, infinity).
-spec getaddr(Host :: ip_address() | hostname(),
- Family :: family_option(),
+ Family :: address_family(),
Timeout :: non_neg_integer() | 'infinity') ->
{'ok', ip_address()} | {'error', posix()}.
@@ -553,14 +480,14 @@ getaddr_tm(Address, Family, Timer) ->
-spec getaddrs(Host, Family) ->
{ok, Addresses} | {error, posix()} when
Host :: ip_address() | hostname(),
- Family :: family_option(),
+ Family :: address_family(),
Addresses :: [ip_address()].
getaddrs(Address, Family) ->
getaddrs(Address, Family, infinity).
-spec getaddrs(Host :: ip_address() | string() | atom(),
- Family :: family_option(),
+ Family :: address_family(),
Timeout :: non_neg_integer() | 'infinity') ->
{'ok', [ip_address()]} | {'error', posix()}.
@@ -570,7 +497,7 @@ getaddrs(Address, Family, Timeout) ->
stop_timer(Timer),
Res.
--spec getservbyport(Port :: ip_port(), Protocol :: atom() | string()) ->
+-spec getservbyport(Port :: port_number(), Protocol :: atom() | string()) ->
{'ok', string()} | {'error', posix()}.
getservbyport(Port, Proto) ->
@@ -584,7 +511,7 @@ getservbyport(Port, Proto) ->
-spec getservbyname(Name :: atom() | string(),
Protocol :: atom() | string()) ->
- {'ok', ip_port()} | {'error', posix()}.
+ {'ok', port_number()} | {'error', posix()}.
getservbyname(Name, Protocol) when is_atom(Name) ->
case inet_udp:open(0, []) of
@@ -1067,7 +994,7 @@ gethostbyaddr_tm_native(Addr, Timer, Opts) ->
-spec open(Fd :: integer(),
Addr :: ip_address(),
- Port :: ip_port(),
+ Port :: port_number(),
Opts :: [socket_setopt()],
Protocol :: protocol_option(),
Family :: 'inet' | 'inet6',
@@ -1108,7 +1035,7 @@ open(Fd, _Addr, _Port, Opts, Protocol, Family, Module) ->
-spec fdopen(Fd :: non_neg_integer(),
Opts :: [socket_setopt()],
Protocol :: protocol_option(),
- Family :: family_option(),
+ Family :: address_family(),
Module :: atom()) ->
{'ok', socket()} | {'error', posix()}.
diff --git a/lib/kernel/src/inet_config.erl b/lib/kernel/src/inet_config.erl
index 2458876326..1ddbdcec25 100644
--- a/lib/kernel/src/inet_config.erl
+++ b/lib/kernel/src/inet_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -44,26 +44,6 @@
%%
-spec init() -> 'ok'.
init() ->
- OsType = os:type(),
- case OsType of
- {ose,_} ->
- case init:get_argument(loader) of
- {ok,[["ose_inet"]]} ->
- %% port already started by prim_loader
- ok;
- _Other ->
- %% Setup reserved port for ose_inet driver (only OSE)
- case catch erlang:open_port({spawn,"ose_inet"}, [binary]) of
- {'EXIT',Why} ->
- error("can't open port for ose_inet: ~p", [Why]);
- OseInetPort ->
- erlang:display({ose_inet_port,OseInetPort})
- end
- end;
- _ ->
- ok
- end,
-
set_hostname(),
%% Note: In shortnames (or non-distributed) mode we don't need to know
@@ -71,6 +51,7 @@ init() ->
%% the user to provide it (by means of inetrc), so we need to look
%% for it ourselves.
+ OsType = os:type(),
do_load_resolv(OsType, erl_dist_mode()),
case OsType of
@@ -226,35 +207,6 @@ do_load_resolv(vxworks, _) ->
load_resolv(Resolv, resolv)
end;
-do_load_resolv({ose,_Type}, _) ->
- inet_db:set_lookup([file, dns]),
- case os:getenv("NAMESERVER") of
- false ->
- case os:getenv("RESOLVFILE") of
- false ->
- erlang:display('Warning: No NAMESERVER or RESOLVFILE specified!'),
- no_resolv;
- Resolv ->
- load_resolv(Resolv, resolv)
- end;
- Ns ->
- {ok,IP} = inet_parse:address(Ns),
- inet_db:add_rc_list([{nameserver,IP}])
- end,
- case os:getenv("DOMAIN") of
- false ->
- no_domain;
- D ->
- ok = inet_db:add_rc_list([{domain,D}])
- end,
- case os:getenv("HOSTSFILE") of
- false ->
- erlang:display('Warning: No HOSTSFILE specified!'),
- no_hosts_file;
- File ->
- load_hosts(File, ose)
- end;
-
do_load_resolv(_, _) ->
inet_db:set_lookup([native]).
diff --git a/lib/kernel/src/inet_dns_record_adts.pl b/lib/kernel/src/inet_dns_record_adts.pl
index b1d8fab939..da50c7114f 100644
--- a/lib/kernel/src/inet_dns_record_adts.pl
+++ b/lib/kernel/src/inet_dns_record_adts.pl
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2009. All Rights Reserved.
+# Copyright Ericsson AB 2009-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -73,6 +73,10 @@ while( my ($Name, $r) = each(%Names)) {
# "@Values" = "V1,V2"...",VN"
my @D = @DATA;
foreach my $line (@D) {
+ # Ignore !name lines
+ if ($line =~ s/^\!(\S+)\s+//) {
+ next if $1 eq $Name;
+ }
my $m = 1;
# For leading * iterate $n times, otherwise once
$line =~ s/^\s*[*]// and $m = $n;
@@ -155,9 +159,9 @@ make_Name() -> \
make_Name(L) when is_list(L) -> \
make_Name(#Record{}, L).
-%% Generate #Record{} with one updated field
-%%
-*make_Name(Field, Value) -> \
+!dns_rr_opt %% Generate #Record{} with one updated field
+!dns_rr_opt %%
+!dns_rr_opt *make_Name(Field, Value) -> \
#Record{Field=Value};
%%
%% Update #Record{} from property list
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 2276ddcd08..59ba408d7a 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -71,7 +71,7 @@
-type dns_class() :: in | chaos | hs | any.
--opaque dns_msg() :: term().
+-type dns_msg() :: term().
-type dns_data() ::
dns_name()
@@ -407,7 +407,7 @@ gethostbyname(Name) ->
-spec gethostbyname(Name, Family) -> {ok, Hostent} | {error, Reason} when
Name :: dns_name(),
Hostent :: inet:hostent(),
- Family :: inet:family_option(),
+ Family :: inet:address_family(),
Reason :: inet:posix() | res_error().
gethostbyname(Name,Family) ->
@@ -418,7 +418,7 @@ gethostbyname(Name,Family) ->
Name :: dns_name(),
Hostent :: inet:hostent(),
Timeout :: timeout(),
- Family :: inet:family_option(),
+ Family :: inet:address_family(),
Reason :: inet:posix() | res_error().
gethostbyname(Name,Family,Timeout) ->
diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl
index be35f99ed2..e214ffa404 100644
--- a/lib/kernel/src/rpc.erl
+++ b/lib/kernel/src/rpc.erl
@@ -662,9 +662,10 @@ async_call(Node, Mod, Fun, Args) ->
ReplyTo ! {self(), {promise_reply, R}} %% self() is key
end).
--spec yield(Key) -> {value, Val} | timeout when
+-spec yield(Key) -> Res | {badrpc, Reason} when
Key :: key(),
- Val :: (Res :: term()) | {badrpc, Reason :: term()}.
+ Res :: term(),
+ Reason :: term().
yield(Key) when is_pid(Key) ->
{value,R} = do_yield(Key, infinity),
diff --git a/lib/kernel/src/seq_trace.erl b/lib/kernel/src/seq_trace.erl
index ea5da2de1c..a90b7b07c8 100644
--- a/lib/kernel/src/seq_trace.erl
+++ b/lib/kernel/src/seq_trace.erl
@@ -45,7 +45,7 @@
%%---------------------------------------------------------------------------
--opaque token() :: {integer(), boolean(), _, _, _}.
+-type token() :: {integer(), boolean(), _, _, _}.
-spec set_token(Token) -> PreviousToken | 'ok' when
Token :: [] | token(),
PreviousToken :: [] | token().
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 95517ffd6a..82bc3fc6d1 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2010. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index d8a5519195..b734d7fd98 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -400,6 +400,7 @@ open_fd(Config) when is_list(Config) ->
{ok,S1} = gen_udp:open(0),
{ok,P2} = inet:port(S1),
{ok,FD} = prim_inet:getfd(S1),
+ {error,einval} = gen_udp:open(P2, [inet6, {fd,FD}]),
{ok,S2} = gen_udp:open(P2, [{fd,FD}]),
{ok,S3} = gen_udp:open(0),
{ok,P3} = inet:port(S3),
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index e7b71cc168..8be265e79d 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.14.4
+KERNEL_VSN = 2.14.5
diff --git a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
index 21174340d1..ae41a216f4 100644
--- a/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
+++ b/lib/mnesia/doc/src/Mnesia_chap7.xmlsrc
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml
index 2a2c7d3a9f..7a8f796cee 100644
--- a/lib/mnesia/doc/src/mnesia.xml
+++ b/lib/mnesia/doc/src/mnesia.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2010</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index f1c362261a..7f50dc049a 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -38,7 +38,39 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.4.18</title>
+ <section><title>Mnesia 4.4.19</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Mnesia could crash if mnesia:add_table_index/2 was
+ invoked before the table was loaded on all nodes.</p>
+ <p>
+ Own Id: OTP-9285 Aux Id: seq11844 </p>
+ </item>
+ <item>
+ <p>
+ Add {majority, boolean()} per-table option.</p>
+ <p>
+ With {majority, true} set for a table, write transactions
+ will abort if they cannot commit to a majority of the
+ nodes that have a copy of the table. Currently, the
+ implementation hooks into the prepare_commit, and forces
+ an asymmetric transaction if the commit set affects any
+ table with the majority flag set. In the commit itself,
+ the transaction will abort if it cannot satisfy the
+ majority requirement for all tables involved in the
+ transaction.(Thanks to Ulf Wiger)</p>
+ <p>
+ Own Id: OTP-9304</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.4.18</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/mnesia/src/mnesia.hrl b/lib/mnesia/src/mnesia.hrl
index 26537815a3..2375b72d59 100644
--- a/lib/mnesia/src/mnesia.hrl
+++ b/lib/mnesia/src/mnesia.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index 6e9d4727ec..d1c65f97e8 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index d61ce940c3..11e311d72d 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -90,7 +90,7 @@
Datatype - USER_INT | USER_SMALL_INT | {USER_DECIMAL, Precision, Scale} |
{USER_NMERIC, Precision, Scale} | {USER_CHAR, Max} | {USER_VARCHAR, Max} |
{USER_WVARCHAR, Max} | {USER_FLOAT, Precision} | USER_REAL | USER_DOUBLE |
- USER_TIMESTAMP
+ USER_TIMESTAMP | {USER_WLONGVARCHAR, Max}
Scale - integer
Precision - integer
Max - integer
@@ -173,7 +173,7 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows,
db_state *state);
static void encode_column_dyn(db_column column, int column_nr,
db_state *state);
-static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
+static void encode_data_type(SQLSMALLINT sql_type, SQLINTEGER size,
SQLSMALLINT decimal_digits, db_state *state);
static Boolean decode_params(db_state *state, byte *buffer, int *index, param_array **params,
int i, int j);
@@ -221,7 +221,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
int num_param_values, db_state* state);
static void init_param_statement(int cols,
- int num_param_values,
+ SQLLEN num_param_values,
db_state *state,
param_status *status);
@@ -435,7 +435,7 @@ static db_result_msg db_connect(byte *args, db_state *state)
diagnos diagnos;
byte *connStrIn;
int erl_auto_commit_mode, erl_trace_driver,
- use_srollable_cursors, tuple_row_state, binary_strings;
+ use_srollable_cursors, tuple_row_state, binary_strings;
erl_auto_commit_mode = args[0];
erl_trace_driver = args[1];
@@ -757,8 +757,9 @@ static db_result_msg db_select(byte *args, db_state *state)
static db_result_msg db_param_query(byte *buffer, db_state *state)
{
byte *sql;
- db_result_msg msg;
- int i, num_param_values, ver = 0,
+ db_result_msg msg;
+ SQLLEN num_param_values;
+ int i, ver = 0,
erl_type = 0, index = 0, size = 0, cols = 0;
long long_num_param_values;
param_status param_status;
@@ -785,7 +786,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
ei_decode_long(buffer, &index, &long_num_param_values);
- num_param_values = (int)long_num_param_values;
+ num_param_values = (SQLLEN)long_num_param_values;
ei_decode_list_header(buffer, &index, &cols);
@@ -1002,12 +1003,16 @@ static db_result_msg encode_result(db_state *state)
db_result_msg msg;
int elements, update, num_of_rows = 0;
char *atom;
+ diagnos diagnos;
msg = encode_empty_message();
if(!sql_success(SQLNumResultCols(statement_handle(state),
&num_of_columns))) {
- DO_EXIT(EXIT_COLS);
+ diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
+ msg = encode_error_message(diagnos.error_msg);
+ clean_state(state);
+ return msg;
}
if (num_of_columns == 0) {
@@ -1021,7 +1026,10 @@ static db_result_msg encode_result(db_state *state)
}
if(!sql_success(SQLRowCount(statement_handle(state), &RowCountPtr))) {
- DO_EXIT(EXIT_ROWS);
+ diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state));
+ msg = encode_error_message(diagnos.error_msg);
+ clean_state(state);
+ return msg;
}
if(param_query(state) && update) {
@@ -1220,7 +1228,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
&nullable)))
DO_EXIT(EXIT_DESC);
- if(sql_type == SQL_LONGVARCHAR || sql_type == SQL_LONGVARBINARY)
+ if(sql_type == SQL_LONGVARCHAR || sql_type == SQL_LONGVARBINARY || sql_type == SQL_WLONGVARCHAR)
size = MAXCOLSIZE;
(columns(state)[i]).type.decimal_digits = dec_digits;
@@ -1452,7 +1460,7 @@ static void encode_column_dyn(db_column column, int column_nr,
}
}
-static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
+static void encode_data_type(SQLSMALLINT sql_type, SQLINTEGER size,
SQLSMALLINT decimal_digits, db_state *state)
{
switch(sql_type) {
@@ -1529,6 +1537,11 @@ static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
case SQL_LONGVARCHAR:
ei_x_encode_atom(&dynamic_buffer(state), "SQL_LONGVARCHAR");
break;
+ case SQL_WLONGVARCHAR:
+ ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
+ ei_x_encode_atom(&dynamic_buffer(state), "sql_wlongvarchar");
+ ei_x_encode_long(&dynamic_buffer(state), size);
+ break;
case SQL_VARBINARY:
ei_x_encode_atom(&dynamic_buffer(state), "SQL_VARBINARY");
break;
@@ -2007,7 +2020,7 @@ static void init_driver(int erl_auto_commit_mode, int erl_trace_driver,
db_state *state)
{
- int auto_commit_mode, trace_driver;
+ SQLLEN auto_commit_mode, trace_driver;
if(erl_auto_commit_mode == ON) {
auto_commit_mode = SQL_AUTOCOMMIT_ON;
@@ -2057,7 +2070,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
ei_decode_long(buffer, index, &user_type);
- params->type.strlen_or_indptr = (SQLINTEGER)NULL;
+ params->type.strlen_or_indptr = (SQLLEN)NULL;
params->type.strlen_or_indptr_array = NULL;
params->type.decimal_digits = (SQLINTEGER)0;
@@ -2131,10 +2144,14 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
break;
case USER_WCHAR:
case USER_WVARCHAR:
- if(user_type == USER_WCHAR) {
- params->type.sql = SQL_WCHAR;
- } else {
- params->type.sql = SQL_WVARCHAR;
+ case USER_WLONGVARCHAR:
+ switch (user_type) {
+ case USER_WCHAR:
+ params->type.sql = SQL_WCHAR; break;
+ case USER_WVARCHAR:
+ params->type.sql = SQL_WVARCHAR; break;
+ default:
+ params->type.sql = SQL_WLONGVARCHAR; break;
}
ei_decode_long(buffer, index, &length);
/* Max string length + string terminator */
@@ -2206,7 +2223,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
}
-static void init_param_statement(int cols, int num_param_values,
+static void init_param_statement(int cols, SQLLEN num_param_values,
db_state *state, param_status *status)
{
int i;
@@ -2234,11 +2251,11 @@ static void init_param_statement(int cols, int num_param_values,
DO_EXIT(EXIT_PARAM_ARRAY);
}
- /* Note the (int *) cast is correct as the API function SQLSetStmtAttr
+ /* Note the (SQLLEN *) cast is correct as the API function SQLSetStmtAttr
takes either an interger or a pointer depending on the attribute */
if(!sql_success(SQLSetStmtAttr(statement_handle(state),
SQL_ATTR_PARAMSET_SIZE,
- (int *)num_param_values,
+ (SQLLEN *)num_param_values,
0))) {
DO_EXIT(EXIT_PARAM_ARRAY);
}
@@ -2300,6 +2317,7 @@ static db_result_msg map_sql_2_c_column(db_column* column)
break;
case SQL_WCHAR:
case SQL_WVARCHAR:
+ case SQL_WLONGVARCHAR:
column -> type.len = (column -> type.col_size + 1)*sizeof(SQLWCHAR);
column -> type.c = SQL_C_WCHAR;
column -> type.strlen_or_indptr = SQL_NTS;
@@ -2308,21 +2326,21 @@ static db_result_msg map_sql_2_c_column(db_column* column)
case SQL_DECIMAL:
map_dec_num_2_c_column(&(column -> type), column -> type.col_size,
column -> type.decimal_digits);
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_TINYINT:
case SQL_INTEGER:
case SQL_SMALLINT:
column -> type.len = sizeof(SQLINTEGER);
column -> type.c = SQL_C_SLONG;
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
column -> type.len = sizeof(double);
column -> type.c = SQL_C_DOUBLE;
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
@@ -2334,17 +2352,17 @@ static db_result_msg map_sql_2_c_column(db_column* column)
case SQL_TYPE_TIMESTAMP:
column -> type.len = sizeof(TIMESTAMP_STRUCT);
column -> type.c = SQL_C_TYPE_TIMESTAMP;
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_BIGINT:
column -> type.len = DEC_NUM_LENGTH;
column -> type.c = SQL_C_CHAR;
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_BIT:
column -> type.len = sizeof(byte);
column -> type.c = SQL_C_BIT;
- column -> type.strlen_or_indptr = (SQLINTEGER)NULL;
+ column -> type.strlen_or_indptr = (SQLLEN)NULL;
break;
case SQL_UNKNOWN_TYPE:
msg = encode_error_message("Unknown column type");
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 3e2b22ab7d..314fbf32c6 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -115,6 +115,7 @@
#define USER_WCHAR 12
#define USER_WVARCHAR 13
#define USER_TIMESTAMP 14
+#define USER_WLONGVARCHAR 15
/*------------------------ TYPDEFS ----------------------------------*/
diff --git a/lib/odbc/doc/src/databases.xml b/lib/odbc/doc/src/databases.xml
index a6ba0e5245..09f5a5af5b 100644
--- a/lib/odbc/doc/src/databases.xml
+++ b/lib/odbc/doc/src/databases.xml
@@ -205,6 +205,10 @@ when p >= 16 </cell>
<cell align="left" valign="middle">String | Binary (configurable)</cell>
</row>
<row>
+ <cell align="left" valign="middle">SQL_WLONGVARCHAR(size) </cell>
+ <cell align="left" valign="middle">Unicode binary encoded as UTF16 little endian.</cell>
+ </row>
+ <row>
<cell align="left" valign="middle">SQL_BINARY</cell>
<cell align="left" valign="middle">String | Binary (configurable)</cell>
</row>
diff --git a/lib/odbc/doc/src/odbc.xml b/lib/odbc/doc/src/odbc.xml
index 70d8cfbe22..11ca97f743 100644
--- a/lib/odbc/doc/src/odbc.xml
+++ b/lib/odbc/doc/src/odbc.xml
@@ -102,7 +102,7 @@
{sql_decimal, precision(), scale()} |
{sql_numeric, precision(), scale()} |
{sql_char, size()} | {sql_wchar, size()} | {sql_varchar, size()} | {sql_wvarchar, size()}| {sql_float, precision()} |
- {sql_float, precision()} | sql_real | sql_double | sql_bit | atom()
+ {sql_wlongvarchar, size()} | {sql_float, precision()} | sql_real | sql_double | sql_bit | atom()
</code>
<code type="none">
precision() = integer() </code>
diff --git a/lib/odbc/src/odbc.appup.src b/lib/odbc/src/odbc.appup.src
index 2a6667ccd3..f3a3af8c29 100644
--- a/lib/odbc/src/odbc.appup.src
+++ b/lib/odbc/src/odbc.appup.src
@@ -1,8 +1,10 @@
%% -*- erlang -*-
{"%VSN%",
[
- {"2.10.9", [{restart_application, ssl}]}
+ {"2.10.10", [{restart_application, odbc}]},
+ {"2.10.9", [{restart_application, odbc}]}
],
[
- {"2.10.9", [{restart_application, ssl}]}
+ {"2.10.10", [{restart_application, odbc}]},
+ {"2.10.9", [{restart_application, odbc}]}
]}.
diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl
index 83d9f33102..68497292db 100644
--- a/lib/odbc/src/odbc.erl
+++ b/lib/odbc/src/odbc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -431,7 +431,7 @@ init(Args) ->
erlang:monitor(process, ClientPid),
- Inet = case gen_tcp:listen(0, [inet6]) of
+ Inet = case gen_tcp:listen(0, [inet6, {ip, loopback}]) of
{ok, Dummyport} ->
gen_tcp:close(Dummyport),
inet6;
@@ -925,6 +925,9 @@ fix_params({{sql_wchar, Max}, InOut, Values}) ->
fix_params({{sql_wvarchar, Max}, InOut, Values}) ->
NewValues = string_terminate(Values),
{?USER_WVARCHAR, Max, fix_inout(InOut), NewValues};
+fix_params({{sql_wlongvarchar, Max}, InOut, Values}) ->
+ NewValues = string_terminate(Values),
+ {?USER_WLONGVARCHAR, Max, fix_inout(InOut), NewValues};
fix_params({{sql_float, Precision}, InOut, Values}) ->
{?USER_FLOAT, Precision, fix_inout(InOut), Values};
fix_params({sql_real, InOut, Values}) ->
diff --git a/lib/odbc/src/odbc_internal.hrl b/lib/odbc/src/odbc_internal.hrl
index aa60120f9a..c0e7d9657b 100644
--- a/lib/odbc/src/odbc_internal.hrl
+++ b/lib/odbc/src/odbc_internal.hrl
@@ -72,6 +72,7 @@
-define(USER_WCHAR, 12).
-define(USER_WVARCHAR, 13).
-define(USER_TIMESTAMP, 14).
+-define(USER_WLONGVARCHAR, 15).
%% INPUT & OUTPUT TYPE
-define(IN, 0).
diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile
index ec2bcc67b5..bc6449242e 100644
--- a/lib/odbc/test/Makefile
+++ b/lib/odbc/test/Makefile
@@ -34,7 +34,8 @@ MODULES= \
odbc_test_lib \
oracle \
sqlserver \
- postgres
+ postgres \
+ mysql
EBIN = .
diff --git a/lib/odbc/test/mysql.erl b/lib/odbc/test/mysql.erl
new file mode 100644
index 0000000000..c990793213
--- /dev/null
+++ b/lib/odbc/test/mysql.erl
@@ -0,0 +1,277 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2011-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(mysql).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%-------------------------------------------------------------------------
+connection_string() ->
+ case test_server:os_type() of
+ {unix, linux} ->
+ "DSN=MySQL;Database=odbctest;Uid=odbctest;Pwd=gurka;CHARSET=utf8;SSTMT=SET NAMES 'utf8';";
+ {unix, sunos} ->
+ solaris_str();
+ {unix, darwin} ->
+ "DSN=MySQLMac;Database=odbctest;Uid=odbctest;Pwd=gurka;CHARSET=utf8;SSTMT=SET NAMES 'utf8';"
+ end.
+
+solaris_str() ->
+ case erlang:system_info(system_architecture) of
+ "sparc" ++ _ ->
+ "DSN=MySQLSolaris10;Database=odbctest;Uid=odbctest;Pwd=gurka;CHARSET=utf8;SSTMT=SET NAMES 'utf8';";
+ "i386" ++ _ ->
+ "DSN=MySQLSolaris10i386;Database=odbctest;Uid=odbctest;Pwd=gurka;CHARSET=utf8;SSTMT=SET NAMES 'utf8';"
+ end.
+
+%-------------------------------------------------------------------------
+insert_result() ->
+ {selected,["ID","DATA"],[{1,"bar"}]}.
+
+update_result() ->
+ {selected,["ID","DATA"],[{1,"foo"}]}.
+
+selected_ID(N, next) ->
+ {selected,["ID"],[{N}]};
+
+selected_ID(_, _) ->
+ {error, driver_does_not_support_function}.
+
+selected_next_N(1)->
+ {selected,["ID"],
+ [{1},
+ {2},
+ {3}]};
+
+selected_next_N(2)->
+ {selected,["ID"],
+ [{4},
+ {5}]}.
+
+selected_relative_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_absolute_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_list_rows() ->
+ {selected,["ID", "DATA"],[[1, "bar"],[2,"foo"]]}.
+
+first_list_rows() ->
+ {error, driver_does_not_support_function}.
+last_list_rows() ->
+ {error, driver_does_not_support_function}.
+prev_list_rows() ->
+ {error, driver_does_not_support_function}.
+next_list_rows() ->
+ {selected,["ID","DATA"],[[1,"bar"]]}.
+
+multiple_select()->
+ [{selected,["ID", "DATA"],[{1, "bar"},{2, "foo"}]},
+ {selected,["ID"],[{"foo"}]}].
+
+multiple_mix()->
+ [{updated, 1},{updated, 1},
+ {selected,["ID", "DATA"],[{1, "foobar"},{2, "foo"}]},
+ {updated, 1}, {selected,["DATA"],[{"foo"}]}].
+
+%-------------------------------------------------------------------------
+var_char_min() ->
+ 0.
+var_char_max() ->
+ 65535.
+
+create_var_char_table(Size) ->
+ " (FIELD varchar(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+text_min() ->
+ 1.
+text_max() ->
+ 2147483646. % 2147483647. %% 2^31 - 1
+
+create_text_table() ->
+ " (FIELD text)".
+
+%-------------------------------------------------------------------------
+create_timestamp_table() ->
+ " (FIELD TIMESTAMP)".
+
+%-------------------------------------------------------------------------
+tiny_int_min() ->
+ -128.
+tiny_int_max() ->
+ 127.
+
+create_tiny_int_table() ->
+ " (FIELD tinyint)".
+
+tiny_int_min_selected() ->
+ {selected,["FIELD"],[{tiny_int_min()}]}.
+
+tiny_int_max_selected() ->
+ {selected,["FIELD"], [{tiny_int_max()}]}.
+
+%-------------------------------------------------------------------------
+small_int_min() ->
+ -32768.
+small_int_max() ->
+ 32767.
+
+create_small_int_table() ->
+ " (FIELD smallint)".
+
+small_int_min_selected() ->
+ {selected,["FIELD"],[{-32768}]}.
+
+small_int_max_selected() ->
+ {selected,["FIELD"], [{32767}]}.
+
+%-------------------------------------------------------------------------
+int_min() ->
+ -2147483648.
+int_max() ->
+ 2147483647.
+
+create_int_table() ->
+ " (FIELD int)".
+
+int_min_selected() ->
+ {selected,["FIELD"],[{-2147483648}]}.
+
+int_max_selected() ->
+ {selected,["FIELD"], [{2147483647}]}.
+
+%-------------------------------------------------------------------------
+big_int_min() ->
+ -9223372036854775808.
+
+big_int_max() ->
+ 9223372036854775807.
+
+create_big_int_table() ->
+ " (FIELD bigint )".
+
+big_int_min_selected() ->
+ {selected,["FIELD"], [{"-9223372036854775808"}]}.
+
+big_int_max_selected() ->
+ {selected,["FIELD"], [{"9223372036854775807"}]}.
+
+%-------------------------------------------------------------------------
+bit_false() ->
+ 0.
+bit_true() ->
+ 1.
+
+create_bit_table() ->
+ " (FIELD bit)".
+
+bit_false_selected() ->
+ {selected,["FIELD"],[{"0"}]}.
+
+bit_true_selected() ->
+ {selected,["FIELD"], [{"1"}]}.
+
+%-------------------------------------------------------------------------
+
+%% Do not test float min/max as value is only theoretical defined in
+%% mysql and may vary depending on hardware.
+
+create_float_table() ->
+ " (FIELD float)".
+
+float_zero_selected() ->
+ {selected,["FIELD"],[{0.00000e+0}]}.
+
+%-------------------------------------------------------------------------
+real_min() ->
+ -3.40e+38.
+real_max() ->
+ 3.40e+38.
+
+real_underflow() ->
+ "-3.41e+38".
+
+real_overflow() ->
+ "3.41e+38".
+
+create_real_table() ->
+ " (FIELD real)".
+
+real_zero_selected() ->
+ {selected,["FIELD"],[{0.00000e+0}]}.
+
+%-------------------------------------------------------------------------
+param_select_small_int() ->
+ {selected,["FIELD"],[{1}, {2}]}.
+
+param_select_int() ->
+ Int = small_int_max() + 1,
+ {selected,["FIELD"],[{1}, {Int}]}.
+
+param_select_decimal() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_numeric() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_float() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_real() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_double() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_mix() ->
+ {selected,["ID","DATA"],[{1, "foo"}, {2, "bar"}]}.
+
+param_update() ->
+ {selected,["ID","DATA"],[{1, "foobar"}, {2, "foobar"}, {3, "baz"}]}.
+
+param_delete() ->
+ {selected,["ID","DATA"],[{3, "baz"}]}.
+
+param_select() ->
+ {selected,["ID","DATA"],[{1, "foo"},{3, "foo"}]}.
+
+%-------------------------------------------------------------------------
+describe_integer() ->
+ {ok,[{"myint1",sql_smallint},
+ {"myint2",sql_integer},
+ {"myint3",sql_integer}]}.
+
+describe_string() ->
+ {ok,[{"str1",{sql_char,10}},
+ {"str2",{sql_char,10}},
+ {"str3",{sql_varchar,10}},
+ {"str4",{sql_varchar,10}}]}.
+
+describe_floating() ->
+ {ok,[{"f",sql_real},{"r",sql_double},{"d",sql_double}]}.
+describe_dec_num() ->
+ {ok,[{"mydec",{sql_decimal,9,3}},{"mynum",{sql_decimal,9,2}}]}.
+
+describe_timestamp() ->
+ {ok, [{"FIELD", sql_timestamp}]}.
diff --git a/lib/odbc/test/odbc.dynspec b/lib/odbc/test/odbc.dynspec
deleted file mode 100644
index bb15edceed..0000000000
--- a/lib/odbc/test/odbc.dynspec
+++ /dev/null
@@ -1,31 +0,0 @@
-%% -*- erlang -*-
-%% You can test this file using this command.
-%% file:script("odbc.dynspec", [{'Os',"Unix"}]).
-
-Exists =
-fun() ->
- case code:lib_dir(odbc) of
- {error,bad_name} ->
- false;
- P ->
- %% Make sure that the odbc directory really
- %% contains the application (and not only documentation).
- case filelib:is_file(filename:join(P, "ebin/odbc.beam")) of
- false -> false;
- true ->
- %% We know that we don't have any odbc libraries
- %% installed on this computer.
- {ok,Host} = inet:gethostname(),
- Host =/= "netsim200"
- end
- end
-end,
-case Exists() of
- false ->
- NoOdbc = "No odbc application",
- [{skip, {odbc_connect_SUITE, NoOdbc}},
- {skip, {odbc_data_type_SUITE, NoOdbc}},
- {skip, {odbc_query_SUITE, NoOdbc}}];
- true ->
- []
-end.
diff --git a/lib/odbc/test/odbc.spec b/lib/odbc/test/odbc.spec
index edaf821c91..653f1a780e 100644
--- a/lib/odbc/test/odbc.spec
+++ b/lib/odbc/test/odbc.spec
@@ -1,25 +1 @@
{suites,"../odbc_test",all}.
-{skip_cases,"../odbc_test",odbc_data_type_SUITE,
- [varchar_upper_limit],
- "Known bug in database"}.
-{skip_cases,"../odbc_test",odbc_data_type_SUITE,
- [text_upper_limit],
- "Consumes too much resources"}.
-{skip_cases,"../odbc_test",odbc_data_type_SUITE,
- [bit_true],
- "Not supported by driver"}.
-{skip_cases,"../odbc_test",odbc_data_type_SUITE,
- [bit_false],
- "Not supported by driver"}.
-{skip_cases,"../odbc_test",odbc_query_SUITE,
- [multiple_select_result_sets],
- "Not supported by driver"}.
-{skip_cases,"../odbc_test",odbc_query_SUITE,
- [multiple_mix_result_sets],
- "Not supported by driver"}.
-{skip_cases,"../odbc_test",odbc_query_SUITE,
- [multiple_result_sets_error],
- "Not supported by driver"}.
-{skip_cases,"../odbc_test",odbc_query_SUITE,
- [param_insert_tiny_int],
- "Not supported by driver"}.
diff --git a/lib/odbc/test/odbc.spec.win b/lib/odbc/test/odbc.spec.win
deleted file mode 100644
index 1fd349d2c3..0000000000
--- a/lib/odbc/test/odbc.spec.win
+++ /dev/null
@@ -1,5 +0,0 @@
-{topcase, {dir, "../odbc_test"}}.
-{skip, {odbc_data_type_SUITE, big_int_lower_limit, "Not supported by sqlserver 7.0"}}.
-{skip, {odbc_data_type_SUITE, big_int_upper_limit, "Not supported by sqlserver7.0"}}.
-{skip, {odbc_data_type_SUITE, text_upper_limit, "Consumes too much resources"}}.
-
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
index 6a2268f40e..a076c4dfff 100644
--- a/lib/odbc/test/odbc_connect_SUITE.erl
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -76,16 +76,26 @@ end_per_group(_GroupName, 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_suite(Config) ->
- application:start(odbc),
- case catch odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]) of
- {ok, Ref} ->
- odbc:disconnect(Ref),
- [{tableName, odbc_test_lib:unique_table_name()} | Config];
- _ ->
- {skip, "ODBC is not properly setup"}
- end.
+init_per_suite(Config) when is_list(Config) ->
+ case odbc_test_lib:skip() of
+ true ->
+ {skip, "ODBC not supported"};
+ false ->
+ case (catch odbc:start()) of
+ ok ->
+ case catch odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()) of
+ {ok, Ref} ->
+ odbc:disconnect(Ref),
+ [{tableName, odbc_test_lib:unique_table_name()} | Config];
+ _ ->
+ {skip, "ODBC is not properly setup"}
+ end;
+ _ ->
+ {skip,"ODBC not startable"}
+ end
+ end.
+
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -93,8 +103,7 @@ init_per_suite(Config) ->
%% Description: Cleanup after the whole suite
%%--------------------------------------------------------------------
end_per_suite(_Config) ->
- application:stop(odbc),
- ok.
+ application:stop(odbc).
%%--------------------------------------------------------------------
%% Function: init_per_testcase(Case, Config) -> Config
@@ -124,15 +133,13 @@ init_per_testcase(_TestCase, Config) ->
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
end_per_testcase(_TestCase, Config) ->
- %% Clean up if needed
Table = ?config(tableName, Config),
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
- Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
+ Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
io:format("Drop table: ~p ~p~n", [Table, Result]),
odbc:disconnect(Ref),
Dog = ?config(watchdog, Config),
- test_server:timetrap_cancel(Dog),
- ok.
+ test_server:timetrap_cancel(Dog).
%%-------------------------------------------------------------------------
%% Test cases starts here.
@@ -142,13 +149,15 @@ commit(doc)->
commit(suite) -> [];
commit(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
+ TransStr = transaction_support_str(?RDBMS),
+
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10))"),
+ " (ID integer, DATA varchar(10))" ++ TransStr),
{updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1,'bar')"),
@@ -173,50 +182,47 @@ commit(Config) ->
{'EXIT', {function_clause, _}} =
(catch odbc:commit(Ref, commit, -1)),
- ok = odbc:disconnect(Ref),
-
- ok.
+ ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
rollback(doc)->
["Test the use of explicit rollback"];
rollback(suite) -> [];
rollback(Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
- {updated, _} =
- odbc:sql_query(Ref,
+ TransStr = transaction_support_str(?RDBMS),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10))"),
- {updated, 1} =
+ " (ID integer, DATA varchar(10))" ++ TransStr),
+ {updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
ok = odbc:commit(Ref, commit),
- {updated, 1} =
+ {updated, 1} =
odbc:sql_query(Ref, "UPDATE " ++ Table ++
- " SET DATA = 'foo' WHERE ID = 1"),
+ " SET DATA = 'foo' WHERE ID = 1"),
ok = odbc:commit(Ref, rollback),
InsertResult = ?RDBMS:insert_result(),
- InsertResult =
+ InsertResult =
odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
-
- {updated, 1} =
+ {updated, 1} =
odbc:sql_query(Ref, "UPDATE " ++ Table ++
- " SET DATA = 'foo' WHERE ID = 1"),
+ " SET DATA = 'foo' WHERE ID = 1"),
ok = odbc:commit(Ref, rollback, ?TIMEOUT),
InsertResult = ?RDBMS:insert_result(),
- InsertResult =
+ InsertResult =
odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+ {'EXIT', {function_clause, _}} =
+ (catch odbc:commit(Ref, rollback, -1)),
- {'EXIT', {function_clause, _}} =
- (catch odbc:commit(Ref, rollback, -1)),
-
- ok = odbc:disconnect(Ref),
- ok.
+ ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
not_explicit_commit(doc) ->
@@ -224,20 +230,20 @@ not_explicit_commit(doc) ->
not_explicit_commit(suite) -> [];
not_explicit_commit(_Config) ->
{ok, Ref} =
- odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}]),
+ odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}] ++
+ odbc_test_lib:platform_options()),
{error, _} = odbc:commit(Ref, commit),
- ok = odbc:disconnect(Ref),
- ok.
+ ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
not_exist_db(doc) ->
["Tests valid data format but invalid data in the connection parameters."];
not_exist_db(suite) -> [];
not_exist_db(_Config) ->
- {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar", []),
+ {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar",
+ odbc_test_lib:platform_options()),
%% So that the odbc control server can be stoped "in the correct way"
- test_server:sleep(100),
- ok.
+ test_server:sleep(100).
%%-------------------------------------------------------------------------
no_c_node(doc) ->
@@ -252,7 +258,8 @@ no_c_node(_Config) ->
FileName2 = filename:nativename(filename:join(Dir, "odbcsrv")),
ok = file:rename(FileName1, FileName2),
Result =
- case catch odbc:connect(?RDBMS:connection_string(), []) of
+ case catch odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()) of
{error, port_program_executable_not_found} ->
ok;
Else ->
@@ -267,7 +274,7 @@ port_dies(doc) ->
"Tests what happens if the port program dies";
port_dies(suite) -> [];
port_dies(_Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
{status, _} = process_info(Ref, status),
process_flag(trap_exit, true),
Port = lists:last(erlang:ports()),
@@ -275,26 +282,23 @@ port_dies(_Config) ->
%% Wait for exit_status from port 5000 ms (will not get a exit
%% status in this case), then wait a little longer to make sure
%% the port and the controlprocess has had time to terminate.
- test_server:sleep(7000),
- undefined = process_info(Ref, status),
- ok.
+ test_server:sleep(10000),
+ undefined = process_info(Ref, status).
%%-------------------------------------------------------------------------
control_process_dies(doc) ->
"Tests what happens if the Erlang control process dies";
control_process_dies(suite) -> [];
control_process_dies(_Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
process_flag(trap_exit, true),
Port = lists:last(erlang:ports()),
{connected, Ref} = erlang:port_info(Port, connected),
exit(Ref, kill),
- test_server:sleep(100),
- undefined = erlang:port_info(Port, connected),
+ test_server:sleep(500),
+ undefined = erlang:port_info(Port, connected).
%% Check for c-program still running, how?
- ok.
-%%-------------------------------------------------------------------------
%%-------------------------------------------------------------------------
client_dies_normal(doc) ->
@@ -319,7 +323,7 @@ client_dies_normal(Config) when is_list(Config) ->
end.
client_normal(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -351,7 +355,7 @@ client_dies_timeout(Config) when is_list(Config) ->
end.
client_timeout(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -383,7 +387,7 @@ client_dies_error(Config) when is_list(Config) ->
end.
client_error(Pid) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Pid ! {dbRef, Ref},
receive
continue ->
@@ -398,7 +402,10 @@ connect_timeout(doc) ->
connect_timeout(suite) -> [];
connect_timeout(Config) when is_list(Config) ->
{'EXIT',timeout} = (catch odbc:connect(?RDBMS:connection_string(),
- [{timeout, 0}])),
+ [{timeout, 0}] ++
+ odbc_test_lib:platform_options())),
+ %% Need to return ok here "{'EXIT',timeout} return value" will
+ %% be interpreted as that the testcase has timed out.
ok.
%%-------------------------------------------------------------------------
timeout(doc) ->
@@ -411,10 +418,12 @@ timeout(Config) when is_list(Config) ->
[{auto_commit, off}]),
Table = ?config(tableName, Config),
+ TransStr = transaction_support_str(?RDBMS),
+
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))" ++ TransStr),
{updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
@@ -446,14 +455,12 @@ timeout(Config) when is_list(Config) ->
["DATA"] = odbc_test_lib:to_upper(Fields),
ok = odbc:commit(Ref, commit),
- ok = odbc:disconnect(Ref),
- ok.
-
+ ok = odbc:disconnect(Ref).
update_table_timeout(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
@@ -474,15 +481,16 @@ update_table_timeout(Table, TimeOut, Pid) ->
odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"),
["DATA"] = odbc_test_lib:to_upper(Fields),
- {updated, 1} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
+ %% Do not check {updated, 1} as some drivers will return 0
+ %% even though the update is done, which is checked by the test
+ %% case when the altered message is recived.
+ {updated, _} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
ok = odbc:commit(Ref, commit),
Pid ! altered,
- ok = odbc:disconnect(Ref),
-
- ok.
+ ok = odbc:disconnect(Ref).
%%-------------------------------------------------------------------------
many_timeouts(doc) ->
["Tests that many consecutive timeouts lead to that the connection "
@@ -490,14 +498,15 @@ many_timeouts(doc) ->
many_timeouts(suite) -> [];
many_timeouts(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
+ TransStr = transaction_support_str(?RDBMS),
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))" ++ TransStr),
{updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
@@ -517,22 +526,20 @@ many_timeouts(Config) when is_list(Config) ->
end,
ok = odbc:commit(Ref, commit),
- ok = odbc:disconnect(Ref),
- ok.
+ ok = odbc:disconnect(Ref).
update_table_many_timeouts(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
ok = loop_many_timouts(Ref, UpdateQuery, TimeOut),
Pid ! many_timeouts_occurred,
- ok = odbc:disconnect(Ref),
- ok.
+ ok = odbc:disconnect(Ref).
loop_many_timouts(Ref, UpdateQuery, TimeOut) ->
@@ -546,18 +553,19 @@ loop_many_timouts(Ref, UpdateQuery, TimeOut) ->
end.
%%-------------------------------------------------------------------------
timeout_reset(doc) ->
- ["Check that the number of consecutive timouts is reset to 0 when "
+ ["Check that the number of consecutive timouts is reset to 0 when "
"a successful call to the database is made."];
timeout_reset(suite) -> [];
timeout_reset(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
+ TransStr = transaction_support_str(?RDBMS),
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))" ++ TransStr),
{updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
@@ -593,13 +601,12 @@ timeout_reset(Config) when is_list(Config) ->
["DATA"] = odbc_test_lib:to_upper(Fields),
ok = odbc:commit(Ref, commit),
- ok = odbc:disconnect(Ref),
- ok.
+ ok = odbc:disconnect(Ref).
update_table_timeout_reset(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
ok = loop_timout_reset(Ref, UpdateQuery, TimeOut,
@@ -616,15 +623,16 @@ update_table_timeout_reset(Table, TimeOut, Pid) ->
odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"),
["DATA"] = odbc_test_lib:to_upper(Fields),
- {updated,1} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
+ %% Do not check {updated, 1} as some drivers will return 0
+ %% even though the update is done, which is checked by the test
+ %% case when the altered message is recived.
+ {updated, _} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
ok = odbc:commit(Ref, commit),
Pid ! altered,
- ok = odbc:disconnect(Ref),
-
- ok.
+ ok = odbc:disconnect(Ref).
loop_timout_reset(_, _, _, 0) ->
ok;
@@ -648,13 +656,14 @@ disconnect_on_timeout(suite) -> [];
disconnect_on_timeout(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
+ TransStr = transaction_support_str(?RDBMS),
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))" ++ TransStr),
{updated, 1} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
@@ -678,7 +687,7 @@ disconnect_on_timeout(Config) when is_list(Config) ->
update_table_disconnect_on_timeout(Table, TimeOut, Pid) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{auto_commit, off}]),
+ [{auto_commit, off}] ++ odbc_test_lib:platform_options()),
UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
@@ -695,7 +704,7 @@ connection_closed(doc) ->
" use a connection that has been closed"];
connection_closed(suite) -> [];
connection_closed(Config) when is_list(Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
{updated, _} =
@@ -714,8 +723,7 @@ connection_closed(Config) when is_list(Config) ->
{error, connection_closed} = odbc:next(Ref),
{error, connection_closed} = odbc:prev(Ref),
{error, connection_closed} = odbc:select(Ref, next, 3),
- {error, connection_closed} = odbc:commit(Ref, commit),
- ok.
+ {error, connection_closed} = odbc:commit(Ref, commit).
%%-------------------------------------------------------------------------
disable_scrollable_cursors(doc) ->
@@ -753,8 +761,7 @@ disable_scrollable_cursors(Config) when is_list(Config) ->
{error, scrollable_cursors_disabled} =
odbc:select(Ref, {absolute, 2}, 5),
- {selected, _ColNames,[]} = odbc:select(Ref, next, 1),
- ok.
+ {selected, _ColNames,[]} = odbc:select(Ref, next, 1).
%%-------------------------------------------------------------------------
return_rows_as_lists(doc)->
@@ -763,7 +770,7 @@ return_rows_as_lists(doc)->
return_rows_as_lists(suite) -> [];
return_rows_as_lists(Config) when is_list(Config) ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{tuple_row, off}]),
+ [{tuple_row, off}] ++ odbc_test_lib:platform_options()),
Table = ?config(tableName, Config),
@@ -784,16 +791,21 @@ return_rows_as_lists(Config) when is_list(Config) ->
{ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
- First = ?RDBMS:first_list_rows(),
- Last = ?RDBMS:last_list_rows(),
- Prev = ?RDBMS:prev_list_rows(),
- Next = ?RDBMS:next_list_rows(),
-
- Last = odbc:last(Ref),
- Prev = odbc:prev(Ref),
- First = odbc:first(Ref),
- Next = odbc:next(Ref),
- ok.
+ case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of
+ off ->
+ Next = ?RDBMS:next_list_rows(),
+ Next = odbc:next(Ref);
+ _ ->
+ First = ?RDBMS:first_list_rows(),
+ Last = ?RDBMS:last_list_rows(),
+ Prev = ?RDBMS:prev_list_rows(),
+ Next = ?RDBMS:next_list_rows(),
+
+ Last = odbc:last(Ref),
+ Prev = odbc:prev(Ref),
+ First = odbc:first(Ref),
+ Next = odbc:next(Ref)
+ end.
%%-------------------------------------------------------------------------
@@ -802,22 +814,27 @@ api_missuse(doc)->
api_missuse(suite) -> [];
api_missuse(Config) when is_list(Config)->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:call(Ref, {self(), foobar, 10}, infinity),
test_server:sleep(10),
undefined = process_info(Ref, status),
- {ok, Ref2} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref2} = odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()),
%% Serious programming fault, connetion will be shut down
gen_server:cast(Ref2, {self(), foobar, 10}),
test_server:sleep(10),
undefined = process_info(Ref2, status),
- {ok, Ref3} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref3} = odbc:connect(?RDBMS:connection_string(),
+ odbc_test_lib:platform_options()),
%% Could be an innocent misstake the connection lives.
Ref3 ! foobar,
test_server:sleep(10),
- {status, _} = process_info(Ref3, status),
- ok.
+ {status, _} = process_info(Ref3, status).
+transaction_support_str(mysql) ->
+ "ENGINE = InnoDB";
+transaction_support_str(_) ->
+ "".
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
index bfb1e4b329..d61a91f973 100644
--- a/lib/odbc/test/odbc_data_type_SUITE.erl
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -44,24 +44,29 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
case odbc_test_lib:odbc_check() of
ok ->
- [{group, char}, {group, int}, {group, floats},
+ [{group, char},{group, fixed_char}, {group, binary_char},
+ {group, fixed_binary_char}, {group, unicode},
+ {group, int}, {group, floats},
{group, dec_and_num}, timestamp];
Other -> {skip, Other}
end.
groups() ->
[{char, [],
- [char_fixed_lower_limit, char_fixed_upper_limit,
- char_fixed_padding, varchar_lower_limit,
+ [varchar_lower_limit,
varchar_upper_limit, varchar_no_padding,
- text_lower_limit, text_upper_limit, unicode]},
+ text_lower_limit, text_upper_limit]},
+ {fixed_char, [],
+ [char_fixed_lower_limit, char_fixed_upper_limit,
+ char_fixed_padding]},
{binary_char, [],
- [binary_char_fixed_lower_limit,
- binary_char_fixed_upper_limit,
- binary_char_fixed_padding, binary_varchar_lower_limit,
+ [binary_varchar_lower_limit,
binary_varchar_upper_limit, binary_varchar_no_padding,
- binary_text_lower_limit, binary_text_upper_limit,
- unicode]},
+ binary_text_lower_limit, binary_text_upper_limit]},
+ {fixed_binary_char, [], [binary_char_fixed_lower_limit,
+ binary_char_fixed_upper_limit,
+ binary_char_fixed_padding]},
+ {unicode, [], [utf8, nchar, nvarchar]},
{int, [],
[tiny_int_lower_limit, tiny_int_upper_limit,
small_int_lower_limit, small_int_upper_limit,
@@ -74,14 +79,31 @@ groups() ->
[dec_long, dec_double, dec_bignum, num_long, num_double,
num_bignum]}].
+init_per_group(GroupName, Config) when GroupName == fixed_char;
+ GroupName == fixed_binary_char ->
+ case ?RDBMS of
+ mysql ->
+ {skip, "No supported by MYSQL"};
+ _ ->
+ Config
+ end;
+
+init_per_group(unicode, Config) ->
+ case {os:type(), erlang:system_info({wordsize, external})} of
+ {{unix, _}, 4} ->
+ Config;
+ {{unix, _}, _} ->
+ {skip, "Postgres drivers pre version psqlODBC 08.04.0200 have utf8-problems"};
+ _ ->
+ Config
+ end;
+
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, Config) ->
Config.
-
-
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -91,10 +113,18 @@ end_per_group(_GroupName, 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_suite(Config) ->
- application:start(odbc),
- [{tableName, odbc_test_lib:unique_table_name()} | Config].
-
+init_per_suite(Config) when is_list(Config) ->
+ case odbc_test_lib:skip() of
+ true ->
+ {skip, "ODBC not supported"};
+ false ->
+ case (catch odbc:start()) of
+ ok ->
+ [{tableName, odbc_test_lib:unique_table_name()}| Config];
+ _ ->
+ {skip, "ODBC not startable"}
+ end
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
%% Config - [tuple()]
@@ -117,22 +147,81 @@ 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(Case, Config) when Case == varchar_upper_limit;
+ Case == binary_varchar_upper_limit;
+ Case == varchar_no_padding;
+ Case == binary_varchar_no_padding ->
+ case is_fixed_upper_limit(?RDBMS) of
+ true ->
+ common_init_per_testcase(Case, Config);
+ false ->
+ {skip, "Upper limit is not fixed in" ++ atom_to_list(?RDBMS)}
+ end;
+
+init_per_testcase(text_upper_limit, _Config) ->
+ {skip, "Consumes too much resources"};
+
+init_per_testcase(Case, Config) when Case == bit_true; Case == bit_false ->
+ case is_supported_bit(?RDBMS) of
+ true ->
+ common_init_per_testcase(Case, Config);
+ false ->
+ {skip, "Not supported by driver"}
+ end;
+
+init_per_testcase(param_insert_tiny_int = Case, Config) ->
+ case is_supported_tinyint(?RDBMS) of
+ true ->
+ common_init_per_testcase(Case, Config);
+ false ->
+ {skip, "Not supported by driver"}
+ end;
+
+init_per_testcase(Case, Config) when Case == nchar;
+ Case == nvarchar ->
+ case ?RDBMS of
+ sqlserver ->
+ common_init_per_testcase(Case, Config);
+ _ ->
+ {skip, "Not supported by driver"}
+ end;
+
init_per_testcase(Case, Config) ->
+ common_init_per_testcase(Case, Config).
+
+common_init_per_testcase(Case, Config) ->
+ PlatformOptions = odbc_test_lib:platform_options(),
case atom_to_list(Case) of
"binary" ++ _ ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}]);
- "unicode" ->
+ [{binary_strings, on}] ++ PlatformOptions);
+ LCase when LCase == "utf8";
+ LCase == "nchar";
+ LCase == "nvarchar" ->
{ok, Ref} = odbc:connect(?RDBMS:connection_string(),
- [{binary_strings, on}]);
+ [{binary_strings, on}] ++ PlatformOptions);
_ ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), [])
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), PlatformOptions)
end,
+ odbc_test_lib:strict(Ref, ?RDBMS),
Dog = test_server:timetrap(?default_timeout),
Temp = lists:keydelete(connection_ref, 1, Config),
NewConfig = lists:keydelete(watchdog, 1, Temp),
[{watchdog, Dog}, {connection_ref, Ref} | NewConfig].
+is_fixed_upper_limit(mysql) ->
+ false;
+is_fixed_upper_limit(_) ->
+ true.
+is_supported_tinyint(sqlserver) ->
+ true;
+is_supported_tinyint(_) ->
+ false.
+is_supported_bit(sqlserver) ->
+ true;
+is_supported_bit(_) ->
+ false.
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
%% Case - atom()
@@ -146,7 +235,7 @@ end_per_testcase(_TestCase, Config) ->
ok = odbc:disconnect(Ref),
%% Clean up if needed
Table = ?config(tableName, Config),
- {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
odbc:disconnect(NewRef),
Dog = ?config(watchdog, Config),
@@ -169,18 +258,18 @@ char_fixed_lower_limit(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- ?RDBMS:create_fixed_char_table(
+ ?RDBMS:create_fixed_char_table(
(?RDBMS:fixed_char_min() - 1))),
%% Lower limit
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_fixed_char_table(
- ?RDBMS:fixed_char_min())),
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_min())),
%% Right length data
{updated, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a, ?RDBMS:fixed_char_min())
+ "'" ++ string:chars($a, ?RDBMS:fixed_char_min())
++ "')"),
%% Select data
{selected, Fields,[{"a"}]} =
@@ -191,11 +280,11 @@ char_fixed_lower_limit(Config) when is_list(Config) ->
%% Too long data
{error, _} =
odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a,
- (?RDBMS:fixed_char_min()
- + 1))
- ++ "')"),
- ok.
+ "'" ++ string:chars($a,
+ (?RDBMS:fixed_char_min()
+ + 1))
+ ++ "')").
+
%%-------------------------------------------------------------------------
char_fixed_upper_limit(doc) ->
@@ -243,8 +332,7 @@ char_fixed_upper_limit(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
?RDBMS:create_fixed_char_table(
- (?RDBMS:fixed_char_max() + 1))),
- ok
+ (?RDBMS:fixed_char_max() + 1)))
end.
%%-------------------------------------------------------------------------
@@ -261,20 +349,20 @@ char_fixed_padding(Config) when is_list(Config) ->
%% Data should be padded with blanks
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_fixed_char_table(
- ?RDBMS:fixed_char_max())),
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_max())),
- {updated, _} =
+ {updated, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a,
- ?RDBMS:fixed_char_min())
+ "'" ++ string:chars($a,
+ ?RDBMS:fixed_char_min())
++ "')"),
{selected, Fields, [{CharStr}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
true = length(CharStr) == ?RDBMS:fixed_char_max(),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
+
%%-------------------------------------------------------------------------
varchar_lower_limit(doc) ->
@@ -287,33 +375,33 @@ varchar_lower_limit(Config) when is_list(Config) ->
%% Below limit
{error, _} =
- odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_var_char_table(
- ?RDBMS:var_char_min() - 1)),
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min() - 1)),
%% Lower limit
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_var_char_table(
- ?RDBMS:var_char_min())),
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min())),
+
+ Str = string:chars($a, ?RDBMS:var_char_min()),
%% Right length data
{updated, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a, ?RDBMS:var_char_min())
- ++ "')"),
+ "'" ++ Str ++ "')"),
%% Select data
- {selected, Fields, [{"a"}]} =
+ {selected, Fields, [{Str}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields),
- %% Too long data
- {error, _} =
- odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a,
- (?RDBMS:var_char_min()+1))
- ++ "')"),
- ok.
+ %% Too long datae
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:var_char_min()+1))
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -389,8 +477,7 @@ varchar_no_padding(Config) when is_list(Config) ->
{selected, Fields, [{CharStr}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
true = length(CharStr) /= ?RDBMS:var_char_max(),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%-------------------------------------------------------------------------
@@ -413,8 +500,7 @@ text_lower_limit(Config) when is_list(Config) ->
{selected, Fields, [{"a"}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%-------------------------------------------------------------------------
@@ -444,8 +530,7 @@ text_upper_limit(Config) when is_list(Config) ->
%% {error, _} =
%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
%% "'" ++ string:chars($a, (?RDBMS:text_max()+1))
-%% ++ "')"),
-%% ok.
+%% ++ "')").
%%-------------------------------------------------------------------------
@@ -469,13 +554,18 @@ binary_char_fixed_lower_limit(Config) when is_list(Config) ->
?RDBMS:create_fixed_char_table(
?RDBMS:fixed_char_min())),
+ Str = string:chars($a, ?RDBMS:fixed_char_min()),
+
%% Right length data
{updated, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a, ?RDBMS:fixed_char_min())
+ "'" ++ Str
++ "')"),
+
+ Bin = list_to_binary(Str),
+
%% Select data
- {selected, Fields,[{<<"a">>}]} =
+ {selected, Fields,[{Bin}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields),
@@ -486,8 +576,7 @@ binary_char_fixed_lower_limit(Config) when is_list(Config) ->
"'" ++ string:chars($a,
(?RDBMS:fixed_char_min()
+ 1))
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
binary_char_fixed_upper_limit(doc) ->
@@ -565,8 +654,8 @@ binary_char_fixed_padding(Config) when is_list(Config) ->
{selected, Fields, [{CharBin}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
true = size(CharBin) == ?RDBMS:fixed_char_max(),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
+
%%-------------------------------------------------------------------------
binary_varchar_lower_limit(doc) ->
@@ -588,13 +677,17 @@ binary_varchar_lower_limit(Config) when is_list(Config) ->
?RDBMS:create_var_char_table(
?RDBMS:var_char_min())),
+ Str = string:chars($a, ?RDBMS:var_char_min()),
+
%% Right length data
{updated, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ string:chars($a, ?RDBMS:var_char_min())
+ "'" ++ Str
++ "')"),
+ BinStr = list_to_binary(Str),
+
%% Select data
- {selected, Fields, [{<<"a">>}]} =
+ {selected, Fields, [{BinStr}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
["FIELD"] = odbc_test_lib:to_upper(Fields),
@@ -604,8 +697,7 @@ binary_varchar_lower_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ string:chars($a,
(?RDBMS:var_char_min()+1))
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -654,8 +746,7 @@ binary_varchar_upper_limit(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
?RDBMS:create_var_char_table(
- (?RDBMS:var_char_max() + 1))),
- ok
+ (?RDBMS:var_char_max() + 1)))
end.
%%-------------------------------------------------------------------------
@@ -681,8 +772,7 @@ binary_varchar_no_padding(Config) when is_list(Config) ->
{selected, Fields, [{CharBin}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
true = size(CharBin) /= ?RDBMS:var_char_max(),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%-------------------------------------------------------------------------
@@ -705,8 +795,7 @@ binary_text_lower_limit(Config) when is_list(Config) ->
{selected, Fields, [{<<"a">>}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%-------------------------------------------------------------------------
@@ -736,11 +825,7 @@ binary_text_upper_limit(Config) when is_list(Config) ->
%% {error, _} =
%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
%% "'" ++ string:chars($a, (?RDBMS:text_max()+1))
-%% ++ "')"),
-%% ok.
-
-
-%%-------------------------------------------------------------------------
+%% ++ "')").
%%-------------------------------------------------------------------------
@@ -774,8 +859,7 @@ tiny_int_lower_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:tiny_int_min()
- 1)
- ++ "')"),
- ok
+ ++ "')")
end.
%%-------------------------------------------------------------------------
@@ -809,8 +893,7 @@ tiny_int_upper_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:tiny_int_max()
+ 1)
- ++ "')"),
- ok
+ ++ "')")
end.
%%-------------------------------------------------------------------------
@@ -840,8 +923,7 @@ small_int_lower_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:small_int_min()
- 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -870,8 +952,7 @@ small_int_upper_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:small_int_max()
+ 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
int_lower_limit(doc) ->
@@ -898,8 +979,7 @@ int_lower_limit(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:int_min() - 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -927,8 +1007,7 @@ int_upper_limit(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:int_max() + 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -957,8 +1036,7 @@ big_int_lower_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:big_int_min()
- 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
@@ -987,8 +1065,7 @@ big_int_upper_limit(Config) when is_list(Config) ->
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(?RDBMS:big_int_max()
+ 1)
- ++ "')"),
- ok.
+ ++ "')").
%%-------------------------------------------------------------------------
bit_false(doc) ->
@@ -1020,8 +1097,7 @@ bit_false(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(-1)
- ++ "')"),
- ok
+ ++ "')")
end.
%%-------------------------------------------------------------------------
@@ -1056,14 +1132,10 @@ bit_true(Config) when is_list(Config) ->
{error, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
"'" ++ integer_to_list(-1)
- ++ "')"),
- ok
+ ++ "')")
end.
%%-------------------------------------------------------------------------
-
-
-%%-------------------------------------------------------------------------
float_lower_limit(doc) ->
[""];
float_lower_limit(suite) ->
@@ -1073,44 +1145,45 @@ float_lower_limit(Config) when is_list(Config) ->
Ref = ?config(connection_ref, Config),
Table = ?config(tableName, Config),
- {updated, _} = % Value == 0 || -1 driver dependent!
- odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_float_table()),
-
- {updated, _} =
- odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ float_to_list(
- ?RDBMS:float_min())
- ++ "')"),
- {selected,[_ColName],[{MinFloat}]} =
- odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
-
- true = ?RDBMS:float_min() == MinFloat,
-
case ?RDBMS of
- oracle ->
- {updated, _} = % Value == 0 || -1 driver dependent!
- odbc:sql_query(Ref, "DROP TABLE " ++ Table),
-
+ mysql ->
+ {skip, "Not clearly defined in MYSQL"};
+ _ ->
{updated, _} = % Value == 0 || -1 driver dependent!
odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_float_table()),
+ ?RDBMS:create_float_table()),
{updated, _} =
- odbc:sql_query(Ref,
- "INSERT INTO " ++ Table ++" VALUES(" ++
- ?RDBMS:float_underflow() ++ ")"),
-
- SelectResult = ?RDBMS:float_zero_selected(),
- SelectResult =
- odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table);
- _ ->
- {error, _} =
odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- ?RDBMS:float_underflow() ++ ")")
- end,
- ok.
+ "'" ++ float_to_list(
+ ?RDBMS:float_min())
+ ++ "')"),
+ {selected,[_ColName],[{MinFloat}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = ?RDBMS:float_min() == MinFloat,
+
+ case ?RDBMS of
+ oracle ->
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_underflow() ++ ")"),
+ SelectResult = ?RDBMS:float_zero_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table);
+ _ ->
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_underflow() ++ ")")
+ end
+ end.
%%-------------------------------------------------------------------------
float_upper_limit(doc) ->
@@ -1121,26 +1194,28 @@ float_upper_limit(Config) when is_list(Config) ->
Ref = ?config(connection_ref, Config),
Table = ?config(tableName, Config),
- {updated, _} = % Value == 0 || -1 driver dependent!
- odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_float_table()),
-
- {updated, _} =
- odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- "'" ++ float_to_list(
- ?RDBMS:float_max())
- ++ "')"),
-
+ case ?RDBMS of
+ mysql ->
+ {skip, "Not clearly defined in MYSQL"};
+ _->
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
- {selected,[_ColName],[{MaxFloat}]}
- = odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ float_to_list(
+ ?RDBMS:float_max())
+ ++ "')"),
+ {selected,[_ColName],[{MaxFloat}]}
+ = odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- true = ?RDBMS:float_max() == MaxFloat,
+ true = ?RDBMS:float_max() == MaxFloat,
- {error, _} =
- odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
- ?RDBMS:float_overflow() ++ ")"),
- ok.
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_overflow() ++ ")")
+ end.
%%-------------------------------------------------------------------------
float_zero(doc) ->
@@ -1160,8 +1235,7 @@ float_zero(Config) when is_list(Config) ->
SelectResult = ?RDBMS:float_zero_selected(),
SelectResult =
- odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ok.
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table).
%%-------------------------------------------------------------------------
real_zero(doc) ->
["Test the real value zero."];
@@ -1185,10 +1259,8 @@ real_zero(Config) when is_list(Config) ->
SelectResult = ?RDBMS:real_zero_selected(),
SelectResult =
- odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ok
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table)
end.
-%%-------------------------------------------------------------------------
%%------------------------------------------------------------------------
dec_long(doc) ->
[""];
@@ -1207,8 +1279,7 @@ dec_long(Config) when is_list(Config) ->
{selected, Fields, [{2}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%------------------------------------------------------------------------
dec_double(doc) ->
[""];
@@ -1255,8 +1326,7 @@ dec_double(Config) when is_list(Config) ->
{selected, Fields2, [{1.60000}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields2),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields2).
%%------------------------------------------------------------------------
dec_bignum(doc) ->
@@ -1289,8 +1359,7 @@ dec_bignum(Config) when is_list(Config) ->
{selected, Fields1, [{"1.6"}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields1),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1).
%%------------------------------------------------------------------------
num_long(doc) ->
[""];
@@ -1309,8 +1378,7 @@ num_long(Config) when is_list(Config) ->
{selected, Fields, [{2}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields).
%%------------------------------------------------------------------------
num_double(doc) ->
[""];
@@ -1356,8 +1424,7 @@ num_double(Config) when is_list(Config) ->
{selected, Fields2, [{1.6000}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields2),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields2).
%%------------------------------------------------------------------------
num_bignum(doc) ->
[""];
@@ -1389,21 +1456,19 @@ num_bignum(Config) when is_list(Config) ->
{selected, Fields1, [{"1.6"}]} =
odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
- ["FIELD"] = odbc_test_lib:to_upper(Fields1),
- ok.
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1).
%%------------------------------------------------------------------------
-unicode(doc) ->
+utf8(doc) ->
["Test unicode support"];
-unicode(suit) ->
+utf8(suit) ->
[];
-unicode(Config) when is_list(Config) ->
+utf8(Config) when is_list(Config) ->
Ref = ?config(connection_ref, Config),
Table = ?config(tableName, Config),
- {updated, _} = % Value == 0 || -1 driver dependent!
- odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
- ?RDBMS:create_unicode_table()),
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ "(FIELD text)"),
+
Latin1Data = ["���������",
"testasdf",
"Row 3",
@@ -1416,39 +1481,7 @@ unicode(Config) when is_list(Config) ->
"Row 10",
"Row 11",
"Row 12"],
-
- case ?RDBMS of
- sqlserver ->
- w_char_support_win(Ref, Table, Latin1Data);
- postgres ->
- direct_utf8(Ref, Table, Latin1Data);
- oracle ->
- {skip, "not currently supported"}
- end.
-
-w_char_support_win(Ref, Table, Latin1Data) ->
- UnicodeIn = lists:map(fun(S) ->
- unicode:characters_to_binary(S,latin1,{utf16,little})
- end,
- Latin1Data),
-
- test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
- {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
- [{{sql_wvarchar,50},UnicodeIn}]),
-
- {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
-
- test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
-
- Result = lists:map(fun({Unicode}) ->
- unicode:characters_to_list(Unicode,{utf16,little})
- end,
- UnicodeOut),
- Latin1Data = Result.
-
-
-direct_utf8(Ref, Table, Latin1Data) ->
UnicodeIn = lists:map(fun(String) ->
unicode:characters_to_binary(String,latin1,utf8)
end,
@@ -1469,6 +1502,37 @@ direct_utf8(Ref, Table, Latin1Data) ->
test_server:format("Result: ~p ~n", [Result]),
Latin1Data = Result.
+%%------------------------------------------------------------------------
+
+nchar(doc) ->
+ ["Test unicode nchar support in sqlserver"];
+nchar(suit) ->
+ [];
+nchar(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD nchar(50))"),
+
+ w_char_support(Ref, Table, sql_wvarchar, 50).
+
+%%------------------------------------------------------------------------
+
+nvarchar(doc) ->
+ ["Test 'unicode' nvarchar support"];
+nvarchar(suit) ->
+ [];
+nvarchar(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD nvarchar(50))"),
+
+ w_char_support(Ref, Table, sql_wlongvarchar, 50).
%%------------------------------------------------------------------------
timestamp(doc) ->
@@ -1497,3 +1561,43 @@ timestamp(Config) when is_list(Config) ->
TimeStamps = lists:map(fun(Value) -> {Value} end, Data),
{selected,_, TimeStamps} = odbc:sql_query(Ref, "SELECT * FROM " ++ Table).
+%%------------------------------------------------------------------------
+
+w_char_support(Ref, Table, CharType, Size) ->
+ Latin1Data = ["���������",
+ "testasdf",
+ "Row 3",
+ "Row 4",
+ "Row 5",
+ "Row 6",
+ "Row 7",
+ "Row 8",
+ "Row 9",
+ "Row 10",
+ "Row 11",
+ "Row 12"],
+
+ UnicodeIn = lists:map(fun(S) ->
+ unicode:characters_to_binary(S,latin1,{utf16,little})
+ end,
+ Latin1Data),
+
+ test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
+
+ {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
+ [{{CharType, Size},UnicodeIn}]),
+
+ {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
+
+ test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+
+ PadResult = lists:map(fun({Unicode}) ->
+ unicode:characters_to_list(Unicode,{utf16,little})
+ end,
+ UnicodeOut),
+
+ test_server:format("Result: ~p~n", [PadResult]),
+
+ Result = lists:map(fun(Str) -> string:strip(Str) end, PadResult),
+
+ Latin1Data = Result.
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
index 8b8d1e7a40..1852678b4b 100644
--- a/lib/odbc/test/odbc_query_SUITE.erl
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -43,19 +43,22 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
case odbc_test_lib:odbc_check() of
ok ->
- [sql_query, first, last, next, prev, select_count,
+ [sql_query, next, {group, scrollable_cursors}, select_count,
select_next, select_relative, select_absolute,
create_table_twice, delete_table_twice, duplicate_key,
not_connection_owner, no_result_set, query_error,
- multiple_select_result_sets, multiple_mix_result_sets,
- multiple_result_sets_error,
+ {group, multiple_result_sets},
{group, parameterized_queries}, {group, describe_table},
delete_nonexisting_row];
Other -> {skip, Other}
end.
groups() ->
- [{parameterized_queries, [],
+ [{multiple_result_sets, [], [multiple_select_result_sets,
+ multiple_mix_result_sets,
+ multiple_result_sets_error]},
+ {scrollable_cursors, [], [first, last, prev]},
+ {parameterized_queries, [],
[{group, param_integers}, param_insert_decimal,
param_insert_numeric, {group, param_insert_string},
param_insert_float, param_insert_real,
@@ -72,15 +75,27 @@ groups() ->
[describe_integer, describe_string, describe_floating,
describe_dec_num, describe_no_such_table]}].
-init_per_group(_GroupName, Config) ->
+init_per_group(multiple_result_sets, Config) ->
+ case is_supported_multiple_resultsets(?RDBMS) of
+ true ->
+ Config;
+ false ->
+ {skip, "Not supported by " ++ atom_to_list(?RDBMS) ++ "driver"}
+ end;
+init_per_group(scrollable_cursors, Config) ->
+ case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of
+ off ->
+ {skip, "Not supported by driver"};
+ _ ->
+ Config
+ end;
+
+init_per_group(_,Config) ->
Config.
end_per_group(_GroupName, Config) ->
Config.
-
-
-
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -91,8 +106,17 @@ end_per_group(_GroupName, Config) ->
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) when is_list(Config) ->
- application:start(odbc),
- [{tableName, odbc_test_lib:unique_table_name()}| Config].
+ case odbc_test_lib:skip() of
+ true ->
+ {skip, "ODBC not supported"};
+ false ->
+ case (catch odbc:start()) of
+ ok ->
+ [{tableName, odbc_test_lib:unique_table_name()}| Config];
+ _ ->
+ {skip, "ODBC not startable"}
+ end
+ end.
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
@@ -117,7 +141,8 @@ end_per_suite(_Config) ->
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_testcase(_Case, Config) ->
- {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
+ odbc_test_lib:strict(Ref, ?RDBMS),
Dog = test_server:timetrap(?default_timeout),
Temp = lists:keydelete(connection_ref, 1, Config),
NewConfig = lists:keydelete(watchdog, 1, Temp),
@@ -136,7 +161,7 @@ end_per_testcase(_Case, Config) ->
ok = odbc:disconnect(Ref),
%% Clean up if needed
Table = ?config(tableName, Config),
- {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
odbc:disconnect(NewRef),
Dog = ?config(watchdog, Config),
@@ -663,9 +688,6 @@ multiple_result_sets_error(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
-%%-------------------------------------------------------------------------
param_insert_tiny_int(doc)->
["Test insertion of tiny ints by parameterized queries."];
param_insert_tiny_int(suite) ->
@@ -901,8 +923,6 @@ param_insert_numeric(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
param_insert_char(doc)->
["Test insertion of fixed length string by parameterized queries."];
param_insert_char(suite) ->
@@ -1325,8 +1345,6 @@ param_select(Config) when is_list(Config) ->
ok.
%%-------------------------------------------------------------------------
-
-%%-------------------------------------------------------------------------
describe_integer(doc) ->
["Test describe_table/[2,3] for integer columns."];
describe_integer(suite) ->
@@ -1338,7 +1356,7 @@ describe_integer(Config) when is_list(Config) ->
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (int1 SMALLINT, int2 INT, int3 INTEGER)"),
+ " (myint1 SMALLINT, myint2 INT, myint3 INTEGER)"),
Decs = ?RDBMS:describe_integer(),
%% Make sure to test timeout clause
@@ -1399,7 +1417,7 @@ describe_dec_num(Config) when is_list(Config) ->
{updated, _} =
odbc:sql_query(Ref,
"CREATE TABLE " ++ Table ++
- " (dec DECIMAL(9,3), num NUMERIC(9,2))"),
+ " (mydec DECIMAL(9,3), mynum NUMERIC(9,2))"),
Decs = ?RDBMS:describe_dec_num(),
@@ -1451,3 +1469,7 @@ is_driver_error(Error) ->
false ->
test_server:fail(Error)
end.
+is_supported_multiple_resultsets(sqlserver) ->
+ true;
+is_supported_multiple_resultsets(_) ->
+ false.
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
index 65b990133f..e3a3440559 100644
--- a/lib/odbc/test/odbc_start_SUITE.erl
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -39,11 +39,18 @@
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
init_per_suite(Config) ->
- case code:which(odbc) of
- non_existing ->
- {skip, "No ODBC built"};
- _ ->
- [{tableName, odbc_test_lib:unique_table_name()} | Config]
+ case odbc_test_lib:skip() of
+ true ->
+ {skip, "ODBC not supported"};
+ false ->
+ case code:which(odbc) of
+ non_existing ->
+ {skip, "No ODBC built"};
+ _ ->
+ %% Make sure odbc is not already started
+ odbc:stop(),
+ [{tableName, odbc_test_lib:unique_table_name()} | Config]
+ end
end.
%%--------------------------------------------------------------------
@@ -125,14 +132,16 @@ start(doc) ->
start(suite) ->
[];
start(Config) when is_list(Config) ->
- {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(), []),
+ PlatformOptions = odbc_test_lib:platform_options(),
+ {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(),
+ PlatformOptions),
odbc:start(),
- case odbc:connect(?RDBMS:connection_string(), []) of
+ case odbc:connect(?RDBMS:connection_string(), PlatformOptions) of
{ok, Ref0} ->
ok = odbc:disconnect(Ref0),
odbc:stop(),
{error,odbc_not_started} =
- odbc:connect(?RDBMS:connection_string(), []),
+ odbc:connect(?RDBMS:connection_string(), PlatformOptions),
start_odbc(transient),
start_odbc(permanent);
{error, odbc_not_started} ->
@@ -144,7 +153,7 @@ start(Config) when is_list(Config) ->
start_odbc(Type) ->
ok = odbc:start(Type),
- case odbc:connect(?RDBMS:connection_string(), []) of
+ case odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()) of
{ok, Ref} ->
ok = odbc:disconnect(Ref),
odbc:stop();
diff --git a/lib/odbc/test/odbc_test.hrl b/lib/odbc/test/odbc_test.hrl
index 87f50043db..f7bb338a7f 100644
--- a/lib/odbc/test/odbc_test.hrl
+++ b/lib/odbc/test/odbc_test.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,9 +25,16 @@
-define(RDBMS, case os:type() of
{unix, sunos} ->
- postgres;
+ mysql;
{unix,linux} ->
- postgres;
+ case erlang:system_info({wordsize, external}) of
+ 4 ->
+ mysql;
+ _ ->
+ postgres
+ end;
+ {unix, darwin} ->
+ mysql;
{win32, _} ->
sqlserver
end).
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
index 012eb96e43..2d6bf5fcac 100644
--- a/lib/odbc/test/odbc_test_lib.erl
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,20 +36,9 @@ match_float(Float, Match, Delta) ->
(Float < Match + Delta) and (Float > Match - Delta).
odbc_check() ->
- case erlang:system_info(wordsize) of
+ case erlang:system_info({wordsize, external}) of
4 ->
- case test_server:os_type() of
- {unix, sunos} ->
- ok;
- {unix, linux} ->
- ok;
- {win32, _} ->
- ok;
- Other ->
- lists:flatten(
- io_lib:format("Platform not supported: ~w",
- [Other]))
- end;
+ ok;
Other ->
case os:type() of
{unix, linux} ->
@@ -75,3 +64,43 @@ check_row_count(Expected, Count) ->
to_upper(List) ->
lists:map(fun(Str) -> string:to_upper(Str) end, List).
+
+strict(Ref, mysql) ->
+ odbc:sql_query(Ref, "SET sql_mode='STRICT_ALL_TABLES,STRICT_TRANS_TABLES';");
+strict(_,_) ->
+ ok.
+
+platform_options() ->
+ [].
+
+skip() ->
+ case os:type() of
+ {unix, linux} ->
+ Issue = linux_issue(),
+ is_sles9(Issue);
+ {unix, sunos} ->
+ not supported_solaris();
+ _ ->
+ false
+ end.
+
+supported_solaris() ->
+ case os:version() of
+ {_,10,_} ->
+ true;
+ _ ->
+ false
+ end.
+
+linux_issue() ->
+ {ok, Binary} = file:read_file("/etc/issue"),
+ string:tokens(binary_to_list(Binary), " ").
+
+is_sles11(IssueTokens) ->
+ lists:member(11, IssueTokens).
+
+is_sles10(IssueTokens) ->
+ lists:member(10, IssueTokens).
+
+is_sles9(IssueTokens) ->
+ lists:member(9, IssueTokens).
diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl
index ebf6dbb6bf..d74863d8c1 100644
--- a/lib/odbc/test/oracle.erl
+++ b/lib/odbc/test/oracle.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -108,10 +108,6 @@ create_text_table() ->
" (FIELD long)". %Oracle long is variable length char data
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD nvarchar(50))".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD DATETIME)".
@@ -231,8 +227,8 @@ param_select() ->
%-------------------------------------------------------------------------
describe_integer() ->
- {ok,[{"INT1",{sql_decimal,38,0}},{"INT2",{sql_decimal,38,0}},
- {"INT3",{sql_decimal,38,0}}]}.
+ {ok,[{"MYINT1",{sql_decimal,38,0}},{"MYINT2",{sql_decimal,38,0}},
+ {"MYINT3",{sql_decimal,38,0}}]}.
describe_string() ->
{ok,[{"STR1",{sql_char,10}},
@@ -243,4 +239,4 @@ describe_string() ->
describe_floating() ->
{ok,[{"F",sql_double},{"R",sql_double},{"D",sql_double}]}.
describe_dec_num() ->
- {ok,[{"DEC",{sql_decimal,9,3}},{"NUM",{sql_decimal,9,2}}]}.
+ {ok,[{"MYDEC",{sql_decimal,9,3}},{"MYNUM",{sql_decimal,9,2}}]}.
diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl
index 169ca26e43..d564dbd5ff 100644
--- a/lib/odbc/test/postgres.erl
+++ b/lib/odbc/test/postgres.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,7 +30,7 @@ connection_string() ->
{unix, sunos} ->
"DSN=Postgres;UID=odbctest";
{unix, linux} ->
- Size = erlang:system_info(wordsize),
+ Size = erlang:system_info({wordsize, external}),
linux_dist_connection_string(Size)
end.
@@ -43,7 +43,12 @@ linux_dist_connection_string(4) ->
end;
linux_dist_connection_string(_) ->
- "DSN=PostgresLinux64;UID=odbctest".
+ case linux_dist() of
+ "ubuntu" ->
+ "DSN=PostgresLinux64Ubuntu;UID=odbctest";
+ _ ->
+ "DSN=PostgresLinux64;UID=odbctest"
+ end.
linux_dist() ->
case file:read_file("/etc/issue") of
@@ -135,10 +140,6 @@ create_text_table() ->
" (FIELD text)".
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD text)".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD TIMESTAMP)".
@@ -275,9 +276,9 @@ param_select() ->
%-------------------------------------------------------------------------
describe_integer() ->
- {ok,[{"int1",sql_smallint},
- {"int2",sql_integer},
- {"int3",sql_integer}]}.
+ {ok,[{"myint1",sql_smallint},
+ {"myint2",sql_integer},
+ {"myint3",sql_integer}]}.
describe_string() ->
{ok,[{"str1",{sql_char,10}},
@@ -288,7 +289,7 @@ describe_string() ->
describe_floating() ->
{ok,[{"f",sql_real},{"r",sql_real},{"d",{sql_float,15}}]}.
describe_dec_num() ->
- {ok,[{"dec",{sql_numeric,9,3}},{"num",{sql_numeric,9,2}}]}.
+ {ok,[{"mydec",{sql_numeric,9,3}},{"mynum",{sql_numeric,9,2}}]}.
describe_timestamp() ->
{ok, [{"field", sql_timestamp}]}.
diff --git a/lib/odbc/test/sqlserver.erl b/lib/odbc/test/sqlserver.erl
index e3fe30e0bc..59252d4276 100644
--- a/lib/odbc/test/sqlserver.erl
+++ b/lib/odbc/test/sqlserver.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -123,10 +123,6 @@ create_text_table() ->
" (FIELD text)".
%-------------------------------------------------------------------------
-create_unicode_table() ->
- " (FIELD nvarchar(50))".
-
-%-------------------------------------------------------------------------
create_timestamp_table() ->
" (FIELD DATETIME)".
@@ -279,8 +275,8 @@ param_select() ->
%-------------------------------------------------------------------------
describe_integer() ->
- {ok,[{"int1", sql_smallint},{"int2", sql_integer},
- {"int3", sql_integer}]}.
+ {ok,[{"myint1", sql_smallint},{"myint2", sql_integer},
+ {"myint3", sql_integer}]}.
describe_string() ->
{ok,[{"str1",{sql_char,10}},
@@ -292,7 +288,7 @@ describe_floating() ->
{ok,[{"f", sql_real},{"r", sql_real}, {"d", {sql_float, 53}}]}.
describe_dec_num() ->
- {ok,[{"dec",{sql_decimal,9,3}},{"num",{sql_numeric,9,2}}]}.
+ {ok,[{"mydec",{sql_decimal,9,3}},{"mynum",{sql_numeric,9,2}}]}.
describe_timestamp() ->
{ok, [{"field", sql_timestamp}]}.
diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk
index 42a51be33e..120ed9ee3d 100644
--- a/lib/odbc/vsn.mk
+++ b/lib/odbc/vsn.mk
@@ -1 +1 @@
-ODBC_VSN = 2.10.10
+ODBC_VSN = 2.10.11
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 589123ef73..231872f958 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,6 +33,22 @@
</header>
<section>
+ <title>Orber 3.6.21</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ Eliminated Dialyzer warnings.</p>
+ <p>
+ Own Id: OTP-9326 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>Orber 3.6.20</title>
<section>
diff --git a/lib/orber/src/orber.erl b/lib/orber/src/orber.erl
index 665b3cb383..386c07d227 100644
--- a/lib/orber/src/orber.erl
+++ b/lib/orber/src/orber.erl
@@ -245,7 +245,7 @@ create_nodes(Host, N, Port, Options, Errors, NodeData) ->
create_node(Host, Port, Options) ->
- case slave:start_link(Host, Port) of
+ case slave:start_link(Host, list_to_atom(integer_to_list(Port))) of
{ok, NewNode} ->
case net_adm:ping(NewNode) of
pong ->
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 5f17cda229..35aabd51cd 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1,3 +1,3 @@
-ORBER_VSN = 3.6.20
+ORBER_VSN = 3.6.21
diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml
index 1062b07dfd..3b5dbe3146 100644
--- a/lib/os_mon/doc/src/notes.xml
+++ b/lib/os_mon/doc/src/notes.xml
@@ -30,6 +30,35 @@
</header>
<p>This document describes the changes made to the OS_Mon application.</p>
+<section><title>Os_Mon 2.2.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add NetBSD support to memsup and disksup (Thanks to
+ Andrew Thompson)</p>
+ <p>
+ Own Id: OTP-9216</p>
+ </item>
+ <item>
+ <p>
+ Add support for DragonFlyBSD to memsup</p>
+ <p>
+ DragonFly was partially supported by os_mon already but
+ when trying to start the os_mon application it'd crash
+ with an error about an unknown operating system in
+ memsup. This patch changes memsup to use the FreeBSD
+ sysctl method to get memory information when on
+ DragonFly. (Thanks to Andrew Thompson )</p>
+ <p>
+ Own Id: OTP-9217</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Os_Mon 2.2.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/os_mon/src/disksup.erl b/lib/os_mon/src/disksup.erl
index 3ee1df759f..308cd1b7fa 100644
--- a/lib/os_mon/src/disksup.erl
+++ b/lib/os_mon/src/disksup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl
index cc4941ee7d..ba07a529bc 100644
--- a/lib/os_mon/src/memsup.erl
+++ b/lib/os_mon/src/memsup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk
index ecc47e70d8..2d583a398b 100644
--- a/lib/os_mon/vsn.mk
+++ b/lib/os_mon/vsn.mk
@@ -1 +1 @@
-OS_MON_VSN = 2.2.5
+OS_MON_VSN = 2.2.6
diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml
index 12abfd244f..1fa426a79e 100644
--- a/lib/parsetools/doc/src/leex.xml
+++ b/lib/parsetools/doc/src/leex.xml
@@ -79,6 +79,10 @@ Token = tuple()</code>
<item><p>Causes warnings to be printed as they occur. Default is
<c>true</c>.</p>
</item>
+ <tag><c>warnings_as_errors</c></tag>
+ <item>
+ <p>Causes warnings to be treated as errors.</p>
+ </item>
<tag><c>{report, bool()}</c></tag>
<item><p>This is a short form for both <c>report_errors</c> and
<c>report_warnings</c>.</p>
diff --git a/lib/parsetools/doc/src/yecc.xml b/lib/parsetools/doc/src/yecc.xml
index 81f1550b0a..1d2a985d7d 100644
--- a/lib/parsetools/doc/src/yecc.xml
+++ b/lib/parsetools/doc/src/yecc.xml
@@ -95,6 +95,10 @@
<item>This is a short form for both <c>report_errors</c> and
<c>report_warnings</c>.
</item>
+ <tag><c>warnings_as_errors</c></tag>
+ <item>
+ <p>Causes warnings to be treated as errors.</p>
+ </item>
<tag><c>{return_errors, bool()}</c>.</tag>
<item>If this flag is set, <c>{error, Errors, Warnings}</c>
is returned when there are errors. Default is
@@ -421,9 +425,9 @@ myparser:parse_and_scan({Mod, Tokenizer, Args}) </code>
Nonterminals E T F.
Terminals '+' '*' '(' ')' number.
Rootsymbol E.
-E -> E '+' T: ['$1', '$2', '$3'].
+E -> E '+' T: ['$2', '$1', '$3'].
E -> T : '$1'.
-T -> T '*' F: ['$1', '$2', '$3'].
+T -> T '*' F: ['$2', '$1', '$3'].
T -> F : '$1'.
F -> '(' E ')' : '$2'.
F -> number : '$1'. </code>
@@ -434,8 +438,8 @@ Terminals '+' '*' '(' ')' number.
Rootsymbol E.
Left 100 '+'.
Left 200 '*'.
-E -> E '+' E : ['$1', '$2', '$3'].
-E -> E '*' E : ['$1', '$2', '$3'].
+E -> E '+' E : ['$2', '$1', '$3'].
+E -> E '*' E : ['$2', '$1', '$3'].
E -> '(' E ')' : '$2'.
E -> number : '$1'. </code>
<p>3. An overloaded minus operator:</p>
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index d0b4b9efe7..942e9928b1 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -35,7 +35,7 @@
-export([compile/3,file/1,file/2,format_error/1]).
-import(lists, [member/2,reverse/1,sort/1,delete/2,
- keysort/2,keydelete/3,keyfind/3,
+ keysort/2,keydelete/3,
map/2,foldl/3,foreach/2,flatmap/2]).
-import(string, [substr/2,substr/3,span/2]).
-import(ordsets, [is_element/2,add_element/2,union/2]).
@@ -58,7 +58,7 @@
gfile=[], % Graph file
module, % Module name
opts=[], % Options
- posix=false, % POSIX regular expressions
+ % posix=false, % POSIX regular expressions
errors=[],
warnings=[]
}).
@@ -107,10 +107,15 @@ file(File, Opts0) ->
St = try
{ok,REAs,Actions,Code,St2} = parse_file(St1),
{DFA,DF} = make_dfa(REAs, St2),
- St3 = out_file(St2, DFA, DF, Actions, Code),
- case lists:member(dfa_graph, St3#leex.opts) of
- true -> out_dfa_graph(St3, DFA, DF);
- false -> St3
+ case werr(St2) of
+ false ->
+ St3 = out_file(St2, DFA, DF, Actions, Code),
+ case lists:member(dfa_graph, St3#leex.opts) of
+ true -> out_dfa_graph(St3, DFA, DF);
+ false -> St3
+ end;
+ true ->
+ St2
end
catch #leex{}=St4 ->
St4
@@ -131,8 +136,8 @@ format_error({regexp,E})->
"unterminated " ++ Cs;
{illegal_char,Cs} ->
"illegal character " ++ Cs;
- {posix_cc,What} ->
- ["illegal POSIX character class ",io_lib:write_string(What)];
+%% {posix_cc,What} ->
+%% ["illegal POSIX character class ",io_lib:write_string(What)];
{char_class,What} ->
["illegal character class ",io_lib:write_string(What)]
end,
@@ -163,7 +168,8 @@ options(Options0) when is_list(Options0) ->
(T) -> [T]
end, Options0),
options(Options, [scannerfile,includefile,report_errors,
- report_warnings,return_errors,return_warnings,
+ report_warnings,warnings_as_errors,
+ return_errors,return_warnings,
verbose,dfa_graph], [])
catch error: _ -> badarg
end;
@@ -217,6 +223,7 @@ default_option(dfa_graph) -> false;
default_option(includefile) -> [];
default_option(report_errors) -> true;
default_option(report_warnings) -> true;
+default_option(warnings_as_errors) -> false;
default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(scannerfile) -> [];
@@ -225,6 +232,7 @@ default_option(verbose) -> false.
atom_option(dfa_graph) -> {dfa_graph,true};
atom_option(report_errors) -> {report_errors,true};
atom_option(report_warnings) -> {report_warnings,true};
+atom_option(warnings_as_errors) -> {warnings_as_errors,true};
atom_option(return_errors) -> {return_errors,true};
atom_option(return_warnings) -> {return_warnings,true};
atom_option(verbose) -> {verbose,true};
@@ -251,19 +259,29 @@ leex_ret(St) ->
report_warnings(St),
Es = pack_errors(St#leex.errors),
Ws = pack_warnings(St#leex.warnings),
+ Werr = werr(St),
if
+ Werr ->
+ do_error_return(St, Es, Ws);
Es =:= [] ->
case member(return_warnings, St#leex.opts) of
true -> {ok, St#leex.efile, Ws};
false -> {ok, St#leex.efile}
end;
- true ->
- case member(return_errors, St#leex.opts) of
- true -> {error, Es, Ws};
- false -> error
- end
+ true ->
+ do_error_return(St, Es, Ws)
end.
+do_error_return(St, Es, Ws) ->
+ case member(return_errors, St#leex.opts) of
+ true -> {error, Es, Ws};
+ false -> error
+ end.
+
+werr(St) ->
+ member(warnings_as_errors, St#leex.opts)
+ andalso length(St#leex.warnings) > 0.
+
pack_errors([{File,_} | _] = Es) ->
[{File, flatmap(fun({_,E}) -> [E] end, sort(Es))}];
pack_errors([]) ->
@@ -296,6 +314,7 @@ report_warnings(St) ->
end, sort(St#leex.warnings))
end, report_warnings, St#leex.opts).
+-spec add_error(_, #leex{}) -> no_return().
add_error(E, St) ->
add_error(St#leex.xfile, E, St).
@@ -644,14 +663,14 @@ re_repeat1([$*|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {kclosure,S}, St);
re_repeat1([$+|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {pclosure,S}, St);
re_repeat1([$?|Cs], Sn, S, St) -> re_repeat1(Cs, Sn, {optional,S}, St);
%% { only starts interval when ere is true, otherwise normal character.
-re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
- case re_interval_range(Cs0) of
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
- re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
- {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
- end;
+%% re_repeat1([${|Cs0], Sn, S, #leex{posix=true}=St) -> % $}
+%% case re_interval_range(Cs0) of
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_integer(Max), Min =< Max ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {Min,Max,[$}|Cs1]} when is_integer(Min), is_atom(Max) ->
+%% re_repeat1(Cs1, Sn, {interval,S,Min,Max}, St);
+%% {_,_,Cs1} -> parse_error({interval_range,string_between([${|Cs0], Cs1)})
+%% end;
re_repeat1(Cs, Sn, S, _) -> {S,Sn,Cs}.
%% re_single(Chars, SubNumber, State) -> {RegExp,SubNumber,Chars}.
@@ -733,7 +752,7 @@ special_char($|, _) -> true;
special_char($*, _) -> true;
special_char($+, _) -> true;
special_char($?, _) -> true;
-special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
+%% special_char(${, #leex{posix=true}) -> true; % Only when POSIX set
special_char($\\, _) -> true;
special_char(_, _) -> false.
@@ -744,12 +763,12 @@ re_char_class([$]|Cs], St) -> % Must special case this.
re_char_class(Cs, [$]], St);
re_char_class(Cs, St) -> re_char_class(Cs, [], St).
-re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
- %% POSIX char class only.
- case posix_cc(Cs0) of
- {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
- {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
- end;
+%% re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
+%% %% POSIX char class only.
+%% case posix_cc(Cs0) of
+%% {Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
+%% {_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
+%% end;
re_char_class([C1|Cs0], Cc, St) when C1 =/= $] ->
case re_char(C1, Cs0) of
{Cf,[$-,C2|Cs1]} when C2 =/= $] ->
@@ -766,19 +785,19 @@ re_char_class(Cs, Cc, _) -> {reverse(Cc),Cs}. % Preserve order
%% posix_cc(String) -> {PosixClass,RestString}.
%% Handle POSIX character classes.
-posix_cc("alnum" ++ Cs) -> {alnum,Cs};
-posix_cc("alpha" ++ Cs) -> {alpha,Cs};
-posix_cc("blank" ++ Cs) -> {blank,Cs};
-posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
-posix_cc("digit" ++ Cs) -> {digit,Cs};
-posix_cc("graph" ++ Cs) -> {graph,Cs};
-posix_cc("lower" ++ Cs) -> {lower,Cs};
-posix_cc("print" ++ Cs) -> {print,Cs};
-posix_cc("punct" ++ Cs) -> {punct,Cs};
-posix_cc("space" ++ Cs) -> {space,Cs};
-posix_cc("upper" ++ Cs) -> {upper,Cs};
-posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
-posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
+%% posix_cc("alnum" ++ Cs) -> {alnum,Cs};
+%% posix_cc("alpha" ++ Cs) -> {alpha,Cs};
+%% posix_cc("blank" ++ Cs) -> {blank,Cs};
+%% posix_cc("cntrl" ++ Cs) -> {cntrl,Cs};
+%% posix_cc("digit" ++ Cs) -> {digit,Cs};
+%% posix_cc("graph" ++ Cs) -> {graph,Cs};
+%% posix_cc("lower" ++ Cs) -> {lower,Cs};
+%% posix_cc("print" ++ Cs) -> {print,Cs};
+%% posix_cc("punct" ++ Cs) -> {punct,Cs};
+%% posix_cc("space" ++ Cs) -> {space,Cs};
+%% posix_cc("upper" ++ Cs) -> {upper,Cs};
+%% posix_cc("xdigit" ++ Cs) -> {xdigit,Cs};
+%% posix_cc(Cs) -> parse_error({posix_cc,substr(Cs, 1, 5)}).
escape_char($n) -> $\n; % \n = LF
escape_char($r) -> $\r; % \r = CR
@@ -797,24 +816,24 @@ escape_char(C) -> C. % Pass it straight through
%% Int, -> Int,any
%% Int1,Int2 -> Int1,Int2
-re_interval_range(Cs0) ->
- case re_number(Cs0) of
- {none,Cs1} -> {none,none,Cs1};
- {N,[$,|Cs1]} ->
- case re_number(Cs1) of
- {none,Cs2} -> {N,any,Cs2};
- {M,Cs2} -> {N,M,Cs2}
- end;
- {N,Cs1} -> {N,none,Cs1}
- end.
+%% re_interval_range(Cs0) ->
+%% case re_number(Cs0) of
+%% {none,Cs1} -> {none,none,Cs1};
+%% {N,[$,|Cs1]} ->
+%% case re_number(Cs1) of
+%% {none,Cs2} -> {N,any,Cs2};
+%% {M,Cs2} -> {N,M,Cs2}
+%% end;
+%% {N,Cs1} -> {N,none,Cs1}
+%% end.
-re_number([C|Cs]) when C >= $0, C =< $9 ->
- re_number(Cs, C - $0);
-re_number(Cs) -> {none,Cs}.
+%% re_number([C|Cs]) when C >= $0, C =< $9 ->
+%% re_number(Cs, C - $0);
+%% re_number(Cs) -> {none,Cs}.
-re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
- re_number(Cs, 10*Acc + (C - $0));
-re_number(Cs, Acc) -> {Acc,Cs}.
+%% re_number([C|Cs], Acc) when C >= $0, C =< $9 ->
+%% re_number(Cs, 10*Acc + (C - $0));
+%% re_number(Cs, Acc) -> {Acc,Cs}.
string_between(Cs1, Cs2) ->
substr(Cs1, 1, length(Cs1)-length(Cs2)).
diff --git a/lib/parsetools/src/yecc.erl b/lib/parsetools/src/yecc.erl
index 4119e2631b..72cff3af92 100644
--- a/lib/parsetools/src/yecc.erl
+++ b/lib/parsetools/src/yecc.erl
@@ -278,8 +278,8 @@ options(Options0) when is_list(Options0) ->
(T) -> [T]
end, Options0),
options(Options, [file_attributes, includefile, parserfile,
- report_errors, report_warnings, return_errors,
- return_warnings, time, verbose], [])
+ report_errors, report_warnings, warnings_as_errors,
+ return_errors, return_warnings, time, verbose], [])
catch error: _ -> badarg
end;
options(Option) ->
@@ -333,6 +333,7 @@ default_option(includefile) -> [];
default_option(parserfile) -> [];
default_option(report_errors) -> true;
default_option(report_warnings) -> true;
+default_option(warnings_as_errors) -> false;
default_option(return_errors) -> false;
default_option(return_warnings) -> false;
default_option(time) -> false;
@@ -341,6 +342,7 @@ default_option(verbose) -> false.
atom_option(file_attributes) -> {file_attributes, true};
atom_option(report_errors) -> {report_errors, true};
atom_option(report_warnings) -> {report_warnings, true};
+atom_option(warnings_as_errors) -> {warnings_as_errors,true};
atom_option(return_errors) -> {return_errors, true};
atom_option(return_warnings) -> {return_warnings, true};
atom_option(time) -> {time, true};
@@ -409,12 +411,16 @@ infile(Parent, Infilex, Options) ->
{error, Reason} ->
add_error(St0#yecc.infile, none, {file_error, Reason}, St0)
end,
- case St#yecc.errors of
- [] -> ok;
+ case {St#yecc.errors, werr(St)} of
+ {[], false} -> ok;
_ -> _ = file:delete(St#yecc.outfile)
end,
Parent ! {self(), yecc_ret(St)}.
+werr(St) ->
+ member(warnings_as_errors, St#yecc.options)
+ andalso length(St#yecc.warnings) > 0.
+
outfile(St0) ->
case file:open(St0#yecc.outfile, [write, delayed_write]) of
{ok, Outport} ->
@@ -777,17 +783,23 @@ yecc_ret(St0) ->
report_warnings(St),
Es = pack_errors(St#yecc.errors),
Ws = pack_warnings(St#yecc.warnings),
+ Werr = werr(St),
if
+ Werr ->
+ do_error_return(St, Es, Ws);
Es =:= [] ->
case member(return_warnings, St#yecc.options) of
true -> {ok, St#yecc.outfile, Ws};
false -> {ok, St#yecc.outfile}
end;
true ->
- case member(return_errors, St#yecc.options) of
- true -> {error, Es, Ws};
- false -> error
- end
+ do_error_return(St, Es, Ws)
+ end.
+
+do_error_return(St, Es, Ws) ->
+ case member(return_errors, St#yecc.options) of
+ true -> {error, Es, Ws};
+ false -> error
end.
check_expected(St0) ->
diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl
index 23ad16f98d..48312445ef 100644
--- a/lib/parsetools/test/leex_SUITE.erl
+++ b/lib/parsetools/test/leex_SUITE.erl
@@ -152,6 +152,19 @@ file(Config) when is_list(Config) ->
?line writable(Dotfile),
file:delete(Dotfile),
+ Warn = <<"Definitions.1998\n"
+ "D = [0-9]\n"
+ "Rules.\n"
+ "{L}+ : {token,{word,TokenLine,TokenChars}}.\n"
+ "Erlang code.\n">>,
+ ok = file:write_file(Filename, Warn),
+ error = leex:file(Filename, [warnings_as_errors]),
+ error = leex:file(Filename, [return_warnings,warnings_as_errors]),
+ {ok,Scannerfile,[{Filename,[{1,leex,ignored_characters}]}]} =
+ leex:file(Filename, [return_warnings]),
+ {error,_,[{Filename,[{1,leex,ignored_characters}]}]} =
+ leex:file(Filename, [return_errors,warnings_as_errors]),
+
file:delete(Filename),
ok.
@@ -551,7 +564,7 @@ ex2(Config) when is_list(Config) ->
<<"
%%% File : erlang_scan.xrl
%%% Author : Robert Virding
-%%% Purpose : Tkoen definitions for Erlang.
+%%% Purpose : Token definitions for Erlang.
Definitions.
O = [0-7]
diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl
index 1de87b3bff..0133524950 100644
--- a/lib/parsetools/test/yecc_SUITE.erl
+++ b/lib/parsetools/test/yecc_SUITE.erl
@@ -247,6 +247,14 @@ syntax(Config) when is_list(Config) ->
?line {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
yecc:file(Filename, Ret),
+ %% Bad declaration with warnings_as_errors.
+ error = yecc:file(Filename, [warnings_as_errors]),
+ error = yecc:file(Filename, [return_warnings,warnings_as_errors]),
+ {ok,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, [return_warnings]),
+ {error,_,[{_,[{2,yecc,bad_declaration}]}]} =
+ yecc:file(Filename, [return_errors,warnings_as_errors]),
+
%% Bad declaration.
?line ok = file:write_file(Filename,
<<"Nonterminals nt. Terminals t.
diff --git a/lib/percept/src/percept_db.erl b/lib/percept/src/percept_db.erl
index 52e9afb78f..61b68ce44f 100644
--- a/lib/percept/src/percept_db.erl
+++ b/lib/percept/src/percept_db.erl
@@ -92,7 +92,7 @@ restart(PerceptDB)->
stop_sync(PerceptDB),
do_start().
-%% @spec do_start(pid()) -> pid()
+%% @spec do_start() -> pid()
%% @private
%% @doc starts the percept database.
@@ -131,6 +131,7 @@ stop_sync(Pid)->
{'DOWN', MonitorRef, _Type, Pid, _Info}->
true
after ?STOP_TIMEOUT->
+ erlang:demonitor(MonitorRef, [flush]),
exit(Pid, kill)
end.
@@ -166,14 +167,14 @@ insert(Trace) ->
select(Query) ->
percept_db ! {select, self(), Query},
- receive Match -> Match end.
+ receive {result, Match} -> Match end.
%% @spec select(atom(), list()) -> Result
%% @equiv select({Table,Options})
select(Table, Options) ->
percept_db ! {select, self(), {Table, Options}},
- receive Match -> Match end.
+ receive {result, Match} -> Match end.
%% @spec consolidate() -> Result
%% @doc Checks timestamp and state-flow inconsistencies in the
@@ -213,7 +214,7 @@ loop_percept_db() ->
insert_trace(clean_trace(Trace)),
loop_percept_db();
{select, Pid, Query} ->
- Pid ! select_query(Query),
+ Pid ! {result, select_query(Query)},
loop_percept_db();
{action, stop} ->
stopped;
@@ -222,7 +223,7 @@ loop_percept_db() ->
loop_percept_db();
{operate, Pid, {Table, {Fun, Start}}} ->
Result = ets:foldl(Fun, Start, Table),
- Pid ! Result,
+ Pid ! {result, Result},
loop_percept_db();
Unhandled ->
io:format("loop_percept_db, unhandled query: ~p~n", [Unhandled]),
diff --git a/lib/public_key/asn1/README b/lib/public_key/asn1/README
index 5fb8cf9725..2a880e2d51 100644
--- a/lib/public_key/asn1/README
+++ b/lib/public_key/asn1/README
@@ -46,6 +46,6 @@ diff -r1.1 PKIXAttributeCertificate.asn1
---
> version AttCertVersion, -- version is v2
-4. Defenitions of publuic keys from PKCS-1.asn1 present in
+4. Definitions of public keys from PKCS-1.asn1 present in
PKIX1Algorithms88.asn1 where removed as we take them directly from
PKCS-1.asn1 \ No newline at end of file
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index 30326da114..9d77750ea2 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -34,6 +34,22 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 0.12</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The public_key application now supports encode/decode of
+ ssh public-key files.</p>
+ <p>
+ Own Id: OTP-9144</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 0.11</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index d60d91cd83..9a3832c68b 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -63,7 +63,7 @@
<p><code>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey'
'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo'</code></p>
- <p><code>pem_entry () = {pki_asn1_type(), binary() %% DER or encrypted DER
+ <p><code>pem_entry () = {pki_asn1_type(), binary(), %% DER or encrypted DER
not_encrypted | {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}}.</code></p>
<p><code>rsa_public_key() = #'RSAPublicKey'{}</code></p>
@@ -72,8 +72,6 @@
<p><code>dsa_public_key() = {integer(), #'Dss-Parms'{}} </code></p>
- <p><code>rsa_private_key() = #'RSAPrivateKey'{} </code></p>
-
<p><code>dsa_private_key() = #'DSAPrivateKey'{}</code></p>
<p><code> public_crypt_options() = [{rsa_pad, rsa_padding()}]. </code></p>
@@ -149,7 +147,7 @@
<name>der_decode(Asn1type, Der) -> term()</name>
<fsummary> Decodes a public key asn1 der encoded entity.</fsummary>
<type>
- <v>Asn1Type = atom() -</v>
+ <v>Asn1Type = atom()</v>
<d> ASN.1 type present in the public_key applications
asn1 specifications.</d>
<v>Der = der_encoded()</v>
@@ -166,7 +164,8 @@
<v>Asn1Type = atom()</v>
<d> Asn1 type present in the public_key applications
ASN.1 specifications.</d>
- <v>Entity = term() - The erlang representation of <c> Asn1Type</c></v>
+ <v>Entity = term()</v>
+ <d>The erlang representation of <c>Asn1Type</c></d>
</type>
<desc>
<p> Encodes a public key entity with ASN.1 DER encoding.</p>
@@ -218,12 +217,13 @@
<fsummary> Creates a pem entry that can be fed to pem_encode/1.</fsummary>
<type>
<v>Asn1Type = pki_asn1_type()</v>
- <v>Entity = term() - The Erlang representation of
+ <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
'SubjectPublicKeyInfo' entry.
- </v>
+ </d>
<v>CipherInfo = {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}</v>
<v>Password = string()</v>
</type>
@@ -281,7 +281,7 @@
<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 on the otp format, whereas for the plain format this
+ that are decoded/created in the otp format, whereas for the plain format this
function will directly call der_encode/2. </p>
</desc>
</func>
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 2901020e83..33fcce2c44 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -488,9 +488,10 @@ pkix_path_validation(PathErr, [Cert | Chain], Options0) when is_atom(PathErr)->
_:_ ->
{error, Reason}
end;
-pkix_path_validation(TrustedCert, CertChain, Options) when
- is_binary(TrustedCert) -> OtpCert = pkix_decode_cert(TrustedCert,
- otp), pkix_path_validation(OtpCert, CertChain, Options);
+pkix_path_validation(TrustedCert, CertChain, Options)
+ when is_binary(TrustedCert) ->
+ OtpCert = pkix_decode_cert(TrustedCert, otp),
+ pkix_path_validation(OtpCert, CertChain, Options);
pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
when is_list(CertChain), is_list(Options) ->
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index a791f2ce03..324d69675e 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -37,7 +37,33 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.5.5</title>
+ <section><title>Reltool 0.5.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The system level option <c>app_files</c> is documented to
+ allow the values <c>keep | strip | all</c>, but it only
+ allowed <c>keep</c>. This is corrected.</p>
+ <p>
+ Own Id: OTP-9135</p>
+ </item>
+ <item>
+ <p>
+ Allow the same module name in multiple applications
+ visible to reltool, as long as all but one of the
+ applications/modules are explicitely excluded. (Thanks to
+ Andrew Gopienko and Jay Nelson)</p>
+ <p>
+ Own Id: OTP-9229</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.5.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl
index 76c064f1e7..8b0f64eb45 100644
--- a/lib/reltool/src/reltool_sys_win.erl
+++ b/lib/reltool/src/reltool_sys_win.erl
@@ -54,7 +54,9 @@
whitelist,
blacklist,
derived,
- fgraph_wins
+ fgraph_wins,
+ app_box,
+ mod_box
}).
-define(WIN_WIDTH, 800).
@@ -86,6 +88,11 @@
-define(blacklist, "Excluded").
-define(derived, "Derived").
+-define(safe_config,{sys,[{incl_cond,exclude},
+ {app,kernel,[{incl_cond,include}]},
+ {app,stdlib,[{incl_cond,include}]},
+ {app,sasl,[{incl_cond,include}]}]}).
+
-record(root_data, {dir}).
-record(lib_data, {dir, tree, item}).
-record(escript_data, {file, tree, item}).
@@ -102,7 +109,7 @@
start_link(Opts) ->
proc_lib:start_link(?MODULE,
init,
- [[{parent, self()} | Opts]],
+ [[{safe_config, false}, {parent, self()} | Opts]],
infinity,
[]).
@@ -126,53 +133,73 @@ init(Options) ->
exit({Reason, erlang:get_stacktrace()})
end.
-do_init([{parent, Parent} | Options]) ->
+do_init([{safe_config, Safe}, {parent, Parent} | Options]) ->
case reltool_server:start_link(Options) of
{ok, ServerPid, C, Sys} ->
process_flag(trap_exit, C#common.trap_exit),
- S = #state{parent_pid = Parent,
- server_pid = ServerPid,
- common = C,
- config_file = filename:absname("config.reltool"),
- target_dir = filename:absname("reltool_target_dir"),
- app_wins = [],
- sys = Sys,
- fgraph_wins = []},
wx:new(),
wx:debug(C#common.wx_debug),
- S2 = create_window(S),
%% wx_misc:beginBusyCursor(),
case reltool_server:get_status(ServerPid) of
{ok, Warnings} ->
exit_dialog(Warnings),
- {ok, Sys2} = reltool_server:get_sys(ServerPid),
- S3 = S2#state{sys = Sys2},
+ {ok, Sys} = reltool_server:get_sys(ServerPid),
+ S = #state{parent_pid = Parent,
+ server_pid = ServerPid,
+ common = C,
+ config_file = filename:absname("config.reltool"),
+ target_dir = filename:absname("reltool_target_dir"),
+ app_wins = [],
+ sys = Sys,
+ fgraph_wins = []},
+ S2 = create_window(S),
S5 = wx:batch(fun() ->
Title = atom_to_list(?APPLICATION),
- wxFrame:setTitle(S3#state.frame,
+ wxFrame:setTitle(S2#state.frame,
Title),
%% wxFrame:setMinSize(Frame,
%% {?WIN_WIDTH, ?WIN_HEIGHT}),
wxStatusBar:setStatusText(
- S3#state.status_bar,
+ S2#state.status_bar,
"Done."),
- S4 = redraw_apps(S3),
- redraw_libs(S4)
+ S3 = redraw_apps(S2),
+ S4 = redraw_libs(S3),
+ redraw_config_page(S4)
end),
%% wx_misc:endBusyCursor(),
%% wxFrame:destroy(Frame),
proc_lib:init_ack(S#state.parent_pid, {ok, self()}),
loop(S5);
{error, Reason} ->
- io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
- exit(Reason)
+ restart_server_safe_config(Safe,Parent,Reason)
end;
{error, Reason} ->
io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
exit(Reason)
end.
+restart_server_safe_config(true,_Parent,Reason) ->
+ io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
+ exit(Reason);
+restart_server_safe_config(false,Parent,Reason) ->
+ Strings =
+ [{?wxBLACK,"Could not start reltool server:\n\n"},
+ {?wxRED,Reason++"\n\n"},
+ {?wxBLACK,
+ io_lib:format(
+ "Resetting the configuration to:~n~n ~p~n~n"
+ "Do you want to continue with this configuration?",
+ [?safe_config])}],
+
+ case question_dialog_2("Reltool server start error", Strings) of
+ ?wxID_OK ->
+ do_init([{safe_config,true},{parent,Parent},?safe_config]);
+ ?wxID_CANCEL ->
+ io:format("~p(~p): <ERROR> ~p\n", [?MODULE, ?LINE, Reason]),
+ exit(Reason)
+ end.
+
exit_dialog([]) ->
ok;
exit_dialog(Warnings) ->
@@ -606,6 +633,13 @@ create_config_page(#state{sys = Sys, book = Book} = S) ->
{proportion, 1}]),
wxPanel:setSizer(Panel, Sizer),
wxNotebook:addPage(Book, Panel, ?SYS_PAGE, []),
+ S#state{app_box = AppBox, mod_box = ModBox}.
+
+redraw_config_page(#state{sys = Sys, app_box = AppBox, mod_box = ModBox} = S) ->
+ AppChoice = reltool_utils:incl_cond_to_index(Sys#sys.incl_cond),
+ wxRadioBox:setSelection(AppBox, AppChoice),
+ ModChoice = reltool_utils:mod_cond_to_index(Sys#sys.mod_cond),
+ wxRadioBox:setSelection(ModBox, ModChoice),
S.
create_main_release_page(#state{book = Book} = S) ->
@@ -640,15 +674,15 @@ create_main_release_page(#state{book = Book} = S) ->
add_release_page(Book, #rel{name = RelName, rel_apps = RelApps}) ->
Panel = wxPanel:new(Book, []),
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
- RelBox = wxRadioBox:new(Panel,
- ?wxID_ANY,
- "Applications included in the release " ++ RelName,
- ?wxDefaultPosition,
- ?wxDefaultSize,
- [atom_to_list(RA#rel_app.name) || RA <- RelApps],
- []),
- %% wxRadioBox:setSelection(RelBox, 2), % mandatory
- wxEvtHandler:connect(RelBox, command_radiobox_selected,
+ AppNames = [kernel, stdlib |
+ [RA#rel_app.name || RA <- RelApps] -- [kernel, stdlib]],
+ RelBox = wxListBox:new(
+ Panel,?wxID_ANY,
+ [{pos,?wxDefaultPosition},
+ {size,?wxDefaultSize},
+ {choices,[[atom_to_list(AppName)] || AppName <- AppNames]},
+ {style,?wxLB_EXTENDED}]),
+ wxEvtHandler:connect(RelBox, command_listbox_selected,
[{userData, {config_rel_cond, RelName}}]),
RelToolTip = "Choose which applications that shall "
"be included in the release resource file.",
@@ -1363,7 +1397,8 @@ refresh(S) ->
[ok = reltool_app_win:refresh(AW#app_win.pid) || AW <- S#state.app_wins],
S2 = S#state{sys = Sys},
S3 = redraw_libs(S2),
- redraw_apps(S3).
+ S4 = redraw_apps(S3),
+ redraw_config_page(S4).
question_dialog(Question, Details) ->
%% Parent = S#state.frame,
@@ -1420,6 +1455,44 @@ display_message(Message, Icon) ->
wxMessageDialog:showModal(Dialog),
wxMessageDialog:destroy(Dialog).
+%% Strings = [{Color,String}]
+question_dialog_2(DialogLabel, Strings) ->
+ %% Parent = S#state.frame,
+ Parent = wx:typeCast(wx:null(), wxWindow),
+ %% [{style, ?wxYES_NO bor ?wxICON_ERROR bor ?wx}]),
+ DialogStyle = ?wxRESIZE_BORDER bor ?wxCAPTION bor ?wxSYSTEM_MENU bor
+ ?wxMINIMIZE_BOX bor ?wxMAXIMIZE_BOX bor ?wxCLOSE_BOX,
+ Dialog = wxDialog:new(Parent, ?wxID_ANY, DialogLabel,
+ [{style, DialogStyle}]),
+ Color = wxWindow:getBackgroundColour(Dialog),
+ TextStyle = ?wxTE_READONLY bor ?wxTE_MULTILINE bor ?wxHSCROLL,
+ Text = wxTextCtrl:new(Dialog, ?wxID_ANY,
+ [{size, {600, 400}}, {style, TextStyle}]),
+ wxWindow:setBackgroundColour(Text, Color),
+ TextAttr = wxTextAttr:new(),
+ add_text(Text,TextAttr,Strings),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ wxSizer:add(Sizer, Text, [{border, 2}, {flag, ?wxEXPAND}, {proportion, 1}]),
+ ButtSizer = wxDialog:createStdDialogButtonSizer(Dialog, ?wxOK bor ?wxCANCEL),
+ wxSizer:add(Sizer, ButtSizer, [{border, 2}, {flag, ?wxEXPAND}]),
+ wxPanel:setSizer(Dialog, Sizer),
+ wxSizer:fit(Sizer, Dialog),
+ wxSizer:setSizeHints(Sizer, Dialog),
+ Answer = wxDialog:showModal(Dialog),
+ wxDialog:destroy(Dialog),
+ Answer.
+
+add_text(Text,Attr,[{Color,String}|Strings]) ->
+ wxTextAttr:setTextColour(Attr, Color),
+ wxTextCtrl:setDefaultStyle(Text, Attr),
+ wxTextCtrl:appendText(Text, String),
+ add_text(Text,Attr,Strings);
+add_text(_,_,[]) ->
+ ok.
+
+
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% sys callbacks
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 484f84788d..227b1c80a2 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.5.5
+RELTOOL_VSN = 0.5.6
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index 73c4825458..d4460d47b4 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -30,6 +30,102 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 2.1.9.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Remove traces of release_handler reading from filesystem
+ when it has Masters list</p>
+ <p>
+ There are a couple of places in release_handler and
+ release_handler_1 that assumed it has a disk to read
+ from, which in the case of an erl_prim_loader Loader
+ other than efile is not necessarily true</p>
+ <p>
+ Add check_paths/2 to do the equivalent of check_path/1
+ for when there is a Masters list</p>
+ <p>
+ Change get_vsn to no longer get sent File paths but
+ instead use the Bin since beam_lib:version being sent a
+ file path causes it to read the local file system</p>
+ <p>
+ Add get_current_vsn/1 as an equivalent to
+ beam_lib:version(code:which(Mod)), but using
+ erl_prim_loader:get_file instead of reading from local
+ file system</p>
+ <p>
+ (Thanks to Steven Gravell)</p>
+ <p>
+ Own Id: OTP-9142</p>
+ </item>
+ <item>
+ <p>
+ rb:stop did sometimes return {error,running}. This came
+ from supervisor:delete_child and happened when the
+ rb_server has not yet terminated when this function was
+ called. Instead of having a separate gen_server call to
+ rb_server for stopping the process,
+ supervisor:terminate_child is now called. This is a
+ synchronous function - i.e. it waits for the process to
+ actually terminate before it returns.</p>
+ <p>
+ A file descriptor leak in rb:scan_files is corrected. The
+ index file was never closed after reading.</p>
+ <p>
+ A mismatch in the behavior of rb:filter, when filter
+ included 'no', is corrected. Such filters will now return
+ *all* non-matching reports, not only the 'proplist'
+ reports.</p>
+ <p>
+ Own Id: OTP-9149</p>
+ </item>
+ <item>
+ <p>
+ Start and end date for rb:filter/2 was specified as
+ {{Y-M-D},...} in the help text instead of {{Y,M,D},...}.
+ This has been corrected.</p>
+ <p>
+ Own Id: OTP-9166</p>
+ </item>
+ <item>
+ <p>
+ If some, but not all, of the sasl environment variables
+ related to the log_mf_h error handler were missing sasl
+ would successfully start but silently skip starting
+ log_mf_h. This is corrected so sasl startup will now fail
+ if one or two of the three variables are given. If none
+ of the variables are given, sasl will start as before
+ without starting log_mf_h.</p>
+ <p>
+ Own Id: OTP-9185</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Change default behaviour to not check src code when
+ creating release</p>
+ <p>
+ Add new option <c>src_tests</c> to systools:make_script
+ and systools:make_tar. The old option
+ <c>no_module_tests</c> is now ignored as this is the
+ default behaviour.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-9146 Aux Id: seq11803 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 2.1.9.3</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/sasl/examples/src/Makefile b/lib/sasl/examples/src/Makefile
index 4a4e04a536..c58f651696 100644
--- a/lib/sasl/examples/src/Makefile
+++ b/lib/sasl/examples/src/Makefile
@@ -66,7 +66,7 @@ release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/examples/src
$(INSTALL_DIR) $(RELSYSDIR)/examples/ebin
(cd ..; tar cf - src ebin | (cd $(RELSYSDIR)/examples; tar xf -))
- chmod -f -R ug+w $(RELSYSDIR)/examples
+ chmod -R ug+w $(RELSYSDIR)/examples
release_docs_spec:
diff --git a/lib/sasl/src/erlsrv.erl b/lib/sasl/src/erlsrv.erl
index f9804c41dc..086dc7c651 100644
--- a/lib/sasl/src/erlsrv.erl
+++ b/lib/sasl/src/erlsrv.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -75,14 +75,21 @@ write_all_data(Port,[H|T]) ->
write_all_data(Port,T).
read_all_data(Port) ->
+ lists:reverse(read_all_data(Port,[],[])).
+read_all_data(Port,Line,Lines) ->
receive
+ {Port, {data, {noeol,Data}}} ->
+ read_all_data(Port,Line++Data,Lines);
{Port, {data, {eol,Data}}} ->
- [ Data | read_all_data(Port)];
- _ ->
+ read_all_data(Port,[],[Line++Data|Lines]);
+ {Port,_Other} ->
Port ! {self(), close},
receive
{Port, closed} ->
- []
+ case Line of
+ [] -> Lines;
+ _ -> [Line|Lines]
+ end
end
end.
@@ -208,7 +215,7 @@ store_service(EmulatorVersion,Service) ->
false ->
{error, no_servicename};
{value, {_,Name}} ->
- {Action,Service1} = case get_service(Name) of
+ {Action,Service1} = case get_service(EmulatorVersion,Name) of
{error, no_such_service} ->
{"add",Service};
_ ->
@@ -377,8 +384,14 @@ pick_argument(_,[],Acc) ->
{Acc, ""};
pick_argument(normal,[$ |T],Acc) ->
{Acc,T};
+pick_argument(normal,[$\\|T],Acc) ->
+ pick_argument(normal_escaped,T,[$\\|Acc]);
pick_argument(normal,[$"|T],Acc) ->
pick_argument(quoted,T,[$"|Acc]);
+pick_argument(normal_escaped,[$"|T],Acc) ->
+ pick_argument(bquoted,T,[$"|Acc]);
+pick_argument(normal_escaped,[A|T],Acc) ->
+ pick_argument(normal,T,[A|Acc]);
pick_argument(quoted_escaped,[H|T],Acc) ->
pick_argument(quoted,T,[H|Acc]);
pick_argument(quoted,[$"|T],Acc) ->
@@ -387,6 +400,14 @@ pick_argument(quoted,[$\\|T],Acc) ->
pick_argument(quoted_escaped,T,[$\\|Acc]);
pick_argument(quoted,[H|T],Acc) ->
pick_argument(quoted,T,[H|Acc]);
+pick_argument(bquoted_escaped,[$"|T],Acc) ->
+ pick_argument(normal,T,[$"|Acc]);
+pick_argument(bquoted_escaped,[H|T],Acc) ->
+ pick_argument(bquoted,T,[H|Acc]);
+pick_argument(bquoted,[$\\|T],Acc) ->
+ pick_argument(bquoted_escaped,T,[$\\|Acc]);
+pick_argument(bquoted,[H|T],Acc) ->
+ pick_argument(bquoted,T,[H|Acc]);
pick_argument(normal,[H|T],Acc) ->
pick_argument(normal,T,[H|Acc]).
diff --git a/lib/sasl/src/release_handler.erl b/lib/sasl/src/release_handler.erl
index b60aa847df..ab54b1d00b 100644
--- a/lib/sasl/src/release_handler.erl
+++ b/lib/sasl/src/release_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -291,7 +291,8 @@ check_script(Script, LibDirs) ->
release_handler_1:check_script(Script, LibDirs).
%%-----------------------------------------------------------------
-%% eval_script(Script, Apps, LibDirs, Opts) -> {ok, UnPurged} |
+%% eval_script(Script, Apps, LibDirs, NewLibs, Opts) ->
+%% {ok, UnPurged} |
%% restart_new_emulator |
%% {error, Error}
%% {'EXIT', Reason}
@@ -299,9 +300,13 @@ check_script(Script, LibDirs) ->
%% net_kernel:monitor_nodes(true) before calling this function.
%% No! No other process than the release_handler can ever call this
%% function, if sync_nodes is used.
-%%-----------------------------------------------------------------
-eval_script(Script, Apps, LibDirs, Opts) ->
- catch release_handler_1:eval_script(Script, Apps, LibDirs, Opts).
+%%
+%% LibDirs is a list of all applications, while NewLibs is a list of
+%% applications that have changed version between the current and the
+%% new release.
+%% -----------------------------------------------------------------
+eval_script(Script, Apps, LibDirs, NewLibs, Opts) ->
+ catch release_handler_1:eval_script(Script, Apps, LibDirs, NewLibs, Opts).
%%-----------------------------------------------------------------
%% Func: create_RELEASES(Root, RelFile, LibDirs) -> ok | {error, Reason}
@@ -405,6 +410,7 @@ eval_appup_script(App, ToVsn, ToDir, Script) ->
Res = release_handler_1:eval_script(Script,
[], % [AppSpec]
[{App, ToVsn, ToDir}],
+ [{App, ToVsn, ToDir}],
[]), % [Opt]
case Res of
{ok, _Unpurged} ->
@@ -890,6 +896,7 @@ do_check_install_release(RelDir, Vsn, Releases, Masters) ->
end.
do_install_release(#state{start_prg = StartPrg,
+ root = RootDir,
rel_dir = RelDir, releases = Releases,
masters = Masters,
static_emulator = Static},
@@ -905,7 +912,9 @@ do_install_release(#state{start_prg = StartPrg,
EnvBefore = application_controller:prep_config_change(),
Apps = change_appl_data(RelDir, Release, Masters),
LibDirs = Release#release.libs,
- case eval_script(Script, Apps, LibDirs, Opts) of
+ NewLibs = get_new_libs(LatestRelease#release.libs,
+ Release#release.libs),
+ case eval_script(Script, Apps, LibDirs, NewLibs, Opts) of
{ok, []} ->
application_controller:config_change(EnvBefore),
mon_nodes(false),
@@ -926,8 +935,8 @@ do_install_release(#state{start_prg = StartPrg,
NReleases = set_status(Vsn, current, Releases),
NReleases2 = set_status(Vsn,tmp_current,NReleases),
write_releases(RelDir, NReleases2, Masters),
- prepare_restart_new_emulator(StartPrg, RelDir,
- Release,
+ prepare_restart_new_emulator(StartPrg, RootDir,
+ RelDir, Release,
PermanentRelease,
Masters),
{restart_new_emulator, CurrentVsn, Descr};
@@ -997,7 +1006,7 @@ do_make_services_permanent(PermanentVsn,Vsn, PermanentEVsn, EVsn) ->
throw(Error4)
end
end.
-
+
do_make_permanent(#state{releases = Releases,
rel_dir = RelDir, unpurged = Unpurged,
masters = Masters,
@@ -1409,8 +1418,8 @@ prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn},
FutureServiceName = hd(string:tokens(atom_to_list(node()),"@"))
++ "_" ++ Vsn,
CurrentService = case erlsrv:get_service(PermEVsn,CurrentServiceName) of
- {error, Reason} ->
- throw({error, Reason});
+ {error, _} = Error1 ->
+ throw(Error1);
CS ->
CS
end,
@@ -1425,37 +1434,33 @@ prepare_restart_nt(#release{erts_vsn = EVsn, vsn = Vsn},
CurrentServiceName),
case erlsrv:store_service(EVsn, FutureService) of
- {error, Rison} ->
- throw({error,Rison});
- _ ->
+ {error, _} = Error2 ->
+ throw(Error2);
+ _X ->
erlsrv:disable_service(EVsn, FutureServiceName),
ErlSrv = filename:nativename(erlsrv:erlsrv(EVsn)),
- case heart:set_cmd(ErlSrv ++ " enable " ++ FutureServiceName ++
- " & " ++ ErlSrv ++ " start " ++
- FutureServiceName ++
- " & " ++ ErlSrv ++ " disable " ++
- FutureServiceName) of
+ StartDisabled = ErlSrv ++ " start_disabled " ++ FutureServiceName,
+ case heart:set_cmd(StartDisabled) of
ok ->
ok;
- Error ->
- throw({error, {'heart:set_cmd() error', Error}})
+ Error3 ->
+ throw({error, {'heart:set_cmd() error', Error3}})
end
end.
-
%%-----------------------------------------------------------------
%% Set things up for restarting the new emulator. The actual
%% restart is performed by calling init:reboot() higher up.
%%-----------------------------------------------------------------
-prepare_restart_new_emulator(StartPrg, RelDir,
- Release, PRelease,
- Masters) ->
+prepare_restart_new_emulator(StartPrg, RootDir, RelDir,
+ Release, PRelease, Masters) ->
#release{erts_vsn = EVsn, vsn = Vsn} = Release,
Data = EVsn ++ " " ++ Vsn,
DataFile = write_new_start_erl(Data, RelDir, Masters),
%% Tell heart to use DataFile instead of start_erl.data
case os:type() of
{win32,nt} ->
+ write_ini_file(RootDir,EVsn,Masters),
prepare_restart_nt(Release,PRelease,DataFile);
{unix,_} ->
StartP = check_start_prg(StartPrg, Masters),
@@ -1832,50 +1837,10 @@ write_start(File, Data, false) ->
end;
write_start(File, Data, Masters) ->
all_masters(Masters),
- write_start_m(File, Data, Masters).
+ safe_write_file_m(File, Data, Masters).
%%-----------------------------------------------------------------
-%% Write the "start_erl.data" file at all master nodes.
-%% 1. Save "start_erl.backup" at all nodes.
-%% 2. Write the "start_erl.change" file at all nodes.
-%% 3. Move "start_erl.change" to "start_erl.data".
-%% 4. Remove "start_erl.backup" at all nodes.
-%%
-%% If one of the steps above fails, all steps is recovered from
-%% (as long as possible), except for 4 which is allowed to fail.
-%%-----------------------------------------------------------------
-write_start_m(File, Data, Masters) ->
- Dir = filename:dirname(File),
- Backup = filename:join(Dir, "start_erl.backup"),
- Change = filename:join(Dir, "start_erl.change"),
- case at_all_masters(Masters, ?MODULE, do_copy_files,
- [File, [Backup]]) of
- ok ->
- case at_all_masters(Masters, ?MODULE, do_write_file,
- [Change, Data]) of
- ok ->
- case at_all_masters(Masters, file, rename,
- [Change, File]) of
- ok ->
- remove_files(all, [Backup, Change], Masters),
- ok;
- {error, {Master, R}} ->
- takewhile(Master, Masters, file, rename,
- [Backup, File]),
- remove_files(all, [Backup, Change], Masters),
- throw({error, {Master, R, move_start_erl}})
- end;
- {error, {Master, R}} ->
- remove_files(all, [Backup, Change], Masters),
- throw({error, {Master, R, write_start_erl}})
- end;
- {error, {Master, R}} ->
- remove_files(Master, [Backup], Masters),
- throw({error, {Master, R, backup_start_erl}})
- end.
-
-%%-----------------------------------------------------------------
%% Copy the "start.boot" and "sys.config" from SrcDir to DestDir at all
%% master nodes.
%% 1. Save DestDir/"start.backup" and DestDir/"sys.backup" at all nodes.
@@ -1917,3 +1882,97 @@ set_static_files(SrcDir, DestDir, Masters) ->
remove_files(Master, [BackupBoot, BackupConf], Masters),
throw({error, {Master, R, backup_start_config}})
end.
+
+%%-----------------------------------------------------------------
+%% Write erl.ini
+%% Writes the erl.ini file used by erl.exe when (re)starting the erlang node.
+%% At first installation, this is done by Install.exe, which means that if
+%% the format of this file for some reason is changed, then Install.c must
+%% also be updated (and probably some other c-files which read erl.ini)
+%%-----------------------------------------------------------------
+write_ini_file(RootDir,EVsn,Masters) ->
+ BinDir = filename:join([RootDir,"erts-"++EVsn,"bin"]),
+ Str0 = io_lib:format("[erlang]~n"
+ "Bindir=~s~n"
+ "Progname=erl~n"
+ "Rootdir=~s~n",
+ [filename:nativename(BinDir),
+ filename:nativename(RootDir)]),
+ Str = re:replace(Str0,"\\\\","\\\\\\\\",[{return,list},global]),
+ IniFile = filename:join(BinDir,"erl.ini"),
+ do_write_ini_file(IniFile,Str,Masters).
+
+do_write_ini_file(File,Data,false) ->
+ case do_write_file(File, Data) of
+ ok -> ok;
+ Error -> throw(Error)
+ end;
+do_write_ini_file(File,Data,Masters) ->
+ all_masters(Masters),
+ safe_write_file_m(File, Data, Masters).
+
+
+%%-----------------------------------------------------------------
+%% Write the given file at all master nodes.
+%% 1. Save <File>.backup at all nodes.
+%% 2. Write <File>.change at all nodes.
+%% 3. Move <File>.change to <File>
+%% 4. Remove <File>.backup at all nodes.
+%%
+%% If one of the steps above fails, all steps are recovered from
+%% (as long as possible), except for 4 which is allowed to fail.
+%%-----------------------------------------------------------------
+safe_write_file_m(File, Data, Masters) ->
+ Backup = File ++ ".backup",
+ Change = File ++ ".change",
+ case at_all_masters(Masters, ?MODULE, do_copy_files,
+ [File, [Backup]]) of
+ ok ->
+ case at_all_masters(Masters, ?MODULE, do_write_file,
+ [Change, Data]) of
+ ok ->
+ case at_all_masters(Masters, file, rename,
+ [Change, File]) of
+ ok ->
+ remove_files(all, [Backup, Change], Masters),
+ ok;
+ {error, {Master, R}} ->
+ takewhile(Master, Masters, file, rename,
+ [Backup, File]),
+ remove_files(all, [Backup, Change], Masters),
+ throw({error, {Master, R, rename,
+ filename:basename(Change),
+ filename:basename(File)}})
+ end;
+ {error, {Master, R}} ->
+ remove_files(all, [Backup, Change], Masters),
+ throw({error, {Master, R, write, filename:basename(Change)}})
+ end;
+ {error, {Master, R}} ->
+ remove_files(Master, [Backup], Masters),
+ throw({error, {Master, R, backup,
+ filename:basename(File),
+ filename:basename(Backup)}})
+ end.
+
+%%-----------------------------------------------------------------
+%% Figure out which applications that have changed version between the
+%% two releases. The paths for these applications must always be
+%% updated, even if the relup script does not load any modules. See
+%% OTP-9402.
+%%
+%% A different situation is when the same application version is used
+%% in old and new release, but the path has changed. This is not
+%% handled here - instead it must be explicitely indicated by the
+%% 'update_paths' option to release_handler:install_release/2 if the
+%% code path shall be updated then.
+%% -----------------------------------------------------------------
+get_new_libs([{App,Vsn,LibDir}|CurrentLibs], NewLibs) ->
+ case lists:keyfind(App,1,NewLibs) of
+ {App,NewVsn,_} = LibInfo when NewVsn =/= Vsn ->
+ [LibInfo | get_new_libs(CurrentLibs,NewLibs)];
+ _ ->
+ get_new_libs(CurrentLibs,NewLibs)
+ end;
+get_new_libs([],_) ->
+ [].
diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl
index 8d050fb7b0..ff62f847ac 100644
--- a/lib/sasl/src/release_handler_1.erl
+++ b/lib/sasl/src/release_handler_1.erl
@@ -19,7 +19,7 @@
-module(release_handler_1).
%% External exports
--export([eval_script/3, eval_script/4, check_script/2]).
+-export([eval_script/1, eval_script/5, check_script/2]).
-export([get_current_vsn/1]). %% exported because used in a test case
-record(eval_state, {bins = [], stopped = [], suspended = [], apps = [],
@@ -33,11 +33,11 @@
%% libdirs = [{Lib, LibVsn, LibDir}] - Maps Lib to Vsn and Directory
%% unpurged = [{Mod, soft_purge | brutal_purge}]
%% vsns = [{Mod, OldVsn, NewVsn}] - remember the old vsn of a mod
-%% before it is removed/a new vsn is loaded; the new vsn
+%% before a new vsn is loaded; the new vsn
%% is kept in case of a downgrade, where the code_change
%% function receives the vsn of the module to downgrade
%% *to*.
-%% newlibs = [{Lib, Dir}] - list of all new libs; used to change
+%% newlibs = [{Lib, LibVsn, LibDir}] - list of all new libs; used to change
%% the code path
%% opts = [{Tag, Value}] - list of options
%%-----------------------------------------------------------------
@@ -63,10 +63,11 @@ check_script(Script, LibDirs) ->
{error, {old_processes, Mod}}
end.
-eval_script(Script, Apps, LibDirs) ->
- eval_script(Script, Apps, LibDirs, []).
+%% eval_script/1 - For testing only - no apps added, just testing instructions
+eval_script(Script) ->
+ eval_script(Script, [], [], [], []).
-eval_script(Script, Apps, LibDirs, Opts) ->
+eval_script(Script, Apps, LibDirs, NewLibs, Opts) ->
case catch check_old_processes(Script) of
ok ->
{Before, After} = split_instructions(Script),
@@ -75,6 +76,7 @@ eval_script(Script, Apps, LibDirs, Opts) ->
end,
#eval_state{apps = Apps,
libdirs = LibDirs,
+ newlibs = NewLibs,
opts = Opts},
Before) of
EvalState2 when is_record(EvalState2, eval_state) ->
@@ -214,16 +216,15 @@ check_old_code(Mod) ->
%%-----------------------------------------------------------------
eval({load_object_code, {Lib, LibVsn, Modules}}, EvalState) ->
case lists:keysearch(Lib, 1, EvalState#eval_state.libdirs) of
- {value, {Lib, LibVsn, LibDir}} ->
- Ebin = filename:join(LibDir, "ebin"),
+ {value, {Lib, LibVsn, LibDir} = LibInfo} ->
Ext = code:objfile_extension(),
{NewBins, NewVsns} =
lists:foldl(fun(Mod, {Bins, Vsns}) ->
File = lists:concat([Mod, Ext]),
- FName = filename:join(Ebin, File),
+ FName = filename:join([LibDir, "ebin", File]),
case erl_prim_loader:get_file(FName) of
{ok, Bin, FName2} ->
- NVsns = add_new_vsn(Mod, Bin, Vsns),
+ NVsns = add_vsns(Mod, Bin, Vsns),
{[{Mod, Bin, FName2} | Bins],NVsns};
error ->
throw({error, {no_such_file,FName}})
@@ -232,7 +233,7 @@ eval({load_object_code, {Lib, LibVsn, Modules}}, EvalState) ->
{EvalState#eval_state.bins,
EvalState#eval_state.vsns},
Modules),
- NewLibs = [{Lib, Ebin} | EvalState#eval_state.newlibs],
+ NewLibs = lists:keystore(Lib,1,EvalState#eval_state.newlibs,LibInfo),
EvalState#eval_state{bins = NewBins,
newlibs = NewLibs,
vsns = NewVsns};
@@ -242,15 +243,14 @@ eval({load_object_code, {Lib, LibVsn, Modules}}, EvalState) ->
eval(point_of_no_return, EvalState) ->
Libs = case get_opt(update_paths, EvalState, false) of
false ->
- EvalState#eval_state.newlibs; % [{Lib, Path}]
+ EvalState#eval_state.newlibs;
true ->
- lists:map(fun({Lib, _LibVsn, LibDir}) ->
- Ebin= filename:join(LibDir,"ebin"),
- {Lib, Ebin}
- end,
- EvalState#eval_state.libdirs)
+ EvalState#eval_state.libdirs
end,
- lists:foreach(fun({Lib, Path}) -> code:replace_path(Lib, Path) end,
+ lists:foreach(fun({Lib, _LibVsn, LibDir}) ->
+ Ebin = filename:join(LibDir,"ebin"),
+ code:replace_path(Lib, Ebin)
+ end,
Libs),
EvalState;
eval({load, {Mod, _PrePurgeMethod, PostPurgeMethod}}, EvalState) ->
@@ -258,32 +258,21 @@ eval({load, {Mod, _PrePurgeMethod, PostPurgeMethod}}, EvalState) ->
{value, {_Mod, Bin, File}} = lists:keysearch(Mod, 1, Bins),
% load_binary kills all procs running old code
% if soft_purge, we know that there are no such procs now
- Vsns = EvalState#eval_state.vsns,
- NewVsns = add_old_vsn(Mod, Vsns),
code:load_binary(Mod, File, Bin),
% Now, the prev current is old. There might be procs
% running it. Find them.
Unpurged = do_soft_purge(Mod,PostPurgeMethod,EvalState#eval_state.unpurged),
EvalState#eval_state{bins = lists:keydelete(Mod, 1, Bins),
- unpurged = Unpurged,
- vsns = NewVsns};
+ unpurged = Unpurged};
eval({remove, {Mod, _PrePurgeMethod, PostPurgeMethod}}, EvalState) ->
- % purge kills all procs running old code
- % if soft_purge, we know that there are no such procs now
- Vsns = EvalState#eval_state.vsns,
- NewVsns = add_old_vsn(Mod, Vsns),
+ %% purge kills all procs running old code
+ %% if soft_purge, we know that there are no such procs now
code:purge(Mod),
code:delete(Mod),
- % Now, the prev current is old. There might be procs
- % running it. Find them.
- Unpurged =
- case code:soft_purge(Mod) of
- true -> EvalState#eval_state.unpurged;
- false -> [{Mod, PostPurgeMethod} | EvalState#eval_state.unpurged]
- end,
-%% Bins = EvalState#eval_state.bins,
-%% EvalState#eval_state{bins = lists:keydelete(Mod, 1, Bins),
- EvalState#eval_state{unpurged = Unpurged, vsns = NewVsns};
+ %% Now, the prev current is old. There might be procs
+ %% running it. Find them.
+ Unpurged = do_soft_purge(Mod,PostPurgeMethod,EvalState#eval_state.unpurged),
+ EvalState#eval_state{unpurged = Unpurged};
eval({purge, Modules}, EvalState) ->
% Now, if there are any processes still executing old code, OR
% if some new processes started after suspend but before load,
@@ -606,26 +595,20 @@ sync_nodes(Id, Nodes) ->
end,
NNodes).
-add_old_vsn(Mod, Vsns) ->
+add_vsns(Mod, NewBin, Vsns) ->
+ OldVsn = get_current_vsn(Mod),
+ NewVsn = get_vsn(NewBin),
case lists:keysearch(Mod, 1, Vsns) of
- {value, {Mod, undefined, NewVsn}} ->
- OldVsn = get_current_vsn(Mod),
- lists:keyreplace(Mod, 1, Vsns, {Mod, OldVsn, NewVsn});
- {value, {Mod, _OldVsn, _NewVsn}} ->
- Vsns;
+ {value, {Mod, OldVsn0, NewVsn0}} ->
+ lists:keyreplace(Mod, 1, Vsns, {Mod,
+ replace_undefined(OldVsn0,OldVsn),
+ replace_undefined(NewVsn0,NewVsn)});
false ->
- OldVsn = get_current_vsn(Mod),
- [{Mod, OldVsn, undefined} | Vsns]
+ [{Mod, OldVsn, NewVsn} | Vsns]
end.
-add_new_vsn(Mod, Bin, Vsns) ->
- NewVsn = get_vsn(Bin),
- case lists:keysearch(Mod, 1, Vsns) of
- {value, {Mod, OldVsn, undefined}} ->
- lists:keyreplace(Mod, 1, Vsns, {Mod, OldVsn, NewVsn});
- false ->
- [{Mod, undefined, NewVsn} | Vsns]
- end.
+replace_undefined(undefined,Vsn) -> Vsn;
+replace_undefined(Vsn,_) -> Vsn.
%%-----------------------------------------------------------------
%% Func: get_current_vsn/1
@@ -645,7 +628,9 @@ get_current_vsn(Mod) ->
{ok, Bin, _File2} ->
get_vsn(Bin);
error ->
- throw({error, {no_such_file, File}})
+ %% This is the case when a new module is added, there will
+ %% be no current version of it at the time of this call.
+ undefined
end.
%%-----------------------------------------------------------------
diff --git a/lib/sasl/src/sasl.erl b/lib/sasl/src/sasl.erl
index aed5f0da1f..989f99dc82 100644
--- a/lib/sasl/src/sasl.erl
+++ b/lib/sasl/src/sasl.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/sasl/src/systools_lib.erl b/lib/sasl/src/systools_lib.erl
index b652c109fe..f951647b79 100644
--- a/lib/sasl/src/systools_lib.erl
+++ b/lib/sasl/src/systools_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -176,21 +176,26 @@ add_dirs(RegName, Dirs, Root) ->
regexp_match(RegName, D0, Root) ->
case file:list_dir(D0) of
{ok, Files} when length(Files) > 0 ->
- FR = fun(F) ->
- case regexp:match(F, RegName) of
- {match,1,N} when N == length(F) ->
- DirF = join(D0, F, Root),
- case dir_p(DirF) of
- true ->
- {true, DirF};
+ case re:compile(RegName) of
+ {ok, MP} ->
+ FR = fun(F) ->
+ case re:run(F, MP) of
+ {match,[{0,N}]} when N == length(F) ->
+ DirF = join(D0, F, Root),
+ case dir_p(DirF) of
+ true ->
+ {true, DirF};
+ _ ->
+ false
+ end;
_ ->
false
- end;
- _ ->
- false
- end
- end,
- {true,lists:zf(FR, Files)};
+ end
+ end,
+ {true,lists:zf(FR, Files)};
+ _ ->
+ false
+ end;
_ ->
false
end.
diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile
index ad08c8136b..65be134462 100644
--- a/lib/sasl/test/Makefile
+++ b/lib/sasl/test/Makefile
@@ -31,7 +31,8 @@ MODULES= \
systools_SUITE \
systools_rc_SUITE \
overload_SUITE \
- rb_SUITE
+ rb_SUITE \
+ rh_test_lib
ERL_FILES= $(MODULES:%=%.erl)
@@ -85,7 +86,7 @@ release_tests_spec: make_emakefile
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) sasl.spec sasl.cover $(EMAKEFILE) $(RELSYSDIR)
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
@tar cfh - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
release_docs_spec:
diff --git a/lib/sasl/test/installer.erl b/lib/sasl/test/installer.erl
index a114c4b5c9..f5ceab0dc4 100644
--- a/lib/sasl/test/installer.erl
+++ b/lib/sasl/test/installer.erl
@@ -119,6 +119,7 @@ install_3(TestNode,PrivDir) ->
?print(["install_3 unpack_release P2A ok"]),
?check_release("P2A",unpacked,["a-1.1"]),
{ok, "P1I", [new_emu]} = release_handler:check_install_release("P2A"),
+ ?print(["install_3 check_install_release P2A ok"]),
ok = release_handler:make_permanent("P1I"),
?print(["install_3 make_permanent P1I ok"]),
?check_release("P1I",permanent,["a-1.1"]),
@@ -268,23 +269,30 @@ client1_1(TestNode,PrivDir,MasterDir,ClientSname) ->
erl_boot_server:start([IP]),
ok = net_kernel:monitor_nodes(true),
- Node = start_client(TestNode,ClientSname),
+ Node = start_client(TestNode,client1,ClientSname),
trace_disallowed_calls(Node),
%% Check env var for SASL on client node
SaslEnv = rpc:call(Node, application, get_all_env, [sasl]),
+ ?print([{client1_1,sasl_env},SaslEnv]),
{_,CliDir} = lists:keyfind(client_directory,1,SaslEnv),
{_,[Master]} = lists:keyfind(masters,1,SaslEnv),
{_,StartCli} = lists:keyfind(start_prg,1,SaslEnv),
- Root = code:root_dir(),
- true = (CliDir =:= filename:join([Root,"clients","type1",Node])),
- true = (StartCli =:= filename:join([CliDir,"bin","start"])),
+ NodeStr = atom_to_list(Node),
+ [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)),
true = (Master =:= node()),
+ case os:type() of
+ {unix,_} ->
+ true = (StartCli =:= filename:join([CliDir,"bin","start"]));
+ _ ->
+ ok
+ end,
%% Unpack P1H on master
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
%% Unpack and install P1H on client
+ Root = code:root_dir(),
P1HDir = filename:join([Root, "releases", "P1H"]),
%% The AppDirs argument (last arg to set_unpacked) below is really
@@ -339,6 +347,7 @@ client1_2(TestNode,PrivDir,Node) ->
?check_running_app_client(Node,a,"1.0"),
ok = rpc:call(Node, release_handler, make_permanent, ["P1H"]),
+ ?check_release_client(Node,"P1H",permanent,["a-1.0"]),
check_disallowed_calls(),
reboot(TestNode,Node),
@@ -584,7 +593,7 @@ trace_disallowed_calls(Node) ->
MasterProc = self(),
rpc:call(Node,dbg,tracer,[process,{fun(T,_) -> MasterProc ! T end,[]}]),
rpc:call(Node,dbg,p,[all,call]),
- rpc:call(Node,dbg,tp,[file,[]]).
+ rpc:call(Node,dbg,tp,[file,[{'_',[],[{message,{caller}}]}]]).
check_disallowed_calls() ->
receive
@@ -594,13 +603,12 @@ check_disallowed_calls() ->
ok
end.
-start_client(TestNode,Client) ->
- {Start, Node} = do_start_client(Client,test_host()),
- Cmd = lists:concat(["env NODENAME=",Client," ",
- filename:join(code:root_dir(), Start)]),
- ?print([{start_client,Client},Cmd]),
- Res = os:cmd(Cmd),
- ?print([{start_client,result},Res]),
+start_client(TestNode,Client,Sname) ->
+ Node = list_to_atom(lists:concat([Sname,"@",test_host()])),
+ case os:type() of
+ {unix,_} -> start_client_unix(TestNode,Sname,Node);
+ {win32,_} -> start_client_win32(TestNode,Client,Sname)
+ end,
receive
{nodeup, Node} ->
wait_started(TestNode,Node)
@@ -609,10 +617,34 @@ start_client(TestNode,Client) ->
?fail({"can not start", Node})
end.
-do_start_client(Client, Host) ->
- Node = list_to_atom(lists:concat([Client,"@",Host])),
+start_client_unix(TestNode,Sname,Node) ->
Start = filename:join(["clients", "type1", Node, "bin", "start"]),
- {Start, Node}.
+ Cmd = lists:concat(["env NODENAME=",Sname," ",
+ filename:join(code:root_dir(), Start)]),
+ ?print([{start_client,Sname},Cmd]),
+ Res = os:cmd(Cmd),
+ ?print([{start_client,result},Res]).
+
+start_client_win32(TestNode,Client,ClientSname) ->
+ Name = atom_to_list(ClientSname) ++ "_P1G",
+ RootDir = code:root_dir(),
+ ErtsBinDir = filename:join(RootDir,"erts-4.4/bin"),
+
+ {ClientArgs,RelClientDir} = rh_test_lib:get_client_args(Client,ClientSname,
+ RootDir),
+ StartErlArgs = rh_test_lib:get_start_erl_args(RootDir,RelClientDir,
+ ClientArgs),
+ ServiceArgs = rh_test_lib:get_service_args(RootDir, RelClientDir,
+ ClientSname, StartErlArgs),
+
+ ?print([{start_client,ClientSname},ServiceArgs]),
+ Erlsrv = filename:nativename(filename:join(ErtsBinDir,"erlsrv")),
+ rh_test_lib:erlsrv(Erlsrv,stop,Name),
+ rh_test_lib:erlsrv(Erlsrv,remove,Name),
+ ok = rh_test_lib:erlsrv(Erlsrv,add,Name,ServiceArgs),
+ ok = rh_test_lib:erlsrv(Erlsrv,start,Name),
+ ?print([{start_client,result},ok]),
+ ok.
reboot(TestNode,Node) ->
cover_client(TestNode,Node,stop_cover),
@@ -628,7 +660,7 @@ check_reboot(TestNode,Node) ->
receive
{nodeup, Node} -> wait_started(TestNode,Node)
after 30000 ->
- ?fail({Node, "not rebooted",net_adm:ping(Node)})
+ ?fail({Node, "not rebooted",net_adm:ping(Node)})
end
after 30000 ->
?fail({Node, "not closing down",net_adm:ping(Node)})
@@ -678,22 +710,28 @@ client2(TestNode,PrivDir,ClientSname) ->
release_handler:remove_release("P1H"),
ok = net_kernel:monitor_nodes(true),
- Node = start_client(TestNode,ClientSname),
+ Node = start_client(TestNode,client2,ClientSname),
%% Check env var for SASL on client node
- ?print([{sasl_env, Node}, rpc:call(Node, application, get_all_env, [sasl])]),
SaslEnv = rpc:call(Node, application, get_all_env, [sasl]),
+ ?print([{client1_1,sasl_env},SaslEnv]),
{_,CliDir} = lists:keyfind(client_directory,1,SaslEnv),
{_,[Master,Master2]} = lists:keyfind(masters,1,SaslEnv),
{_,StartCli} = lists:keyfind(start_prg,1,SaslEnv),
- Root = code:root_dir(),
- true = (CliDir =:= filename:join([Root,"clients","type1",Node])),
- true = (StartCli =:= filename:join([CliDir,"bin","start"])),
+ NodeStr = atom_to_list(Node),
+ [NodeStr,"type1","clients"|_] = lists:reverse(filename:split(CliDir)),
true = (Master =:= node()),
true = (Master2 =:= list_to_atom("master2@"++TestHost)),
+ case os:type() of
+ {unix,_} ->
+ true = (StartCli =:= filename:join([CliDir,"bin","start"]));
+ _ ->
+ ok
+ end,
{ok, "P1H"} = unpack_release(PrivDir,"rel1"),
+ Root = code:root_dir(),
{error,{bad_masters,[Master2]}} =
rpc:call(Node, release_handler, set_unpacked,
[filename:join([Root, "releases", "P1H", "rel1.rel"]),[]]),
diff --git a/lib/sasl/test/release_handler_SUITE.erl b/lib/sasl/test/release_handler_SUITE.erl
index efa775f344..9c7733b7ec 100644
--- a/lib/sasl/test/release_handler_SUITE.erl
+++ b/lib/sasl/test/release_handler_SUITE.erl
@@ -51,11 +51,11 @@ unix_cases() ->
[target_system] ++ RunErlCases ++ cases().
win32_cases() ->
- cases().
+ [{group,release} | cases()].
%% Cases that can be run on all platforms
cases() ->
- [otp_2740, otp_2760, otp_5761, instructions, eval_appup].
+ [otp_2740, otp_2760, otp_5761, otp_9402, otp_9417, instructions, eval_appup].
groups() ->
[{release,[],
@@ -148,6 +148,10 @@ init_per_group(release_gg, Config0) ->
end_per_group(release, Config) ->
Dog = ?t:timetrap(?default_timeout),
stop_print_proc(),
+ case os:type() of
+ {win32,_} -> delete_all_services();
+ _ -> ok
+ end,
delete_release(Config),
?t:timetrap_cancel(Dog),
Config;
@@ -169,6 +173,10 @@ end_per_testcase(Case, Config) ->
Dog=?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
+ try apply(?MODULE,Case,[cleanup,Config])
+ catch error:undef -> ok
+ end,
+
%% DEBUG
case ?config(tc_status,Config) of
ok ->
@@ -206,10 +214,6 @@ end_per_testcase(Case, Config) ->
%% immediately restarted by heart and the test cases wait until
%% the node is actually up and running -- see wait_nodes_up/2)
file:delete("sasl_erl_crash.dump"),
-
- try apply(?MODULE,Case,[cleanup,Config])
- catch error:undef -> ok
- end,
ok.
gg_node_snames(Config) ->
@@ -224,7 +228,10 @@ gg_node_snames(Config) ->
no_run_erl(Config) when is_list(Config) ->
{comment, "No run_erl program"}.
-
+break(Config) ->
+ erlang:display(test_break),
+ ?t:break(priv_dir(Config)),
+ ok.
%% Test upgrade and downgrade of erts
upgrade(Conf) when is_list(Conf) ->
@@ -323,7 +330,7 @@ client1(Conf) when is_list(Conf) ->
%% Copy the P1G release to a directory for use in this testcase
ok = copy_installed(Conf,p1g_install,[Master]),
- ok = copy_client(Conf,Master,Client,"start_cli1"),
+ ok = copy_client(Conf,Master,Client,client1),
%% start the master node
[TestNode] = start_nodes(Conf,[Master],"client1"),
@@ -348,7 +355,7 @@ client2(Conf) when is_list(Conf) ->
%% Copy the P1G release to a directory for use in this testcase
ok = copy_installed(Conf,p1g_install,[Master]),
- ok = copy_client(Conf,Master,Client,"start_cli2"),
+ ok = copy_client(Conf,Master,Client,client2),
%% start the master node
[TestNode] = start_nodes(Conf,[Master],"client2"),
@@ -386,7 +393,7 @@ instructions(Conf) when is_list(Conf) ->
{stop, [aa]},
{apply, {?MODULE, no_cc, []}},
{start, [aa]}],
- {ok, _} = release_handler_1:eval_script(S1, [], []),
+ {ok, _} = release_handler_1:eval_script(S1),
case whereis(cc) of
Pid2 when is_pid(Pid2) -> ok;
@@ -396,17 +403,17 @@ instructions(Conf) when is_list(Conf) ->
%% Make bb run old version of b.
S2 = [point_of_no_return,
{remove, {b, soft_purge, soft_purge}}],
- {ok, [{b, soft_purge}]} = release_handler_1:eval_script(S2, [], []),
+ {ok, [{b, soft_purge}]} = release_handler_1:eval_script(S2),
check_bstate("first", [FirstBB]),
false = code:is_loaded(b),
- {error,{old_processes,b}} = release_handler_1:eval_script(S2,[],[]),
+ {error,{old_processes,b}} = release_handler_1:eval_script(S2),
check_bstate("first", [FirstBB]),
%% Let supervisor restart bb with new code
S3 = [point_of_no_return,
{purge, [b]}],
- {ok, []} = release_handler_1:eval_script(S3, [], []),
+ {ok, []} = release_handler_1:eval_script(S3),
ok = wait_for(bb),
check_bstate("second", []),
SecondBB = whereis(bb),
@@ -439,7 +446,7 @@ instructions(Conf) when is_list(Conf) ->
%% Let supervisor restart bb yet another time
S4 = [point_of_no_return,
{remove, {b, brutal_purge, soft_purge}}],
- {ok, HopefullyEmpty} = release_handler_1:eval_script(S4, [], []),
+ {ok, HopefullyEmpty} = release_handler_1:eval_script(S4),
ok = wait_for(bb),
FourthBB = whereis(bb),
@@ -559,8 +566,7 @@ otp_2760(Conf) ->
%% Execute the relup script and check that app1 is unloaded
{ok, [{"after", [{_Rel1Vsn, _Descr, Script}], _}]} =
file:consult(filename:join(Rel2Dir, "relup")),
- {ok, []} = rpc:call(Node, release_handler_1, eval_script,
- [Script, [], []]),
+ {ok, []} = rpc:call(Node, release_handler_1, eval_script, [Script]),
false = rpc:call(Node, code, is_loaded, [app1]),
true = stop_node(Node),
@@ -651,6 +657,126 @@ otp_5761(Conf) when is_list(Conf) ->
true = stop_node(Node),
ok.
+
+%% When a new version of an application is added, but no module is
+%% changed - the path was not updated - i.e. code:priv_dir would point
+%% to the old location.
+otp_9402(Conf) when is_list(Conf) ->
+ %% Set some paths
+ PrivDir = priv_dir(Conf),
+ Dir = filename:join(PrivDir,"otp_9402"),
+ LibDir = filename:join(?config(data_dir, Conf), "lib"),
+
+ %% Create the releases
+ Rel1 = create_and_install_fake_first_release(Dir,
+ [{a,"1.1",LibDir}]),
+ Rel2 = create_fake_upgrade_release(Dir,
+ "2",
+ [{a,"1.2",LibDir}],
+ {Rel1,Rel1,[LibDir]}),
+ Rel1Dir = filename:dirname(Rel1),
+ Rel2Dir = filename:dirname(Rel2),
+
+ %% Start a slave node
+ {ok, Node} = t_start_node(otp_9402, Rel1, filename:join(Rel1Dir,"sys.config")),
+
+ %% Check path
+ Dir1 = filename:join([LibDir, "a-1.1"]),
+ Dir1 = rpc:call(Node, code, lib_dir, [a]),
+ ABeam = rpc:call(Node, code, which, [a]),
+
+ %% Install second release, with no changed modules
+ {ok, RelVsn2} =
+ rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", [{a,"1.2",LibDir}]]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "relup")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "start.boot")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "sys.config")]),
+
+ {ok, RelVsn1, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn2]),
+
+ %% Check path
+ Dir2 = filename:join([LibDir, "a-1.2"]),
+ Dir2 = rpc:call(Node, code, lib_dir, [a]),
+ APrivDir2 = rpc:call(Node, code, priv_dir, [a]),
+ true = filelib:is_regular(filename:join(APrivDir2,"file")),
+
+ %% Just to make sure no modules have been re-loaded
+ ABeam = rpc:call(Node, code, which, [a]),
+
+ %% Install RelVsn1 again
+ {ok, _OtherVsn, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn1]),
+
+ %% Check path
+ Dir1 = rpc:call(Node, code, lib_dir, [a]),
+ APrivDir1 = rpc:call(Node, code, priv_dir, [a]),
+ false = filelib:is_regular(filename:join(APrivDir1,"file")),
+
+ %% Just to make sure no modules have been re-loaded
+ ABeam = rpc:call(Node, code, which, [a]),
+
+ ok.
+
+
+%% When a module is deleted in an appup instruction, the upgrade
+%% failed if the module was not loaded.
+otp_9417(Conf) when is_list(Conf) ->
+ %% Set some paths
+ PrivDir = priv_dir(Conf),
+ Dir = filename:join(PrivDir,"otp_9417"),
+ LibDir = filename:join(?config(data_dir, Conf), "lib"),
+
+ %% Create the releases
+ Rel1 = create_and_install_fake_first_release(Dir,
+ [{b,"1.0",LibDir}]),
+ Rel2 = create_fake_upgrade_release(Dir,
+ "2",
+ [{b,"2.0",LibDir}],
+ {Rel1,Rel1,[LibDir]}),
+ Rel1Dir = filename:dirname(Rel1),
+ Rel2Dir = filename:dirname(Rel2),
+
+ %% Start a slave node
+ {ok, Node} = t_start_node(otp_9417, Rel1, filename:join(Rel1Dir,"sys.config")),
+
+ %% Check paths
+ Dir1 = filename:join([LibDir, "b-1.0"]),
+ Dir1 = rpc:call(Node, code, lib_dir, [b]),
+ BLibBeam = filename:join([Dir1,"ebin","b_lib.beam"]),
+ BLibBeam = rpc:call(Node,code,which,[b_lib]),
+ false = rpc:call(Node,code,is_loaded,[b_lib]),
+ false = rpc:call(Node,code,is_loaded,[b_server]),
+
+ %% Install second release, which removes b_lib module
+ {ok, RelVsn2} =
+ rpc:call(Node, release_handler, set_unpacked,
+ [Rel2++".rel", [{b,"2.0",LibDir}]]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "relup")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "start.boot")]),
+ ok = rpc:call(Node, release_handler, install_file,
+ [RelVsn2, filename:join(Rel2Dir, "sys.config")]),
+
+ {ok, _RelVsn1, []} =
+ rpc:call(Node, release_handler, install_release, [RelVsn2]),
+
+ %% Check that the module does no longer exist
+ false = rpc:call(Node, code, is_loaded, [b_lib]),
+ non_existing = rpc:call(Node, code, which, [b_lib]),
+
+ %% And check some paths
+ Dir2 = filename:join([LibDir, "b-2.0"]),
+ Dir2 = rpc:call(Node, code, lib_dir, [b]),
+ BServerBeam = filename:join([Dir2,"ebin","b_server.beam"]),
+ {file,BServerBeam} = rpc:call(Node,code,is_loaded,[b_server]),
+ ok.
+
%% Test upgrade and downgrade of applications
eval_appup(Conf) when is_list(Conf) ->
@@ -983,19 +1109,16 @@ stop_node(Node) ->
?t:stop_node(Node).
-copy_client(Conf,Master,Sname,StartScript) ->
+copy_client(Conf,Master,Sname,Client) ->
io:format("copy_client(Conf)"),
DataDir = ?config(data_dir, Conf),
MasterDir = filename:join(priv_dir(Conf),Master),
- {ok,Host} = inet:gethostname(),
- {ok,IpTuple} = inet:getaddr(Host,inet),
- IpAddr = inet_parse:ntoa(IpTuple),
-
- CliNode = node_name(Sname),
+ {ClientArgs,RelCliDir} = rh_test_lib:get_client_args(Client,Sname,MasterDir,
+ node_name(Master)),
- Cli = filename:join([MasterDir, "clients", "type1", CliNode]),
+ Cli = filename:join([MasterDir, RelCliDir]),
ok = filelib:ensure_dir(filename:join([Cli,"bin","."])),
ok = filelib:ensure_dir(filename:join([Cli,"releases","."])),
ok = filelib:ensure_dir(filename:join([Cli,"log","."])),
@@ -1003,12 +1126,16 @@ copy_client(Conf,Master,Sname,StartScript) ->
P1GOrig = filename:join([MasterDir, "releases", "P1G"]),
ok = copy_tree(Conf,P1GOrig,filename:join(Cli,"releases")),
- ok = subst_file(filename:join([DataDir, "clients", StartScript]),
- filename:join([Cli,"bin","start"]),
- [{"ROOT",MasterDir},
- {"MASTER",atom_to_list(Master)},
- {"IPADDR",IpAddr}],
- [{chmod,8#0755}]),
+ case os:type() of
+ {unix,_} ->
+ ok = subst_file(filename:join([DataDir, "start_client"]),
+ filename:join([Cli,"bin","start"]),
+ [{"ROOT",MasterDir},
+ {"CLIENTARGS",ClientArgs}],
+ [{chmod,8#0755}]);
+ _ ->
+ ok
+ end,
StartErlData = filename:join([MasterDir, "releases", "start_erl.data"]),
CliRelDir = filename:join([Cli, "releases"]),
@@ -1030,21 +1157,32 @@ delete_release(Conf) ->
{ok, Dirs} = file:list_dir(PrivDir),
?t:format("======== deleting ~p~n",[Dirs]),
- ok = delete_release_os(Dirs),
- ?t:format("======== remaining ~p~n",[file:list_dir(PrivDir)]),
+ ok = delete_release_os(Dirs--["save"]),
+ {ok,Remaining} = file:list_dir(PrivDir),
+ ?t:format("======== remaining ~p~n",[Remaining]),
+
+ case Remaining of
+ [] ->
+ ok;
+ _ ->
+ delete_release_os(Remaining),
+ Remaining2 = file:list_dir(PrivDir),
+ ?t:format("======== remaining after second try ~p~n",[Remaining2])
+ end,
+
ok = file:set_cwd(OrigWd),
ok.
delete_release_os(Dirs) ->
case os:type() of
- {unix, _} ->
- delete_release_unix(Dirs);
- {win32, _} ->
- delete_release_win32(Dirs);
- Os ->
- test_server:fail({error, {not_yet_implemented_os, Os}})
- end.
+ {unix, _} ->
+ delete_release_unix(Dirs);
+ {win32, _} ->
+ delete_release_win32(Dirs);
+ Os ->
+ test_server:fail({error, {not_yet_implemented_os, Os}})
+ end.
delete_release_unix([]) ->
@@ -1075,7 +1213,14 @@ delete_release_win32([]) ->
delete_release_win32(["save"|Dirs]) ->
delete_release_win32(Dirs);
delete_release_win32([Dir|Dirs]) ->
- Rm = string:concat("rmdir /s ", Dir),
+ Rm =
+ case filelib:is_dir(Dir) of
+ true ->
+ string:concat("rmdir /s /q ", Dir);
+ false ->
+ string:concat("del /q ", Dir)
+ end,
+ ?t:format("============== COMMAND ~p~n",[Rm]),
[] = os:cmd(Rm),
delete_release_win32(Dirs).
@@ -1200,7 +1345,12 @@ subst_var([], Vars, Result, VarAcc) ->
priv_dir(Conf) ->
- filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash
+%% filename:absname(?config(priv_dir, Conf)). % Get rid of trailing slash
+ %% Due to problem with long paths on windows => creating a new
+ %% priv_dir under data_dir
+ Dir = filename:absname(filename:join(?config(data_dir, Conf),priv_dir)),
+ filelib:ensure_dir(filename:join(Dir,"*")),
+ Dir.
latest_version(Dir) ->
List = filelib:wildcard(Dir ++ "*"),
@@ -1256,12 +1406,28 @@ do_create_p1g(Conf,TargetDir) ->
ErtsLatest = latest_version(filename:join(code:root_dir(),"erts")),
ok = copy_tree(Conf, ErtsLatest, ErtsDir, TargetDir),
ErtsBinDir = filename:join([TargetDir,ErtsDir,bin]),
- copy_file(filename:join([ErtsBinDir, "epmd"]), BinDir, [preserve]),
- copy_file(filename:join([ErtsBinDir, "run_erl"]), BinDir, [preserve]),
- copy_file(filename:join([ErtsBinDir, "to_erl"]), BinDir, [preserve]),
+
+ case os:type() of
+ {unix, _} ->
+ copy_file(filename:join([ErtsBinDir, "epmd"]), BinDir, [preserve]),
+ copy_file(filename:join([ErtsBinDir, "run_erl"]), BinDir, [preserve]),
+ copy_file(filename:join([ErtsBinDir, "to_erl"]), BinDir, [preserve]),
+
+ %% Create the start_erl shell script
+ ok = subst_file(filename:join([ErtsBinDir,"start_erl.src"]),
+ filename:join([BinDir,"start_erl"]),
+ [{"EMU","beam"}],
+ [{chmod,8#0755}]);
+ {win32,_} ->
+ %% Add a batch file to use as HEART_COMMAND
+ ok = copy_file(filename:join(DataDir, "heart_restart.bat"),
+ ErtsBinDir,[preserve])
+ end,
copy_file(filename:join(DataDir, "../installer.beam"),
filename:join([DataDir,lib,"installer-1.0",ebin])),
+ copy_file(filename:join(DataDir, "../rh_test_lib.beam"),
+ filename:join([DataDir,lib,"installer-1.0",ebin])),
%% Create .rel, .script and .boot files
RelName = "rel0",
@@ -1272,7 +1438,7 @@ do_create_p1g(Conf,TargetDir) ->
ok = filelib:ensure_dir(RelFile),
LibPath = filename:join([DataDir,lib,"*",ebin]),
- TarFile = create_basic_release(RelFile, RelVsn, {ErtsVsn,false},
+ TarFile = create_basic_release(Conf, RelFile, RelVsn, {ErtsVsn,false},
LibPath, [], [], [], []),
%% Extract tar file in target directory (i.e. same directory as erts etc.)
@@ -1286,20 +1452,6 @@ do_create_p1g(Conf,TargetDir) ->
%% Create RELEASES
ok = release_handler:create_RELEASES(TargetDir,ReleasesDir,RelFile,[]),
- %% Create start_erl
- ok = subst_file(filename:join([ErtsBinDir,"start_erl.src"]),
- filename:join([BinDir,"start_erl"]),
- [{"EMU","beam"}],
- [{chmod,8#0755}]),
-
- %% Create start script
- %% Using a customized start script from DataDir where some options
- %% (heart and nodename) are added compared to the start.src in the
- %% erlang distribution.
- ok = subst_file(filename:join(DataDir, "start"),
- filename:join([BinDir, "start"]),
- [{"ROOT",TargetDir}],
- [preserve]),
ok.
%% Create version P1H - which is P1G + a-1.0
@@ -1336,12 +1488,12 @@ create_upgrade_release(Conf,RelName,RelVsn,Erts,Apps,Config,{UpFromName,Descr})
UpFrom = [{filename:join([PrivDir,UpFromName,UpFromName]),Descr}],
- create_basic_release(RelFile, RelVsn, Erts, LibPath,
+ create_basic_release(Conf, RelFile, RelVsn, Erts, LibPath,
Apps, Config, UpFrom, []),
ok.
%% Create .rel, .script, .boot, sys.config and tar
-create_basic_release(RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) ->
+create_basic_release(Conf, RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,UpFrom,DownTo) ->
RelDir = filename:dirname(RelFile),
RelFileName = filename:rootname(RelFile),
@@ -1370,7 +1522,14 @@ create_basic_release(RelFile,RelVsn,{ErtsVsn,ErtsDir},LibPath,ExtraApps,Config,U
_ -> [{erts,ErtsDir}]
end]),
- RelFileName ++ ".tar.gz".
+ TarFileName = RelFileName ++ ".tar.gz",
+
+ case os:type() of
+ {win32,_} when ErtsDir=/=false -> modify_tar_win32(Conf, TarFileName);
+ _ -> ok
+ end,
+
+ TarFileName.
%% Create a .rel file
create_installer_rel_file(RelFile,RelVsn,ErtsVsn,ExtraApps) ->
@@ -1470,21 +1629,70 @@ permanent_p1h(Node) ->
copy_installed(Conf,FromNode,ToNodes) ->
PrivDir = priv_dir(Conf),
DataDir = ?config(data_dir,Conf),
+
+ %% Instead of using copy_tree on the complete node directory, I'm
+ %% splitting this in separate tar files per subdirectory so the
+ %% log directory can be completely skipped. The reason for this is
+ %% that the tar file might become faulty if the node is alive and
+ %% writing to the log while the tar is created.
+ FromDir = filename:join(PrivDir,FromNode),
+ {ok,FromDirNames} = file:list_dir(FromDir),
+ TempTarFiles =
+ [begin
+ TempTarFile = filename:join(PrivDir,"temp_" ++ FDN ++ ".tar"),
+ {ok,Tar} = erl_tar:open(TempTarFile,[write]),
+ ok = erl_tar:add(Tar,filename:join(FromDir,FDN),FDN,[]),
+ ok = erl_tar:close(Tar),
+ TempTarFile
+ end || FDN <- FromDirNames, FDN=/="log"],
lists:foreach(
fun(Node) ->
- ok = copy_tree(Conf,filename:join(PrivDir,FromNode),Node,PrivDir),
NodeDir = filename:join(PrivDir,Node),
- ok = subst_file(filename:join(DataDir, "start"),
- filename:join([NodeDir, "bin", "start"]),
- [{"ROOT",NodeDir}]),
- LogDir = filename:join(NodeDir,log),
- {ok,Logs} = file:list_dir(LogDir),
- lists:foreach(fun(Log) ->
- file:delete(filename:join(LogDir,Log))
- end,
- Logs)
+ ok = filelib:ensure_dir(filename:join([NodeDir,"log","*"])),
+ lists:foreach(
+ fun(TempTarFile) ->
+ ok = erl_tar:extract(TempTarFile,[{cwd,NodeDir}])
+ end, TempTarFiles),
+ case os:type() of
+ {unix,_} ->
+ %% Create start script
+ %% Using a customized start script from DataDir
+ %% where some options (heart and nodename) are
+ %% added compared to the start.src in the erlang
+ %% distribution.
+ ok = subst_file(filename:join(DataDir, "start"),
+ filename:join([NodeDir, "bin", "start"]),
+ [{"ROOT",NodeDir}],
+ [preserve]);
+ {win32,_} ->
+ %% Write erl.ini
+ ErtsDirs =
+ filelib:wildcard(filename:join(NodeDir,"erts-*")),
+ lists:foreach(
+ fun(ErtsDir) ->
+ ok = subst_file(
+ filename:join(DataDir, "erl.ini.src"),
+ filename:join([ErtsDir, "bin", "erl.ini"]),
+ [{"ROOTDIR",NodeDir},
+ {"BINDIR",filename:join(ErtsDir,"bin")}])
+ end,
+ ErtsDirs),
+
+ %% The service on windows runs as local
+ %% administrator (not otptest user), so we need
+ %% to chmod the release in order to allow the
+ %% executing node to install releases, write
+ %% logs etc.
+ chmod_release_win32(NodeDir)
+ end
end,
- ToNodes).
+ ToNodes),
+
+ lists:foreach(fun(TempTarFile) -> file:delete(TempTarFile) end, TempTarFiles),
+ ok.
+
+chmod_release_win32(Dir) ->
+ os:cmd("echo y|cacls " ++ Dir ++ " /T /E /G Administrators:F").
start_nodes(Conf,Snames,Tag) ->
PrivDir = priv_dir(Conf),
@@ -1493,19 +1701,42 @@ start_nodes(Conf,Snames,Tag) ->
fun(Sname) ->
NodeDir = filename:join(PrivDir,Sname),
Node = node_name(Sname),
-
- Script = filename:join([NodeDir,"bin","start"]),
- Cmd = "env NODENAME="++atom_to_list(Sname) ++ " " ++ Script,
- %% {ok,StartFile} = file:read_file(Cmd),
- %% io:format("~s:\n~s~n~n",[Start,binary_to_list(StartFile)]),
- Res = os:cmd(Cmd),
- io:format("Start ~p: ~p~n=>\t~p~n", [Sname,Cmd,Res]),
+
+ case os:type() of
+ {unix,_} ->
+ start_node_unix(Sname,NodeDir);
+ {win32,_} ->
+ start_node_win32(Sname,NodeDir)
+ end,
Node
end,
Snames),
wait_nodes_up(Nodes,Tag),
Nodes.
+start_node_unix(Sname,NodeDir) ->
+ Script = filename:join([NodeDir,"bin","start"]),
+ Cmd = "env NODENAME="++atom_to_list(Sname) ++ " " ++ Script,
+ %% {ok,StartFile} = file:read_file(Cmd),
+ %% io:format("~s:\n~s~n~n",[Start,binary_to_list(StartFile)]),
+ Res = os:cmd(Cmd),
+ io:format("Start ~p: ~p~n=>\t~p~n", [Sname,Cmd,Res]).
+
+start_node_win32(Sname,NodeDir) ->
+ Name = atom_to_list(Sname) ++ "_P1G",
+ ErtsBinDir = filename:join(NodeDir,"erts-4.4/bin"),
+
+ StartErlArgs = rh_test_lib:get_start_erl_args(NodeDir),
+ ServiceArgs = rh_test_lib:get_service_args(NodeDir, Sname, StartErlArgs),
+
+ Erlsrv = filename:nativename(filename:join(ErtsBinDir,"erlsrv")),
+ rh_test_lib:erlsrv(Erlsrv,stop,Name),
+ rh_test_lib:erlsrv(Erlsrv,remove,Name),
+ ok = rh_test_lib:erlsrv(Erlsrv,add,Name,ServiceArgs),
+ ok = rh_test_lib:erlsrv(Erlsrv,start,Name),
+ ok.
+
+%% Create a unique node name for each test case
tc_sname(Config) ->
tc_sname(Config,"").
tc_sname(Config,Fix) when is_atom(Fix) ->
@@ -1649,3 +1880,32 @@ create_fake_release(Dir,RelName,RelVsn,AppDirs) ->
rpc_inst(Node,Func,Args) ->
rpc:call(Node,installer,Func,[node()|Args]).
+
+delete_all_services() ->
+ ErlSrv = erlsrv:erlsrv(erlang:system_info(version)),
+ [_|Serviceinfo] = string:tokens(os:cmd(ErlSrv ++ " list"),"\n"),
+ Services =
+ [lists:takewhile(fun($\t) -> false; (_) -> true end,S)
+ || S <- Serviceinfo],
+ ?t:format("Services to remove: ~p~n",[Services]),
+ lists:foreach(fun(S) ->
+ rh_test_lib:erlsrv(ErlSrv,stop,S),
+ rh_test_lib:erlsrv(ErlSrv,remove,S)
+ end,
+ Services).
+
+modify_tar_win32(Conf, TarFileName) ->
+ DataDir = ?config(data_dir,Conf),
+ PrivDir = priv_dir(Conf),
+ TmpDir = filename:join(PrivDir,"tmp_modify_tar_win32"),
+ ok = erl_tar:extract(TarFileName,[{cwd,TmpDir},compressed]),
+
+ ErtsBinDir = filelib:wildcard(filename:join([TmpDir,"erts-*","bin"])),
+ ok = copy_file(filename:join(DataDir, "heart_restart.bat"),
+ ErtsBinDir,[preserve]),
+
+ {ok,Fs} = file:list_dir(TmpDir),
+ {ok,T} = erl_tar:open(TarFileName,[write,compressed]),
+ [ok = erl_tar:add(T,filename:join(TmpDir,F),F,[]) || F <- Fs],
+ ok = erl_tar:close(T),
+ ok.
diff --git a/lib/sasl/test/release_handler_SUITE_data/Makefile.src b/lib/sasl/test/release_handler_SUITE_data/Makefile.src
index 85e25fdc2f..a12e526d2e 100644
--- a/lib/sasl/test/release_handler_SUITE_data/Makefile.src
+++ b/lib/sasl/test/release_handler_SUITE_data/Makefile.src
@@ -1,14 +1,19 @@
EFLAGS=+debug_info
P2B= \
- P2B/a-2.0/ebin/a.beam \
- P2B/a-2.0/ebin/a_sup.beam
+ P2B/a-2.0/ebin/a.@EMULATOR@ \
+ P2B/a-2.0/ebin/a_sup.@EMULATOR@
LIB= \
- lib/a-1.1/ebin/a.beam \
- lib/a-1.1/ebin/a_sup.beam \
- lib/a-1.0/ebin/a.beam \
- lib/a-1.0/ebin/a_sup.beam \
+ lib/a-1.2/ebin/a.@EMULATOR@ \
+ lib/a-1.2/ebin/a_sup.@EMULATOR@ \
+ lib/a-1.1/ebin/a.@EMULATOR@ \
+ lib/a-1.1/ebin/a_sup.@EMULATOR@ \
+ lib/a-1.0/ebin/a.@EMULATOR@ \
+ lib/a-1.0/ebin/a_sup.@EMULATOR@ \
+ lib/b-1.0/ebin/b_server.@EMULATOR@ \
+ lib/b-1.0/ebin/b_lib.@EMULATOR@ \
+ lib/b-2.0/ebin/b_server.@EMULATOR@
APP= \
app1_app2/lib1/app1-1.0/ebin/app1_sup.@EMULATOR@ \
@@ -57,6 +62,21 @@ lib/a-1.1/ebin/a_sup.@EMULATOR@: lib/a-1.1/src/a_sup.erl
erlc $(EFLAGS) -olib/a-1.1/ebin lib/a-1.1/src/a_sup.erl
+lib/a-1.2/ebin/a.@EMULATOR@: lib/a-1.2/src/a.erl
+ erlc $(EFLAGS) -olib/a-1.2/ebin lib/a-1.2/src/a.erl
+lib/a-1.2/ebin/a_sup.@EMULATOR@: lib/a-1.2/src/a_sup.erl
+ erlc $(EFLAGS) -olib/a-1.2/ebin lib/a-1.2/src/a_sup.erl
+
+lib/b-1.0/ebin/b_server.@EMULATOR@: lib/b-1.0/src/b_server.erl
+ erlc $(EFLAGS) -olib/b-1.0/ebin lib/b-1.0/src/b_server.erl
+lib/b-1.0/ebin/b_lib.@EMULATOR@: lib/b-1.0/src/b_lib.erl
+ erlc $(EFLAGS) -olib/b-1.0/ebin lib/b-1.0/src/b_lib.erl
+
+lib/b-2.0/ebin/b_server.@EMULATOR@: lib/b-2.0/src/b_server.erl
+ erlc $(EFLAGS) -olib/b-2.0/ebin lib/b-2.0/src/b_server.erl
+
+
+
app1_app2/lib1/app1-1.0/ebin/app1_sup.@EMULATOR@: app1_app2/lib1/app1-1.0/src/app1_sup.erl
erlc $(EFLAGS) -oapp1_app2/lib1/app1-1.0/ebin app1_app2/lib1/app1-1.0/src/app1_sup.erl
app1_app2/lib1/app1-1.0/ebin/app1_server.@EMULATOR@: app1_app2/lib1/app1-1.0/src/app1_server.erl
diff --git a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1 b/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1
deleted file mode 100755
index ee3d8c97cf..0000000000
--- a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli1
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-#
-# This program invokes the erlang emulator by calling run_erl.
-# It should only be used at an embedded target system.
-# It should be modified to give the correct flags to erl (via start_erl),
-# e.g -mode embedded -sname XXX
-#
-# Usage: start [Data]
-#
-
-if [ "x${NODENAME}" = "x" ]
-then
- echo "ERROR: Variable \$NODENAME is not set!!"
- exit 1
-fi
-
-TESTHOST=`hostname | sed 's/[.].*//'`
-IPADDR=%IPADDR%
-
-ROOTDIR=%ROOT%
-CLIENTDIR=$ROOTDIR/clients/type1/$NODENAME@$TESTHOST
-
-RELDIR=$CLIENTDIR/releases
-
-# Note that this scripts is modified an copied to $CLIENTDIR/bin/start
-# in release_handler_SUITE:copy_client - therefore HEART_COMMAND is as follows:
-HEART_COMMAND=$CLIENTDIR/bin/start
-HW_WD_DISABLE=true
-export HW_WD_DISABLE HEART_COMMAND
-
-START_ERL_DATA=${1:-$RELDIR/start_erl.data}
-
-if [ ! -d /tmp/$NODENAME@$TESTHOST ]
-then
- mkdir /tmp/$NODENAME@$TESTHOST
-fi
-
-$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME -sasl start_prg \\\"$CLIENTDIR/bin/start\\\" masters \[\\'%MASTER%@$TESTHOST\\'\] client_directory \\\"$CLIENTDIR\\\" -loader inet -id $NODENAME -hosts $IPADDR" > $CLIENTDIR/log/run_erl.out 2>&1 &
diff --git a/lib/sasl/test/release_handler_SUITE_data/erl.ini.src b/lib/sasl/test/release_handler_SUITE_data/erl.ini.src
new file mode 100644
index 0000000000..b8791e75a5
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/erl.ini.src
@@ -0,0 +1,4 @@
+[erlang]
+Bindir=%BINDIR%
+Progname=erl
+Rootdir=%ROOTDIR%
diff --git a/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat b/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat
new file mode 100755
index 0000000000..ede1ad4ff3
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/heart_restart.bat
@@ -0,0 +1,3 @@
+@echo off
+%ERLSRV_EXECUTABLE% stop %ERLSRV_SERVICE_NAME%
+%ERLSRV_EXECUTABLE% start %ERLSRV_SERVICE_NAME% \ No newline at end of file
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/README b/lib/sasl/test/release_handler_SUITE_data/lib/README
new file mode 100644
index 0000000000..667d21d4cf
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/README
@@ -0,0 +1,16 @@
+a-1.0:
+start version
+
+a-1.1:
+can be upgraded to from a-1.0. Module a has changed
+
+a-1.2:
+can be upgraded to from a-1.1.
+No module have changed, but priv dir is added including one 'file'
+
+b-1.0:
+start version, includes b_lib and b_server
+
+b-2.0:
+can be upgraded to from b-1.0.
+Removes b_lib and updates b_server
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.app b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.app
index e938137f67..b38722f06d 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.0/src/a.app
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.app
@@ -1,7 +1,7 @@
{application, a,
[{description, "A CXC 138 11"},
- {vsn, "1.0"},
- {modules, [{a, 1}, {a_sup,1}]},
+ {vsn, "1.2"},
+ {modules, [{a, 2}, {a_sup,1}]},
{registered, [a_sup]},
{applications, [kernel, stdlib]},
{env, [{key1, val1}]},
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.appup b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.appup
new file mode 100644
index 0000000000..3df0546316
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/ebin/a.appup
@@ -0,0 +1,3 @@
+{"1.2",
+ [{"1.1",[]}],
+ [{"1.1",[]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/priv/file b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/priv/file
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/priv/file
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
new file mode 100644
index 0000000000..c082ad5339
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a.erl
@@ -0,0 +1,54 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(a).
+
+
+-behaviour(gen_server).
+
+%% External exports
+-export([start_link/0, a/0, b/0]).
+%% Internal exports
+-export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]).
+
+start_link() -> gen_server:start_link({local, aa}, a, [], []).
+
+a() -> gen_server:call(aa, a).
+b() -> gen_server:call(aa, b).
+
+%%-----------------------------------------------------------------
+%% Callback functions from gen_server
+%%-----------------------------------------------------------------
+init([]) ->
+ process_flag(trap_exit, true),
+ {ok, {state, bval}}.
+
+handle_call(a, _From, State) ->
+ X = application:get_all_env(a),
+ {reply, X, State};
+
+handle_call(b, _From, State) ->
+ {reply, {ok, element(2, State)}, State}.
+
+handle_info(_, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(1, Extra, State) ->
+ {ok, {state, bval}}.
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
new file mode 100644
index 0000000000..a141c1767b
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/a-1.2/src/a_sup.erl
@@ -0,0 +1,37 @@
+%% ``The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved via the world wide web at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+-module(a_sup).
+
+
+-behaviour(supervisor).
+
+%% External exports
+-export([start/2]).
+
+%% Internal exports
+-export([init/1]).
+
+start(_, _) ->
+ supervisor:start_link({local, a_sup}, a_sup, []).
+
+init([]) ->
+ SupFlags = {one_for_one, 4, 3600},
+ Config = {a,
+ {a, start_link, []},
+ permanent, 2000, worker, [a]},
+ {ok, {SupFlags, [Config]}}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/ebin/b.app b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/ebin/b.app
new file mode 100644
index 0000000000..00347b2754
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/ebin/b.app
@@ -0,0 +1,7 @@
+%% -*- erlang -*-
+{application, b,
+ [{description, "B CXC 138 12"},
+ {vsn, "1.0"},
+ {modules, [{b_server, 1},{b_lib, 1}]},
+ {registered, [b_server]},
+ {applications, [kernel, stdlib]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_lib.erl b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_lib.erl
new file mode 100644
index 0000000000..7e8a308a5e
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_lib.erl
@@ -0,0 +1,3 @@
+-module(b_lib).
+-compile(export_all).
+foo() -> ok.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_server.erl b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_server.erl
new file mode 100644
index 0000000000..e1a80a076f
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-1.0/src/b_server.erl
@@ -0,0 +1,37 @@
+-module(b_server).
+
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, {}).
+
+start_link() ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
+
+init([]) ->
+ {ok, #state{}}.
+
+handle_call(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(OldVsn, State, Extra) ->
+ file:write_file("/tmp/b_server",io_lib:format("~p~n",[{"1.0",OldVsn,Extra}])),
+ {ok, State}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.app b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.app
new file mode 100644
index 0000000000..73c8e42b32
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.app
@@ -0,0 +1,7 @@
+%% -*- erlang -*-
+{application, b,
+ [{description, "B CXC 138 12"},
+ {vsn, "2.0"},
+ {modules, [{b_server, 1}]},
+ {registered, [b_server]},
+ {applications, [kernel, stdlib]}]}.
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
new file mode 100644
index 0000000000..d261a37732
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/ebin/b.appup
@@ -0,0 +1,3 @@
+{"2.0",
+ [{"1.0",[{delete_module,b_lib}, {update,b_server,{advanced,[]}}]}],
+ [{"1.0",[{add_module,b_lib},{update,b_server,{advanced,[]}}]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_lib.erl b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_lib.erl
new file mode 100644
index 0000000000..7e8a308a5e
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_lib.erl
@@ -0,0 +1,3 @@
+-module(b_lib).
+-compile(export_all).
+foo() -> ok.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_server.erl b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_server.erl
new file mode 100644
index 0000000000..f8bfbdaff7
--- /dev/null
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/b-2.0/src/b_server.erl
@@ -0,0 +1,37 @@
+-module(b_server).
+
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-define(SERVER, ?MODULE).
+
+-record(state, {}).
+
+start_link() ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
+
+init([]) ->
+ {ok, #state{}}.
+
+handle_call(_Request, _From, State) ->
+ Reply = ok,
+ {reply, Reply, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(OldVsn, State, Extra) ->
+ file:write_file("/tmp/b_server",io_lib:format("~p~n",[{"2.0",OldVsn,Extra}])),
+ {ok, State}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app b/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
index 6f77317f6a..e1391c0605 100644
--- a/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
+++ b/lib/sasl/test/release_handler_SUITE_data/lib/installer-1.0/ebin/installer.app
@@ -1,6 +1,6 @@
{application, installer,
[{description, "Installer application"},
{vsn, "1.0"},
- {modules, [{installer, 1}]},
+ {modules, [installer,rh_test_lib]},
{registered, []},
{applications, [kernel, stdlib, sasl]}]}.
diff --git a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli2 b/lib/sasl/test/release_handler_SUITE_data/start_client
index 88912cf884..5ea94d6f7c 100755
--- a/lib/sasl/test/release_handler_SUITE_data/clients/start_cli2
+++ b/lib/sasl/test/release_handler_SUITE_data/start_client
@@ -34,4 +34,4 @@ then
mkdir /tmp/$NODENAME@$TESTHOST
fi
-$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME -sasl start_prg \\\"$CLIENTDIR/bin/start\\\" masters \[\\'%MASTER%@$TESTHOST\\',\\'master2@$TESTHOST\\'\] client_directory \\\"$CLIENTDIR\\\"" > /dev/null 2>&1 &
+$ROOTDIR/bin/run_erl /tmp/$NODENAME@$TESTHOST/ $CLIENTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname $NODENAME %CLIENTARGS%" > $CLIENTDIR/log/run_erl.out 2>&1 &
diff --git a/lib/sasl/test/rh_test_lib.erl b/lib/sasl/test/rh_test_lib.erl
new file mode 100644
index 0000000000..99a7f919a7
--- /dev/null
+++ b/lib/sasl/test/rh_test_lib.erl
@@ -0,0 +1,100 @@
+-module(rh_test_lib).
+
+-export([erlsrv/3,
+ erlsrv/4]).
+-export([get_service_args/3,
+ get_service_args/4,
+ get_start_erl_args/1,
+ get_start_erl_args/3,
+ get_client_args/3,
+ get_client_args/4]).
+
+
+erlsrv(Erlsrv,Action,Name) ->
+ erlsrv(Erlsrv,Action,Name,"").
+erlsrv(Erlsrv,Action,Name,Rest) ->
+ Cmd = Erlsrv ++ " " ++ atom_to_list(Action) ++ " " ++ Name ++ " " ++ Rest,
+ io:format("erlsrv cmd: ~p~n",[Cmd]),
+ Port = open_port({spawn, Cmd}, [stream, {line, 100}, eof, in]),
+ Res = recv_prog_output(Port),
+ case Res of
+ [] ->
+ failed;
+ _Y ->
+ io:format("erlsrv res: ~p~n",[_Y]),
+ ok
+ end.
+
+recv_prog_output(Port) ->
+ receive
+ {Port, {data, {eol,Data}}} ->
+ %%io:format("Got data: ~s~n", [Data]),
+ [ Data, "\n" | recv_prog_output(Port)];
+ {Port, {data, {noeol,Data}}} ->
+ %%io:format("Got data: ~s~n", [Data]),
+ [ Data | recv_prog_output(Port)];
+ {Port, _Other} ->
+ %%io:format("Got ~p from port~n", [_Other]),
+ Port ! {self(), close},
+ receive
+ {Port,closed} ->
+ []
+ end
+ end.
+
+get_service_args(RootDir, Sname, StartErlArgs) ->
+ get_service_args(RootDir, "", Sname, StartErlArgs).
+get_service_args(RootDir, RelClientDir, Sname, StartErlArgs) ->
+ LogDir = filename:nativename(filename:join([RootDir,RelClientDir,"log"])),
+ %% start_erl.exe will be found since it is in the same directory as erlsrv.exe
+ %% And heart_restart.bat will be found since the erts bin dir is
+ %% always in the path for the erlang virtual machine.
+ " -machine start_erl.exe -workdir " ++ LogDir ++
+ " -debugtype new -sname " ++ atom_to_list(Sname) ++
+ " -env HEART_COMMAND=heart_restart.bat -args \"" ++ StartErlArgs ++ "\"".
+
+get_start_erl_args(RootDir) ->
+ get_start_erl_args(RootDir,"","").
+get_start_erl_args(RootDir,RelClientDir,ExtraArgs) ->
+ Cookie = atom_to_list(erlang:get_cookie()),
+ RelDir = filename:join([RootDir,RelClientDir,"releases"]),
+ ExtraArgs ++ " -setcookie " ++ Cookie ++
+ " -heart ++ -rootdir " ++ filename:nativename(RootDir) ++
+ " -reldir " ++ filename:nativename(RelDir).
+
+%% Must be called on the master node
+get_client_args(Client,Sname,RootDir) ->
+ get_client_args(Client,Sname,RootDir,node()).
+get_client_args(Client,Sname,RootDir,Master) ->
+ {ok,Host} = inet:gethostname(),
+ Node = atom_to_list(Sname) ++ "@" ++ Host,
+ RelClientDir = filename:join(["clients","type1",Node]),
+ ClientDir = filename:join([RootDir,RelClientDir]),
+ StartPrg = filename:join([ClientDir,"bin","start"]),
+ {" -sasl start_prg \\\\\\\"" ++ StartPrg ++ "\\\\\\\" masters \[" ++
+ single_quote() ++ atom_to_list(Master) ++ single_quote() ++
+ get_client_extra_master(Client,Host) ++
+ "\] client_directory \\\\\\\"" ++ ClientDir ++ "\\\\\\\"" ++
+ get_client_loader_args(Client,Sname,Host),
+ RelClientDir}.
+
+get_client_loader_args(client1,Sname,Host) ->
+ {ok,IpTuple} = inet:getaddr(Host,inet),
+ IpAddr = inet_parse:ntoa(IpTuple),
+ " -loader inet -id " ++
+ atom_to_list(Sname) ++ " -hosts " ++ IpAddr;
+get_client_loader_args(_,_,_) ->
+ "".
+
+get_client_extra_master(client2,Host) ->
+ "," ++ single_quote() ++ "master2@" ++ Host ++ single_quote();
+get_client_extra_master(_,_) ->
+ "".
+
+single_quote() ->
+ case os:type() of
+ {win32,_} ->
+ "\'";
+ _ ->
+ "\\'"
+ end.
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index 8112d145dd..26dc2c1448 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 2.1.9.3
+SASL_VSN = 2.1.9.4
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile
index 20e3d4692a..c55eff04c6 100644
--- a/lib/snmp/Makefile
+++ b/lib/snmp/Makefile
@@ -67,7 +67,7 @@ do_configure: configure
configure: configure.in
autoconf
-.PHONY: info
+.PHONY: info gclean
info:
@echo "OS: $(OS)"
@@ -76,6 +76,9 @@ info:
@echo "SNMP_VSN: $(SNMP_VSN)"
@echo "APP_VSN: $(APP_VSN)"
+gclean:
+ git clean -fXd
+
# ----------------------------------------------------
# Application (source) release targets
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index 35ed63e103..aa9431477c 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -152,6 +152,7 @@ $(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
html: gifs $(HTML_REF_MAN_FILE)
+html2: html $(INDEX_TARGET)
clean clean_docs: clean_html clean_man clean_pdf
rm -f errs core *~
@@ -228,6 +229,7 @@ clean_man:
clean_html:
@echo "cleaning html:"
rm -rf $(HTMLDIR)/*
+ rm -f $(INDEX_TARGET)
$(MAN7DIR)/%.7: $(MIBSDIR)/%.mib
@echo "processing $*"
@@ -286,7 +288,7 @@ release_docs_spec: docs
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
$(INSTALL_DIR) $(RELEASE_PATH)/man/man1
$(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1
- $(INSTALL_DIR) $(RELEASE_PATH)/man/man
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
$(INSTALL_DIR) $(RELEASE_PATH)/man/man6
$(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 6a20d8ee3a..4178192120 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,136 @@
</header>
<section>
+ <title>SNMP Development Toolkit 4.21</title>
+ <p>Version 4.21 supports code replacement in runtime from/to
+ version 4.20.1, 4.20 and 4.19. </p>
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[manager] There was no way to specify transport domain.
+ The transport domains was assumed to be IPv4 (transportDomainUdpIpv4).
+ This has now been changed so that it can also be IPv6
+ (transportDomainUdpIpv6).
+ To facilitate this, the transport domain, <c>tdomain</c>,
+ is now a (new) valid option when
+ <seealso marker="snmpm#register_agent">registering</seealso>
+ a new agent (and
+ <seealso marker="snmpm#update_agent_info">updating</seealso>
+ agent info). </p>
+ <p>This also mean that the transport behaviour has changed. </p>
+ <p>Own Id: OTP-9305</p>
+ <p>Aux Id: Seq 11847</p>
+ </item>
+
+ <item>
+ <p>[compiler] Added the option
+ <seealso marker="snmpc#compile">warnings_as_errors</seealso>
+ (for the SNMP MIB compiler (escript) frontend, the option
+ <seealso marker="snmpc(command)#option_wae">--wae</seealso> is used)
+ which specifies whether warnings should be treated as errors. </p>
+ <p>Tuncer Ayaz</p>
+ <p>Own Id: OTP-9437</p>
+ </item>
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>The snmp config tool could not handle (manager) audit trail config
+ because the option seqno was not handled. </p>
+ <p>Own Id: OTP-9354</p>
+ </item>
+
+ <item>
+ <p>[agent] The SNMP ACM cache was not properly updated when
+ changes where made to the VACM security-to-group, access and
+ view-tree-family tables. </p>
+ <p>Own Id: OTP-9367</p>
+ <p>Aux Id: Seq 11858</p>
+ </item>
+
+ <item>
+ <p>Fixed install directory typo for man3. </p>
+ <p>Peter Lemenkov</p>
+ <p>Hans Ulrich Niedermann</p>
+ <p>Own Id: OTP-9442</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.21 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.20.1</title>
+ <p>Version 4.20.1 supports code replacement in runtime from/to
+ version 4.20, 4.19 and 4.18.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <p>-</p>
+<!--
+ <list type="bulleted">
+ <item>
+ <p>Added type specs for functions that do not return. </p>
+ <p>Kostis Sagonas</p>
+ <p>Own Id: OTP-9208</p>
+ </item>
+ </list>
+-->
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[agent] Did not handle transport domains properly in some cases,
+ for instance trap sending. </p>
+ <p>Own Id: OTP-9400</p>
+ </item>
+
+ <item>
+ <p>[agent] Wrong default transport domain, snmpUDPDomain, instead
+ of transportDomainUdpIpv4. </p>
+ <p>Own Id: OTP-9425</p>
+ <p>Aux Id: Seq 11874</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.20.1 -->
+
+
+ <section>
<title>SNMP Development Toolkit 4.20</title>
<p>Version 4.20 supports code replacement in runtime from/to
version 4.19 and 4.18.</p>
diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml
index 14ef3630b5..8f1d860d58 100644
--- a/lib/snmp/doc/src/snmp_agent_netif.xml
+++ b/lib/snmp/doc/src/snmp_agent_netif.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml
index 771629492d..61d19251c5 100644
--- a/lib/snmp/doc/src/snmpc.xml
+++ b/lib/snmp/doc/src/snmpc.xml
@@ -48,7 +48,11 @@
<type>
<v>File = string()</v>
<v>Options = [opt()]</v>
- <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | module_compliance() | agent_capabilities() | outdir() | no_defs() | verbosity() | warnings()</v>
+ <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() |
+ description() | reference() | group_check() | i() | il() |
+ imports() | module() | module_identity() | module_compliance() |
+ agent_capabilities() | outdir() | no_defs() | verbosity() |
+ warnings() | warnings_as_errors()</v>
<v>db() = {db, volatile|persistent|mnesia}</v>
<v>deprecated() = {deprecated, bool()}</v>
<v>relaxed_row_name_assign_check() = relaxed_row_name_assign_check</v>
@@ -66,6 +70,7 @@
<v>outdir() = {outdir, dir()}</v>
<v>verbosity() = {verbosity, silence|warning|info|log|debug|trace}</v>
<v>warnings() = {warnings, bool()}</v>
+ <v>warnings_as_errors() = warnings_as_errors</v>
<v>dir() = string()</v>
<v>BinFileName = string()</v>
</type>
@@ -200,11 +205,17 @@
<item>
<p>The option <c>warnings</c> specifies whether warning
- messages should be shown. </p>
+ messages should be shown. </p>
<p>Default is <c>true</c>. </p>
</item>
+ <item>
+ <p>The option <c>warnings_as_errors</c>, if present, specifies
+ whether warnings should be treated as errors.</p>
+ </item>
+
</list>
+
<p>The MIB compiler understands both SMIv1 and SMIv2 MIBs. It
uses the <c>MODULE-IDENTITY</c> statement to determine if the MIB is
version 1 or 2.
diff --git a/lib/snmp/doc/src/snmpc_cmd.xml b/lib/snmp/doc/src/snmpc_cmd.xml
index 9358382a10..72116f8981 100644
--- a/lib/snmp/doc/src/snmpc_cmd.xml
+++ b/lib/snmp/doc/src/snmpc_cmd.xml
@@ -50,6 +50,8 @@
with definitions of Erlang constants for the objects in
the MIB, see
<seealso marker="snmpc#mib_to_hrl">mib_to_hrl/1</seealso>. </p>
+
+ <marker id="options"></marker>
</desc>
</func>
</funcs>
@@ -58,15 +60,18 @@
<title>Compiler options</title>
<p>The following options are supported (note that most of these relate
to the compilation of the MIB file):</p>
+ <marker id="option_help"></marker>
<taglist>
<tag>--help</tag>
<item>
<p>Prints help info.</p>
+ <marker id="option_version"></marker>
</item>
<tag>--version</tag>
<item>
<p>Prints application and mib format version.</p>
+ <marker id="option_verbosity"></marker>
</item>
<tag>--verbosity <em>verbosity</em></tag>
@@ -74,11 +79,20 @@
<p>Print debug info. </p>
<p><c>verbosity</c> = <c>trace</c> | <c>debug</c> | <c>log</c> | <c>info</c> | <c>silence</c></p>
<p>Defaults to <c>silence</c>.</p>
+ <marker id="option_warnings"></marker>
</item>
<tag>--warnings</tag>
<item>
<p>Print warning messages. </p>
+ <marker id="option_wae"></marker>
+ </item>
+
+ <tag>--wae</tag>
+ <item>
+ <p>Warnings as errors.
+ Indicates that warnings shall be treated as errors. </p>
+ <marker id="option_odir"></marker>
</item>
<tag>--o <em>directory</em></tag>
@@ -86,6 +100,7 @@
<p>The directory where the compiler should place the output files.
If not specified, output files will be placed in the current working
directory.</p>
+ <marker id="option_idir"></marker>
</item>
<tag>--i <em>Directory</em></tag>
@@ -94,6 +109,7 @@
By default, the current working directory is always included. </p>
<p>This option can be present several times, each time specifying
<em>one</em> path. </p>
+ <marker id="option_ildir"></marker>
</item>
<tag>--il <em>Directory</em></tag>
@@ -106,6 +122,7 @@
the current version may be in the system). The current directory
and the "snmp-home"/priv/mibs/ are always listed last in the
include path. </p>
+ <marker id="option_sgc"></marker>
</item>
<tag>--sgc</tag>
@@ -114,42 +131,50 @@
group check of the mib compiler.
That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP
macro(s) be checked for correctness or not. </p>
+ <marker id="option_dep"></marker>
</item>
<tag>--dep</tag>
<item>
<p>Keep deprecated definition(s).
If not specified the compiler will ignore deprecated definitions. </p>
+ <marker id="option_desc"></marker>
</item>
<tag>--desc</tag>
<item>
<p>The DESCRIPTION field will be included. </p>
+ <marker id="option_ref"></marker>
</item>
<tag>--ref</tag>
<item>
<p>The REFERENCE field will be included. </p>
+ <marker id="option_imp"></marker>
</item>
<tag>--imp</tag>
<item>
<p>The IMPORTS field will be included. </p>
+ <marker id="option_mi"></marker>
</item>
<tag>--mi</tag>
<item>
<p>The MODULE-IDENTITY field will be included. </p>
+ <marker id="option_mc"></marker>
</item>
<tag>--mc</tag>
<item>
<p>The MODULE-COMPLIANCE field will be included. </p>
+ <marker id="option_ac"></marker>
</item>
<tag>--ac</tag>
<item>
<p>The AGENT-CAPABILITIES field will be included. </p>
+ <marker id="option_mod"></marker>
</item>
<tag>--mod <em>module</em></tag>
@@ -157,6 +182,7 @@
<p>The module which implements all the instrumentation functions. </p>
<p>The name of all instrumentation functions must be the
same as the corresponding managed object it implements. </p>
+ <marker id="option_nd"></marker>
</item>
<tag>--nd</tag>
@@ -165,6 +191,7 @@
used if a managed object have no instrumentation function.
Instead this will be reported as an error, and the compilation
aborts. </p>
+ <marker id="option_rrnac"></marker>
</item>
<tag>--rrnac</tag>
@@ -176,6 +203,7 @@
This means that the error will be converted to a warning. </p>
<p>By default it is not included, but if this option is present
it will be. </p>
+ <marker id="see_also"></marker>
</item>
</taglist>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index 72849b9c9e..c36a1b2a24 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2010</year>
+ <year>2004</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -283,27 +283,27 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
<v>TargetName = target_name()</v>
<v>Config = [agent_config()]</v>
<v>agent_config() = {Item, Val}</v>
- <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level</v>
+ <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level | tdomain</v>
<v>Val = term()</v>
<v>Reason = term()</v>
</type>
<desc>
<p>Explicitly instruct the manager to handle this agent, with
- <c>UserId</c> as the responsible user. </p>
- <p>Called to instruct the manager that this agent
- shall be handled. This function is used when
- the user knows in advance which agents the
- manager shall handle.
- Note that there is an alternate way to do the same thing:
- Add the agent to the manager config files (see
- <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p>
+ <c>UserId</c> as the responsible user. </p>
+ <p>Called to instruct the manager that this agent shall be handled.
+ This function is used when the user knows in advance which agents
+ the manager shall handle.
+ Note that there is an alternate way to do the same thing:
+ Add the agent to the manager config files (see
+ <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p>
<p><c>TargetName</c> is a non-empty string,
- uniquely identifying the agent. </p>
- <p>The type of <c>Val</c> depends on <c>Item</c>: </p>
+ uniquely identifying the agent. </p>
+ <p>The type of <c>Val</c> depends on <c>Item</c>: </p>
<code type="none"><![CDATA[
[mandatory] engine_id = string()
[mandatory] address = ip_address()
[optional] port = integer()
+[optional] tdomain = transportDomainUdpIpv4 | transportDomainUdpIpv6
[optional] community = string()
[optional] timeout = integer() | snmp_timer()
[optional] max_message_size = integer()
@@ -312,7 +312,9 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
[optional] sec_name = string()
[optional] sec_level = noAuthNoPriv | authNoPriv | authPriv
]]></code>
- <p>Note that if no <c>Port</c> is given, the default value is used.</p>
+ <p>Note that if no <c>tdomain</c> is given, the default value,
+ <c>transportDomainUdpIpv4</c>, is used.</p>
+ <p>Note that if no <c>port</c> is given, the default value is used.</p>
<marker id="unregister_agent"></marker>
</desc>
@@ -348,17 +350,25 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
</func>
<func>
+ <name>update_agent_info(UserId, TargetName, Info) -> ok | {error, Reason}</name>
<name>update_agent_info(UserId, TargetName, Item, Val) -> ok | {error, Reason}</name>
<fsummary>Update agent config</fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>Item = atom()</v>
- <v>Val = term()</v>
+ <v>Info = [{item(), item_value()}]</v>
+ <v>Item = item()</v>
+ <v>item() = atom()</v>
+ <v>Val = item_value()</v>
+ <v>item_value() = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Update agent config.</p>
+ <p>Update agent config. The function <c>update_agent_info/3</c>
+ should be used when several values needs to be updated atomically. </p>
+ <p>See function
+ <seealso marker="#register_agent">register_agent</seealso>)
+ for more info about what kind of items are allowed. </p>
<marker id="which_agents"></marker>
</desc>
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 3debe0a30e..77307aa7ad 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl
index 3da5766b44..720ac749b8 100644
--- a/lib/snmp/src/agent/snmp_notification_mib.erl
+++ b/lib/snmp/src/agent/snmp_notification_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index b2f2417b02..77910541a2 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
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 28469a7b4e..37f6dd3f26 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -247,6 +247,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
Key = [Key1, length(Key2) | Key2],
case table_cre_row(vacmSecurityToGroupTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -260,6 +261,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
delete_sec2group(Key) ->
case table_del_row(vacmSecurityToGroupTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
@@ -279,6 +281,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
Key3 = [SM, SL],
Key = Key1 ++ Key2 ++ Key3,
snmpa_vacm:insert([{Key, Row}], false),
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
{error, Reason} ->
{error, Reason};
@@ -287,6 +290,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
end.
delete_access(Key) ->
+ snmpa_agent:invalidate_ca_cache(),
snmpa_vacm:delete(Key).
@@ -299,6 +303,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
Key = [length(Key1) | Key1] ++ [length(Key2) | Key2],
case table_cre_row(vacmViewTreeFamilyTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -312,6 +317,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
delete_view_tree_fam(Key) ->
case table_del_row(vacmViewTreeFamilyTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index b2e4f253ab..50b169e4e7 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmpa_acm.erl b/lib/snmp/src/agent/snmpa_acm.erl
index 30bd34a205..42a0d4d6a3 100644
--- a/lib/snmp/src/agent/snmpa_acm.erl
+++ b/lib/snmp/src/agent/snmpa_acm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index e4cfeddb6a..6322f0f21d 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1626,7 +1626,7 @@ invalidate_ca_cache() ->
MasterAgent ! invalidate_ca_cache;
false ->
%% This is running on a sub-agent node,
- %% so sent skip it
+ %% so skip it
ok
end;
_ -> % Not on this node
diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl
index d406c58ee4..b5ff8460c6 100644
--- a/lib/snmp/src/agent/snmpa_authentication_service.erl
+++ b/lib/snmp/src/agent/snmpa_authentication_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index 4e5aab5319..c17a6abbd7 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -424,7 +424,8 @@ target_addr_entry(Name,
EngineId,
TMask) ->
target_addr_entry(Name, Ip, 162, TagList,
- ParamsName, EngineId, TMask, 2048).
+ ParamsName, EngineId,
+ TMask, 2048).
target_addr_entry(Name,
Ip,
@@ -435,7 +436,8 @@ target_addr_entry(Name,
TMask,
MaxMessageSize) ->
target_addr_entry(Name, Ip, Udp, 1500, 3, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize).
+ ParamsName, EngineId,
+ TMask, MaxMessageSize).
target_addr_entry(Name,
Ip,
@@ -448,7 +450,8 @@ target_addr_entry(Name,
TMask,
MaxMessageSize) ->
target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp,
- Timeout, RetryCount, TagList, ParamsName,
+ Timeout, RetryCount, TagList,
+ ParamsName, EngineId,
TMask, MaxMessageSize).
target_addr_entry(Name,
diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl
index a91f30a4a6..a490a78f84 100644
--- a/lib/snmp/src/agent/snmpa_internal.hrl
+++ b/lib/snmp/src/agent/snmpa_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 39a4246d26..4f50b1a674 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -32,6 +32,7 @@
-include("SNMP-MPD-MIB.hrl").
-include("SNMPv2-TM.hrl").
-include("SNMP-FRAMEWORK-MIB.hrl").
+-include("TRANSPORT-ADDRESS-MIB.hrl").
-define(VMODULE,"MPD").
-include("snmp_verbosity.hrl").
@@ -981,12 +982,15 @@ generate_discovery_msg2(NoteStore, Pdu,
discovery_note_timeout(Timeout) ->
(Timeout div 100) + 1.
-generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
+generate_discovery_msg(NoteStore, {TDomain, TAddress},
Pdu, ScopedPduBytes,
ContextEngineID, ManagerEngineID,
SecModel, SecName, SecLevelFlag,
InitialUserName,
ContextName, Timeout) ->
+
+ {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress),
+
%% 7.1.7
?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]),
MsgID = generate_msg_id(),
@@ -1027,7 +1031,7 @@ generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
%% Log(Packet),
inc_snmp_out_vars(Pdu),
?vdebug("generate_discovery_msg -> done", []),
- {Packet, {{A,B,C,D}, U1 bsl 8 + U2}};
+ {Packet, Address};
Error ->
throw(Error)
@@ -1057,6 +1061,34 @@ generate_sec_discovery_msg(Message, SecModule,
end.
+transform_taddr(?snmpUDPDomain, TAddress) ->
+ transform_taddr(?transportDomainUdpIpv4, TAddress);
+transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) ->
+ Domain = transportDomainUdpIpv4,
+ Addr = {A,B,C,D},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv4, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv4_address, BadAddr}};
+transform_taddr(?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
+ Domain = transportDomainUdpIpv6,
+ Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv6, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv6_address, BadAddr}};
+transform_taddr(BadTDomain, TAddress) ->
+ case lists:member(BadTDomain, snmp_conf:all_tdomains()) of
+ true ->
+ {error, {unsupported_tdomain, BadTDomain, TAddress}};
+ false ->
+ {error, {unknown_tdomain, BadTDomain, TAddress}}
+ end.
+
+
process_taddrs(Dests) ->
?vtrace("process_taddrs -> entry with"
"~n Dests: ~p", [Dests]),
@@ -1066,46 +1098,44 @@ process_taddrs([], Acc) ->
?vtrace("process_taddrs -> entry when done with"
"~n Acc: ~p", [Acc]),
lists:reverse(Acc);
-
+
%% v3
-process_taddrs([{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T], Acc) ->
+process_taddrs([{{TDomain, TAddress}, SecData} | T], Acc) ->
?vtrace("process_taddrs -> entry when v3 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p"
- "~n SecData: ~p", [A, B, C, D, U1, U2, SecData]),
- Entry = {{snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, SecData},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v3
-process_taddrs([{{TDomain, TAddr}, _SecData} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v3 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p"
+ "~n SecData: ~p", [TDomain, TAddress, SecData]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = {DestAddr, SecData},
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v3 domain and address"
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
%% v1 & v2
-process_taddrs([{?snmpUDPDomain, [A,B,C,D,U1,U2]} | T], Acc) ->
+process_taddrs([{TDomain, TAddress} | T], Acc) ->
?vtrace("process_taddrs -> entry when v1/v2 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p", [A, B, C, D, U1, U2]),
- Entry = {snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v1 or v2
-process_taddrs([{TDomain, TAddr} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v1/v2 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p", [TDomain, TAddress]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = DestAddr,
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v1/v2 domain and address: "
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
process_taddrs(Crap, Acc) ->
- throw({error, {taddrs_crap, Crap, Acc}}).
+ throw({error, {bad_taddrs, Crap, Acc}}).
mk_v1_v2_packet_list(To, Packet, Len, Pdu) ->
diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl
index bbc5568cde..79c85a6e4e 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index 3c7ae804a5..567de020c0 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 5deb40be0f..8e1855b4df 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -22,82 +22,82 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.20.1",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
+ {"4.20",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
{"4.19",
[
{load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
{load_module, snmpa_usm, soft_purge, soft_purge, []},
{load_module, snmpm_usm, soft_purge, soft_purge, []},
{load_module, snmp_log, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_conf, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
{load_module, snmp_misc, soft_purge, soft_purge, []},
{load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
{load_module, snmpa_trap, soft_purge, soft_purge,
[snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
{load_module, snmpa_acm, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd, snmp_target_mib]},
{load_module, snmpa_conf, soft_purge, soft_purge,
- [snmp_notification_mib]},
+ [snmp_config, snmp_notification_mib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_notification_mib, soft_purge, soft_purge,
[snmp_conf, snmp_target_mib]},
{load_module, snmp_community_mib, soft_purge, soft_purge, []},
{load_module, snmp_target_mib, soft_purge, soft_purge,
[snmp_conf]},
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
- {update, snmpa_net_if, soft, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd]},
- {update, snmpa_agent, soft, soft_purge, soft_purge,
- [snmpa_acm, snmpa_mpd, snmpa_trap]}
- ]
- },
- {"4.18",
- [
- {load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmp_misc, soft_purge, soft_purge, []},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_config, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge,
- [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
- {load_module, snmpa_acm, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd, snmp_target_mib]},
- {load_module, snmpa, soft_purge, soft_purge,
- [snmp_community_mib,
- snmp_framework_mib,
- snmp_standard_mib,
- snmp_target_mib,
- snmp_user_based_sm_mib,
- snmp_view_based_acm_mib]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge,
- [snmp_conf, snmp_target_mib, snmpa_mib_lib]},
- {load_module, snmp_community_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib, snmpa_vacm]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
{update, snmpa_net_if, soft, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd]},
{update, snmpa_agent, soft, soft_purge, soft_purge,
@@ -109,84 +109,82 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.20.1",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
+ {"4.20",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
{"4.19",
[
{load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
{load_module, snmpa_usm, soft_purge, soft_purge, []},
{load_module, snmpm_usm, soft_purge, soft_purge, []},
{load_module, snmp_log, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_conf, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
{load_module, snmp_misc, soft_purge, soft_purge, []},
{load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
{load_module, snmpa_trap, soft_purge, soft_purge,
[snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
{load_module, snmpa_acm, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd, snmp_target_mib]},
{load_module, snmpa_conf, soft_purge, soft_purge,
- [snmp_notification_mib]},
+ [snmp_config, snmp_notification_mib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_notification_mib, soft_purge, soft_purge,
[snmp_conf, snmp_target_mib]},
{load_module, snmp_community_mib, soft_purge, soft_purge, []},
{load_module, snmp_target_mib, soft_purge, soft_purge,
[snmp_conf]},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
- {update, snmpa_net_if, soft, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd]},
- {update, snmpa_agent, soft, soft_purge, soft_purge,
- [snmpa_acm, snmpa_mpd, snmpa_trap]}
- ]
- },
- {"4.18",
- [
- {load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmp_misc, soft_purge, soft_purge, []},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge,
- [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
- {load_module, snmpa_acm, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd, snmp_target_mib]},
- {load_module, snmpa, soft_purge, soft_purge,
- [snmp_community_mib,
- snmp_framework_mib,
- snmp_standard_mib,
- snmp_target_mib,
- snmp_user_based_sm_mib,
- snmp_view_based_acm_mib]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge,
- [snmp_conf, snmp_target_mib, snmpa_mib_lib]},
- {load_module, snmp_community_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib, snmpa_vacm]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
{update, snmpa_net_if, soft, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd]},
{update, snmpa_agent, soft, soft_purge, soft_purge,
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index 0ceaf276a6..627af6f185 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -45,11 +45,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
include modules.mk
-ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
-
-ERL_FILES = $(MODULES:%=%.erl)
-
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ESCRIPT_BIN)
+ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
+ERL_FILES = $(MODULES:%=%.erl)
+EBIN_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+TARGET_FILES = $(EBIN_FILES) $(ESCRIPT_BIN)
GENERATED_PARSER = $(PARSER_MODULE:%=%.erl)
@@ -125,7 +124,7 @@ release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/src/compiler
$(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
$(INSTALL_DIR) $(RELSYSDIR)/ebin
- $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(EBIN_FILES) $(RELSYSDIR)/ebin
$(INSTALL_DIR) $(RELSYSDIR)/bin
$(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index 195c238184..5e6b81f1ec 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -108,6 +108,7 @@ compile(FileName) ->
%% {i, [import_dir_string()]} ["./"]
%% {il, [import_lib_dir_string()]} []
%% {warnings, bool()} true
+%% warnings_as_errors
%% {outdir, string()} "./"
%% description
%% reference
@@ -199,6 +200,8 @@ get_options([reference|Opts], Formats, Args) ->
get_options(Opts, ["~n reference"|Formats], Args);
get_options([{warnings, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n warnings: ~w"|Formats], [Val|Args]);
+get_options([warnings_as_errors|Opts], Formats, Args) ->
+ get_options(Opts, ["~n warnings_as_errors"|Formats], Args);
get_options([{verbosity, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n verbosity: ~w"|Formats], [Val|Args]);
get_options([imports|Opts], Formats, Args) ->
@@ -261,6 +264,8 @@ check_options([{group_check, Atom} | T]) when is_atom(Atom) ->
check_options([{warnings, Bool} | T]) ->
check_bool(warnings, Bool),
check_options(T);
+check_options([warnings_as_errors | T]) ->
+ check_options(T);
check_options([{db, volatile} | T]) ->
check_options(T);
check_options([{db, persistent} | T]) ->
@@ -331,6 +336,9 @@ get_agent_capabilities(Options) ->
get_module_compliance(Options) ->
get_bool_option(module_compliance, Options).
+get_warnings_as_errors(Options) ->
+ lists:member(warnings_as_errors, Options).
+
get_relaxed_row_name_assign_check(Options) ->
lists:member(relaxed_row_name_assign_check, Options).
@@ -409,6 +417,7 @@ init(From, MibFileName, Options) ->
put(reference, get_reference(Options)),
put(agent_capabilities, get_agent_capabilities(Options)),
put(module_compliance, get_module_compliance(Options)),
+ put(warnings_as_errors, get_warnings_as_errors(Options)),
File = filename:rootname(MibFileName, ".mib"),
put(filename, filename:basename(File ++ ".mib")),
R = case catch c_impl(File) of
diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src
index 5f9b154bfa..4e91ae9a03 100644
--- a/lib/snmp/src/compile/snmpc.src
+++ b/lib/snmp/src/compile/snmpc.src
@@ -50,7 +50,8 @@
%% The default verbosity (silence) will be filled in
%% during argument processing.
verbosity,
- warnings = false
+ warnings = false,
+ warnings_as_errors = false
}).
@@ -74,6 +75,7 @@
%% --version
%% --verbosity V
%% --warnings
+%% --wae
main(Args) when is_list(Args) ->
case (catch process_args(Args)) of
ok ->
@@ -156,7 +158,8 @@ mk_mib_options(#state{outdir = OutDir,
%% The default verbosity (silence) will be filled in
%% during argument processing.
verbosity = V,
- warnings = W}) ->
+ warnings = W,
+ warnings_as_errors = WAE}) ->
[{outdir, OutDir},
{db, DB},
{i, IDs},
@@ -178,7 +181,8 @@ mk_mib_options(#state{outdir = OutDir,
maybe_option(Imp, imports) ++
maybe_option(MI, module_identity) ++
maybe_option(MC, module_compliance) ++
- maybe_option(AC, agent_capabilities).
+ maybe_option(AC, agent_capabilities) ++
+ maybe_option(WE, warnings_as_errors).
maybe_option(true, Opt) -> [Opt];
maybe_option(_, _) -> [].
@@ -292,6 +296,8 @@ process_args(["--nd"|Args], State) ->
process_args(Args, State#state{no_defaults = true});
process_args(["--rrnac"|Args], State) ->
process_args(Args, State#state{relaxed_row_name_assigne_check = true});
+process_args(["--wae"|Args], State) ->
+ process_args(Args, State#state{warnings_as_errors = true});
process_args([MIB], State) ->
Ext = filename:extension(MIB),
if
@@ -371,6 +377,8 @@ usage() ->
"~n a warning. "
"~n By default it is not included, but if this option is "
"~n present it will be. "
+ "~n --wae - Warnings as errors. "
+ "~n Indicates that warnings shall be treated as errors. "
"~n "
"~n", []),
halt(1).
diff --git a/lib/snmp/src/compile/snmpc_lib.hrl b/lib/snmp/src/compile/snmpc_lib.hrl
index 000486e728..35ec9abd03 100644
--- a/lib/snmp/src/compile/snmpc_lib.hrl
+++ b/lib/snmp/src/compile/snmpc_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -20,8 +20,17 @@
-ifndef(snmpc_lib).
-define(snmpc_lib, true).
--define(vwarning(F, A), ?verbosity(warning, F, A, ignore)).
--define(vwarning2(F, A, MibLine), ?verbosity(warning, F, A, MibLine)).
+-define(vwarning(F, A),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A);
+ _ -> ?verbosity(warning, F, A, ignore)
+ end).
+
+-define(vwarning2(F, A, MibLine),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A, MibLine);
+ _ -> ?verbosity(warning, F, A, MibLine)
+ end).
-define(vinfo(F, A), ?verbosity(info, F, A, ignore)).
-define(vinfo2(F, A, MibLine), ?verbosity(info, F, A, MibLine)).
-define(vlog(F, A), ?verbosity(log, F, A, ignore)).
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index e457d3b47a..6d2ac8d747 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -50,7 +50,7 @@
register_agent/2, register_agent/3, register_agent/4,
unregister_agent/2, unregister_agent/3,
which_agents/0, which_agents/1,
- agent_info/2, update_agent_info/4,
+ agent_info/2, update_agent_info/3, update_agent_info/4,
register_usm_user/3, unregister_usm_user/2,
which_usm_users/0, which_usm_users/1,
@@ -167,6 +167,7 @@
-include_lib("snmp/include/snmp_types.hrl").
-include("snmpm_atl.hrl").
-include("snmpm_internal.hrl").
+-include("snmp_verbosity.hrl").
-define(DEFAULT_AGENT_PORT, 161).
@@ -447,8 +448,11 @@ agent_info(Addr, Port, Item) ->
Error
end.
+update_agent_info(UserId, TargetName, Info) when is_list(Info) ->
+ snmpm_config:update_agent_info(UserId, TargetName, Info).
+
update_agent_info(UserId, TargetName, Item, Val) ->
- snmpm_config:update_agent_info(UserId, TargetName, Item, Val).
+ update_agent_info(UserId, TargetName, [{Item, Val}]).
%% Backward compatibility functions
update_agent_info(UserId, Addr, Port, Item, Val) ->
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index fd6da3e71a..c2e57abddb 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -36,7 +36,8 @@
user_info/0, user_info/1, user_info/2,
register_agent/3, unregister_agent/2,
- agent_info/0, agent_info/2, agent_info/3, update_agent_info/4,
+ agent_info/0, agent_info/2, agent_info/3,
+ update_agent_info/3, update_agent_info/4,
which_agents/0, which_agents/1,
is_known_engine_id/2,
@@ -84,7 +85,9 @@
backup/1,
- mk_target_name/3
+ mk_target_name/3,
+
+ default_transport_domain/0
]).
@@ -127,23 +130,24 @@
%% Macros and Constants:
--define(SERVER, ?MODULE).
--define(BACKUP_DB, snmpm_config_backup).
--define(CONFIG_DB, snmpm_config_db).
+-define(SERVER, ?MODULE).
+-define(BACKUP_DB, snmpm_config_backup).
+-define(CONFIG_DB, snmpm_config_db).
-define(DEFAULT_USER, default_user).
-define(DEFAULT_AGENT_PORT, 161).
--define(IRB_DEFAULT, auto).
-%% -define(IRB_DEFAULT, {user, timer:seconds(15)}).
+-define(IRB_DEFAULT, auto).
+%% -define(IRB_DEFAULT, {user, timer:seconds(15)}).
--define(USER_MOD_DEFAULT, snmpm_user_default).
--define(USER_DATA_DEFAULT, undefined).
+-define(USER_MOD_DEFAULT, snmpm_user_default).
+-define(USER_DATA_DEFAULT, undefined).
%% -define(DEF_ADDR_TAG, default_addr_tag).
-define(DEFAULT_TARGETNAME, default_agent).
--define(DEF_PORT_TAG, default_port_tag).
+-define(DEF_PORT_TAG, default_port_tag).
+-define(SUPPORTED_DOMAINS, [transportDomainUdpIpv4, transportDomainUdpIpv6]).
-ifdef(snmp_debug).
-define(GS_START_LINK(Opts),
@@ -159,6 +163,11 @@
%%%-------------------------------------------------------------------
%%% API
%%%-------------------------------------------------------------------
+
+default_transport_domain() ->
+ transportDomainUdpIpv4.
+
+
start_link(Opts) ->
?d("start_link -> entry with"
"~n Opts: ~p", [Opts]),
@@ -269,9 +278,10 @@ do_user_info(_UserId, BadItem) ->
error({not_found, BadItem}).
-%% A target-name constructed in this way is a string with the following
+%% A target-name constructed in this way is a string with the following:
%% <IP-address>:<Port>-<Version>
-%%
+%% This is intended for backward compatibility and therefor has
+%% only support for IPv4 addresses and *no* other transport domain.
mk_target_name(Addr0, Port, Config) when is_list(Config) ->
Version =
case lists:keysearch(version, 1, Config) of
@@ -280,7 +290,6 @@ mk_target_name(Addr0, Port, Config) when is_list(Config) ->
false ->
select_lowest_supported_version()
end,
-%% p("mk_target_name -> Version: ~p", [Version]),
case normalize_address(Addr0) of
{A, B, C, D} ->
lists:flatten(
@@ -308,57 +317,99 @@ select_lowest_supported_version([H|T], Versions) ->
end.
-register_agent(UserId, _TargetName, _Config) when (UserId =:= user_id) ->
+register_agent(UserId, _TargetName, _Config0) when (UserId =:= user_id) ->
{error, {bad_user_id, UserId}};
-register_agent(UserId, TargetName, Config)
+register_agent(UserId, TargetName, Config0)
when (is_list(TargetName) andalso
(length(TargetName) > 0) andalso
- is_list(Config)) ->
+ is_list(Config0)) ->
-%% p("register_agent -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Config: ~p", [UserId, TargetName, Config]),
+ ?vtrace("register_agent -> entry with"
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Config0: ~p", [UserId, TargetName, Config0]),
%% Check:
%% 1) That the mandatory configs are present
- %% 2) That the illegal config user_id (used internally) is
- %% not present
+ %% 2) That no illegal config, e.g. user_id (used internally),
+ %% is not present
%% 3) Check that there are no invalid or erroneous configs
- %% 4) Chack that the manager is capable to use the selected version
- case verify_agent_config(Config) of
- ok ->
+ %% 4) Check that the manager is capable of using the selected version
+ case verify_agent_config(Config0) of
+ {ok, Config} ->
call({register_agent, UserId, TargetName, Config});
Error ->
Error
end.
-verify_agent_config(Conf) ->
- ok = verify_mandatory(Conf, [engine_id, address, reg_type]),
- case verify_invalid(Conf, [user_id]) of
- ok ->
- case verify_agent_config2(Conf) of
- ok ->
- {ok, Vsns} = system_info(versions),
- Vsn =
- case lists:keysearch(version, 1, Conf) of
- {value, {version, V}} ->
- V;
- false ->
- v1
- end,
- case lists:member(Vsn, Vsns) of
- true ->
- ok;
- false ->
- {error, {version_not_supported_by_manager, Vsn, Vsns}}
- end
- end;
- Error ->
+verify_agent_config(Conf0) ->
+ try
+ begin
+ verify_mandatory(Conf0, [engine_id, address, reg_type]),
+ verify_invalid(Conf0, [user_id]),
+ Conf = verify_agent_config3(Conf0),
+ Vsns = versions(),
+ Vsn = which_version(Conf),
+ verify_version(Vsn, Vsns),
+ {ok, Conf}
+ end
+ catch
+ throw:Error ->
Error
end.
+versions() ->
+ case system_info(versions) of
+ {ok, Vsns} ->
+ Vsns;
+ {error, _} = ERROR ->
+ throw(ERROR)
+ end.
+
+which_version(Conf) ->
+ case lists:keysearch(version, 1, Conf) of
+ {value, {version, V}} ->
+ V;
+ false ->
+ v1
+ end.
+
+verify_version(Vsn, Vsns) ->
+ case lists:member(Vsn, Vsns) of
+ true ->
+ ok;
+ false ->
+ Reason = {version_not_supported_by_manager, Vsn, Vsns},
+ throw({error, Reason})
+ end.
+
+verify_agent_config3(Conf0) ->
+ %% Fix (transport) address and domain
+ {TDomain, Conf1} =
+ case lists:keysearch(tdomain, 1, Conf0) of
+ {value, {tdomain, Dom}} ->
+ {Dom, Conf0};
+ false ->
+ Dom = default_transport_domain(),
+ {Dom, [{tdomain, Dom} | Conf0]}
+ end,
+ Conf2 = case lists:keysearch(address, 1, Conf1) of
+ {value, {address, Address}} ->
+ lists:keyreplace(address, 1, Conf1,
+ {address, {TDomain, Address}});
+ false ->
+ %% This is a mandatory config option,
+ %% a later test will detect this
+ Conf1
+ end,
+ case verify_agent2(Conf2) of
+ {ok, Conf} ->
+ Conf;
+ {error, _} = ERROR ->
+ throw(ERROR)
+ end.
+
verify_agent_config2(Conf) ->
verify_agent2(Conf).
@@ -366,6 +417,7 @@ verify_agent_config2(Conf) ->
unregister_agent(UserId, TargetName) ->
call({unregister_agent, UserId, TargetName}).
+%% This is the old style agent unregistration (using Addr and Port).
unregister_agent(UserId, Addr0, Port) ->
Addr = normalize_address(Addr0),
case do_agent_info(Addr, Port, target_name) of
@@ -421,17 +473,51 @@ which_agents(UserId) ->
Agents = ets:match(snmpm_agent_table, Pat),
[TargetName || [TargetName] <- Agents].
-
-update_agent_info(UserId, TargetName, Item, Val0)
- when (Item =/= user_id) ->
- case (catch verify_val(Item, Val0)) of
- {ok, Val} ->
- call({update_agent_info, UserId, TargetName, Item, Val});
- Error ->
+
+verify_agent_info(TargetName, Info0) ->
+ try
+ begin
+ verify_invalid(Info0, [user_id]),
+ %% Check if address is part of the list and
+ %% if so update it with the domain info.
+ Info =
+ case lists:keysearch(address, 1, Info0) of
+ {value, {address, Addr}} ->
+ %% If domain is part of the info, then use it.
+ %% If not, lookup what is already stored for
+ %% this agent and use that.
+ Domain =
+ case lists:keysearch(tdomain, 1, Info0) of
+ {value, {tdomain, Dom}} ->
+ Dom;
+ false ->
+ {ok, Dom} =
+ agent_info(TargetName, tdomain),
+ Dom
+ end,
+ Addr2 = {Domain, Addr},
+ lists:keyreplace(address, 1, Info0, {address, Addr2});
+ false ->
+ Info0
+ end,
+ verify_agent2(Info)
+ end
+ catch
+ throw:Error ->
Error
end.
-%% Backward compatibillity
+update_agent_info(UserId, TargetName, Info) ->
+ call({update_agent_info, UserId, TargetName, Info}).
+
+%% <BACKWARD-COMPAT-2>
+%% This is wrapped in the interface module, so this function is
+%% only here to catch code-upgrade problems.
+update_agent_info(UserId, TargetName, Item, Val) ->
+ update_agent_info(UserId, TargetName, [{Item, Val}]).
+%% </BACKWARD-COMPAT-2>
+
+%% <BACKWARD-COMPAT-1>
update_agent_info(UserId, Addr, Port, Item, Val) ->
case agent_info(Addr, Port, target_name) of
{ok, TargetName} ->
@@ -439,6 +525,7 @@ update_agent_info(UserId, Addr, Port, Item, Val) ->
Error ->
Error
end.
+%% </BACKWARD-COMPAT-1>
is_known_engine_id(EngineID, TargetName) ->
case agent_info(TargetName, engine_id) of
@@ -650,22 +737,14 @@ unregister_usm_user(EngineID, Name)
call({unregister_usm_user, EngineID, Name}).
verify_usm_user_config(EngineID, Name, Config) ->
- %% case verify_mandatory(Config, []) of
- %% ok ->
- %% case verify_invalid(Config, [engine_id, name]) of
- %% ok ->
- %% verify_usm_user_config2(EngineID, Name, Config);
- %% Error ->
- %% Error
- %% end;
- %% Error ->
- %% Error
- %% end.
- ok = verify_mandatory(Config, []),
- case verify_invalid(Config, [engine_id, name]) of
- ok ->
- verify_usm_user_config2(EngineID, Name, Config);
- Error ->
+ try
+ begin
+ verify_mandatory(Config, []),
+ verify_invalid(Config, [engine_id, name]),
+ verify_usm_user_config2(EngineID, Name, Config)
+ end
+ catch
+ throw:Error ->
Error
end.
@@ -1590,6 +1669,7 @@ check_agent_config2(Agent) ->
throw(Err)
end.
+%% For backward compatibility
check_agent_config({UserId,
TargetName,
Community,
@@ -1597,10 +1677,27 @@ check_agent_config({UserId,
EngineId,
Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel}) ->
+ TDomain = default_transport_domain(),
+ check_agent_config({UserId,
+ TargetName,
+ Community,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel});
+
+check_agent_config({UserId,
+ TargetName,
+ Community,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) ->
?vtrace("check_agent_config -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p"
"~n Community: ~p"
+ "~n TDomain: ~p"
"~n Ip: ~p"
"~n Port: ~p"
"~n EngineId: ~p"
@@ -1610,15 +1707,16 @@ check_agent_config({UserId,
"~n SecModel: ~p"
"~n SecName: ~p"
"~n SecLevel: ~p",
- [UserId, TargetName, Community, Ip, Port,
+ [UserId, TargetName, Community,
+ TDomain, Ip, Port,
EngineId, Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel]),
- Addr = normalize_address(Ip),
+ Addr = normalize_address(TDomain, Ip),
?vtrace("check_agent_config -> Addr: ~p", [Addr]),
Agent = {UserId,
TargetName,
Community,
- Addr, Port,
+ TDomain, Addr, Port,
EngineId,
Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel},
@@ -1644,6 +1742,7 @@ init_agent_config({UserId, TargetName, Config}) ->
end.
+%% For backward compatibility
verify_agent({UserId,
TargetName,
Comm,
@@ -1651,48 +1750,68 @@ verify_agent({UserId,
EngineId,
Timeout, MMS,
Version, SecModel, SecName, SecLevel}) ->
- ?vtrace("verify_agent -> entry with"
+ TDomain = default_transport_domain(),
+ verify_agent({UserId,
+ TargetName,
+ Comm,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MMS,
+ Version, SecModel, SecName, SecLevel});
+
+verify_agent({UserId,
+ TargetName,
+ Comm,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MMS,
+ Version, SecModel, SecName, SecLevel}) ->
+ ?vdebug("verify_agent -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p", [UserId, TargetName]),
snmp_conf:check_string(TargetName, {gt, 0}),
- case verify_val(address, Ip) of
- {ok, Addr} ->
- snmp_conf:check_integer(Port, {gt, 0}),
- Conf =
- [{reg_type, target_name},
- {address, Addr},
- {port, Port},
- {community, Comm},
- {engine_id, EngineId},
- {timeout, Timeout},
- {max_message_size, MMS},
- {version, Version},
- {sec_model, SecModel},
- {sec_name, SecName},
- {sec_level, SecLevel}
- ],
- case verify_agent2(Conf) of
- ok ->
- {UserId, TargetName, Conf, Version};
- Err ->
- throw(Err)
- end;
-
- Error ->
- ?vlog("verify_agent -> failed: ~n ~p", [Error]),
- throw(Error)
+ snmp_conf:check_integer(Port, {gt, 0}),
+ %% Note that the order of Conf *is* important.
+ %% Some properties may depend on others, so that
+ %% in order to verify one property, another must
+ %% be already verified (and present). An example
+ %% of this is the property 'address', for which
+ %% the property tdomain is needed.
+ Conf0 =
+ [{reg_type, target_name},
+ {tdomain, TDomain},
+ %% This should be taddress, but what the*...
+ {address, {TDomain, Ip}},
+ {port, Port},
+ {community, Comm},
+ {engine_id, EngineId},
+ {timeout, Timeout},
+ {max_message_size, MMS},
+ {version, Version},
+ {sec_model, SecModel},
+ {sec_name, SecName},
+ {sec_level, SecLevel}
+ ],
+ case verify_agent2(Conf0) of
+ {ok, Conf} ->
+ {UserId, TargetName, Conf, Version};
+ Err ->
+ throw(Err)
end.
-verify_agent2([]) ->
- ok;
-verify_agent2([{Item, Val}|Items]) ->
- case verify_val(Item, Val) of
- {ok, _Val} ->
- verify_agent2(Items);
+verify_agent2(Conf) ->
+ verify_agent2(Conf, []).
+
+verify_agent2([], VerifiedConf) ->
+ {ok, VerifiedConf};
+verify_agent2([{Item, Val0}|Items], VerifiedConf) ->
+ case verify_val(Item, Val0) of
+ {ok, Val} ->
+ verify_agent2(Items, [{Item, Val} | VerifiedConf]);
Err ->
Err
end;
-verify_agent2([Bad|_]) ->
+verify_agent2([Bad|_], _VerifiedConf) ->
{error, {bad_agent_config, Bad}}.
@@ -1708,14 +1827,28 @@ read_users_config_file(Dir) ->
check_user_config({Id, Mod, Data}) ->
+ ?vtrace("check_user_config -> entry with"
+ "~n Id: ~p"
+ "~n Mod: ~p"
+ "~n Data: ~p", [Id, Mod, Data]),
check_user_config({Id, Mod, Data, []});
-check_user_config({Id, Mod, _Data, DefaultAgentConfig} = User)
+check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User)
when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) ->
+ ?vtrace("check_user_config -> entry with"
+ "~n Id: ~p"
+ "~n Mod: ~p"
+ "~n Data: ~p"
+ "~n DefaultAgentConfig: ~p",
+ [Id, Mod, Data, DefaultAgentConfig]),
case (catch verify_user_behaviour(Mod)) of
ok ->
+ ?vtrace("check_user_config -> user behaviour verified", []),
case verify_user_agent_config(DefaultAgentConfig) of
- ok ->
- {ok, User};
+ {ok, DefAgentConf} ->
+ ?vtrace("check_user_config -> "
+ "user agent (default) config verified", []),
+ User2 = {Id, Mod, Data, DefAgentConf},
+ {ok, User2};
{error, Reason} ->
error({bad_default_agent_config, Reason})
end;
@@ -1756,16 +1889,16 @@ verify_user({Id, UserMod, UserData}) ->
verify_user({Id, UserMod, UserData, DefaultAgentConfig})
when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) ->
?d("verify_user -> entry with"
- "~n Id: ~p"
- "~n UserMod: ~p"
- "~n UserData: ~p"
+ "~n Id: ~p"
+ "~n UserMod: ~p"
+ "~n UserData: ~p"
"~n DefaultAgentConfig: ~p",
[Id, UserMod, UserData, DefaultAgentConfig]),
case (catch verify_user_behaviour(UserMod)) of
ok ->
case verify_user_agent_config(DefaultAgentConfig) of
- ok ->
- Config = default_agent_config(DefaultAgentConfig),
+ {ok, DefAgentConf} ->
+ Config = default_agent_config(DefAgentConf),
{ok, #user{id = Id,
mod = UserMod,
data = UserData,
@@ -1783,10 +1916,15 @@ verify_user({Id, _, _, _}) ->
{error, {bad_user_id, Id}}.
verify_user_agent_config(Conf) ->
- case verify_invalid(Conf, [user_id, engine_id, address]) of
- ok ->
- verify_agent_config2(Conf);
- Error ->
+ try
+ begin
+ verify_invalid(Conf, [user_id, engine_id, address]),
+ verify_agent_config2(Conf)
+ end
+ catch
+ throw:Error ->
+ ?vdebug("verify_user_agent_config -> throw"
+ "~n Error: ~p", [Error]),
Error
end.
@@ -2147,6 +2285,16 @@ handle_call({unregister_agent, UserId, TargetName}, _From, State) ->
Reply = handle_unregister_agent(UserId, TargetName),
{reply, Reply, State};
+handle_call({update_agent_info, UserId, TargetName, Info},
+ _From, State) ->
+ ?vlog("received update_agent_info request: "
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Info: ~p", [UserId, TargetName, Info]),
+ Reply = handle_update_agent_info(UserId, TargetName, Info),
+ {reply, Reply, State};
+
+%% <BACKWARD-COMPAT>
handle_call({update_agent_info, UserId, TargetName, Item, Val},
_From, State) ->
?vlog("received update_agent_info request: "
@@ -2156,6 +2304,7 @@ handle_call({update_agent_info, UserId, TargetName, Item, Val},
"~n Val: ~p", [UserId, TargetName, Item, Val]),
Reply = handle_update_agent_info(UserId, TargetName, Item, Val),
{reply, Reply, State};
+%% </BACKWARD-COMPAT>
handle_call({register_usm_user, User}, _From, State) ->
?vlog("received register_usm_user request: "
@@ -2517,16 +2666,27 @@ handle_register_agent(UserId, TargetName, Config) ->
"~n Config: ~p", [UserId, TargetName, Config]),
case (catch agent_info(TargetName, user_id)) of
{error, _} ->
+ ?vtrace("handle_register_agent -> user_id not found in config", []),
case ets:lookup(snmpm_user_table, UserId) of
[#user{default_agent_config = DefConfig}] ->
+ ?vtrace("handle_register_agent -> "
+ "~n DefConfig: ~p", [DefConfig]),
+ %% First, insert this users default config
+ ?vtrace("handle_register_agent -> store default config", []),
do_handle_register_agent(TargetName, DefConfig),
+ %% Second, insert the config for this agent
+ ?vtrace("handle_register_agent -> store config", []),
do_handle_register_agent(TargetName,
[{user_id, UserId}|Config]),
%% <DIRTY-BACKWARD-COMPATIBILLITY>
%% And now for some (backward compatibillity)
%% dirty crossref stuff
+ ?vtrace("handle_register_agent -> lookup address", []),
{ok, Addr} = agent_info(TargetName, address),
+ ?vtrace("handle_register_agent -> Addr: ~p, lookup Port",
+ [Addr]),
{ok, Port} = agent_info(TargetName, port),
+ ?vtrace("handle_register_agent -> register cross-ref fix", []),
ets:insert(snmpm_agent_table,
{{Addr, Port, target_name}, TargetName}),
%% </DIRTY-BACKWARD-COMPATIBILLITY>
@@ -2551,10 +2711,18 @@ handle_register_agent(UserId, TargetName, Config) ->
do_handle_register_agent(_TargetName, []) ->
ok;
do_handle_register_agent(TargetName, [{Item, Val}|Rest]) ->
+ ?vtrace("handle_register_agent -> entry with"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p"
+ "~n Rest: ~p", [TargetName, Item, Val, Rest]),
case (catch do_update_agent_info(TargetName, Item, Val)) of
ok ->
do_handle_register_agent(TargetName, Rest);
{error, Reason} ->
+ ?vtrace("handle_register_agent -> failed updating ~p"
+ "~n Item: ~p"
+ "~n Reason: ~p", [Item, Reason]),
ets:match_delete(snmpm_agent_table, {TargetName, '_'}),
{error, Reason}
end;
@@ -2589,41 +2757,61 @@ handle_unregister_agent(UserId, TargetName) ->
end.
-handle_update_agent_info(UserId, TargetName, Item, Val) ->
+handle_update_agent_info(UserId, TargetName, Info) ->
?vdebug("handle_update_agent_info -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n Item: ~p"
- "~n Val: ~p", [UserId, TargetName, Item, Val]),
+ "~n Info: ~p", [UserId, TargetName, Info]),
+ %% Verify ownership
case (catch agent_info(TargetName, user_id)) of
- {ok, UserId} ->
- do_update_agent_info(TargetName, Item, Val);
+ {ok, UserId} ->
+ handle_update_agent_info(TargetName, Info);
{ok, OtherUserId} ->
{error, {not_owner, OtherUserId}};
Error ->
Error
end.
-do_update_agent_info(TargetName, Item, Val0) ->
-%% p("do_update_agent_info -> entry with"
-%% "~n TargetName: ~p"
-%% "~n Item: ~p"
-%% "~n Val0: ~p", [TargetName, Item, Val0]),
- case verify_val(Item, Val0) of
- {ok, Val} ->
-%% p("do_update_agent_info -> verified value"
-%% "~n Val: ~p", [Val]),
- ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}),
- ok;
+handle_update_agent_info(TargetName, Info0) ->
+ ?vtrace("handle_update_agent_info -> entry with"
+ "~n TargetName: ~p"
+ "~n Info0: ~p", [TargetName, Info0]),
+ %% Verify info
+ try verify_agent_info(TargetName, Info0) of
+ {ok, Info} ->
+ do_update_agent_info(TargetName, Info);
Error ->
- ?vlog("do_update_agent_info -> verify value failed: "
- "~n TargetName: ~p"
- "~n Item: ~p"
- "~n Val0: ~p"
- "~n Error: ~p", [TargetName, Item, Val0, Error]),
- {error, {bad_agent_val, TargetName, Item, Val0}}
+ Error
+ catch
+ throw:Error ->
+ Error;
+ T:E ->
+ {error, {failed_info_verification, Info0, T, E}}
end.
+handle_update_agent_info(UserId, TargetName, Item, Val) ->
+ ?vdebug("handle_update_agent_info -> entry with"
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p", [UserId, TargetName, Item, Val]),
+ handle_update_agent_info(TargetName, [{Item, Val}]).
+
+do_update_agent_info(TargetName, Info) ->
+ InsertItem =
+ fun({Item, Val}) ->
+ ets:insert(snmpm_agent_table, {{TargetName, Item}, Val})
+ end,
+ lists:foreach(InsertItem, Info).
+
+do_update_agent_info(TargetName, Item, Val) ->
+ ?vtrace("do_update_agent_info -> entry with"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p", [TargetName, Item, Val]),
+ ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}),
+ ok.
+
handle_register_usm_user(#usm_user{engine_id = EngineID,
name = Name} = User) ->
@@ -2791,7 +2979,7 @@ verify_mandatory(Conf, [Mand|Mands]) ->
true ->
verify_mandatory(Conf, Mands);
false ->
- {error, {missing_mandatory_config, Mand}}
+ throw({error, {missing_mandatory_config, Mand}})
end.
verify_invalid(_, []) ->
@@ -2801,7 +2989,7 @@ verify_invalid(Conf, [Inv|Invs]) ->
false ->
verify_invalid(Conf, Invs);
true ->
- {error, {illegal_config, Inv}}
+ throw({error, {illegal_config, Inv}})
end.
@@ -2810,10 +2998,26 @@ verify_val(user_id, UserId) ->
verify_val(reg_type, RegType)
when (RegType =:= addr_port) orelse (RegType =:= target_name) ->
{ok, RegType};
-verify_val(address, Addr0) ->
- case normalize_address(Addr0) of
+verify_val(tdomain = Item, snmpUDPDomain = _Domain) ->
+ verify_val(Item, transportDomainUdpIpv4);
+verify_val(tdomain, Domain) ->
+ case lists:member(Domain, ?SUPPORTED_DOMAINS) of
+ true ->
+ {ok, Domain};
+ false ->
+ case lists:member(Domain, snmp_conf:all_domains()) of
+ true ->
+ error({unsupported_domain, Domain});
+ false ->
+ error({unknown_domain, Domain})
+ end
+ end;
+verify_val(address, {Domain, Addr0}) ->
+ case normalize_address(Domain, Addr0) of
{_A1, _A2, _A3, _A4} = Addr ->
{ok, Addr};
+ {_A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8} = Addr ->
+ {ok, Addr};
_ when is_list(Addr0) ->
case (catch snmp_conf:check_ip(Addr0)) of
ok ->
@@ -2824,6 +3028,8 @@ verify_val(address, Addr0) ->
_ ->
error({bad_address, Addr0})
end;
+verify_val(address, BadAddress) ->
+ error({bad_address, BadAddress});
verify_val(port, Port) ->
case (catch snmp_conf:check_integer(Port, {gt, 0})) of
ok ->
@@ -2875,7 +3081,7 @@ verify_val(sec_name, BadName) ->
verify_val(sec_level, Level) ->
(catch snmp_conf:check_sec_level(Level));
verify_val(Item, _) ->
- {error, {no_such_item, Item}}.
+ {error, {unknown_item, Item}}.
%%%-------------------------------------------------------------------
@@ -3034,11 +3240,17 @@ init_mini_mib_elems(MibName, [_|T], Res) ->
%%----------------------------------------------------------------------
normalize_address(Addr) ->
- case inet:getaddr(Addr, inet) of
+ normalize_address(snmpUDPDomain, Addr).
+
+normalize_address(snmpUDPDomain, Addr) ->
+ normalize_address(transportDomainUdpIpv4, Addr);
+
+normalize_address(Domain, Addr) ->
+ case inet:getaddr(Addr, td2fam(Domain)) of
{ok, Addr2} ->
Addr2;
_ when is_list(Addr) ->
- case (catch snmp_conf:check_ip(Addr)) of
+ case (catch snmp_conf:check_ip(Domain, Addr)) of
ok ->
list_to_tuple(Addr);
_ ->
@@ -3048,6 +3260,9 @@ normalize_address(Addr) ->
Addr
end.
+td2fam(transportDomainUdpIpv4) -> inet;
+td2fam(transportDomainUdpIpv6) -> inet6.
+
%%----------------------------------------------------------------------
diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl
index 7712370d28..627838e3d4 100644
--- a/lib/snmp/src/manager/snmpm_mpd.erl
+++ b/lib/snmp/src/manager/snmpm_mpd.erl
@@ -92,7 +92,7 @@ reset(#state{v3 = V3}) ->
%% Purpose: This is the main Message Dispatching function. (see
%% section 4.2.1 in rfc2272)
%%-----------------------------------------------------------------
-process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
+process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
inc(snmpInPkts),
@@ -102,18 +102,18 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
#message{version = 'version-1', vsn_hdr = Community, data = Data}
when State#state.v1 =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-1', NoteStore, Msg, TDomain,
- Addr, Port,
+ process_v1_v2c_msg('version-1', NoteStore, Msg,
+ Domain, Addr, Port,
Community, Data, HS, Logger);
%% Version 2
#message{version = 'version-2', vsn_hdr = Community, data = Data}
when State#state.v2c =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-2', NoteStore, Msg, TDomain,
- Addr, Port,
- Community, Data, HS, Logger);
-
+ (catch process_v1_v2c_msg('version-2', NoteStore, Msg,
+ Domain, Addr, Port,
+ Community, Data, HS, Logger));
+
%% Version 3
#message{version = 'version-3', vsn_hdr = H, data = Data}
when State#state.v3 =:= true ->
@@ -148,17 +148,30 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
+process_v1_v2c_msg(Vsn, _NoteStore, Msg, Domain,
Addr, Port,
Community, Data, HS, Log) ->
?vdebug("process_v1_v2c_msg -> entry with"
"~n Vsn: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
"~n Port: ~p"
"~n Community: ~p"
- "~n HS: ~p", [Vsn, Addr, Port, Community, HS]),
+ "~n HS: ~p", [Vsn, Domain, Addr, Port, Community, HS]),
+ {TDomain, TAddress} =
+ try
+ begin
+ TD = snmp_conf:mk_tdomain(Domain),
+ TA = snmp_conf:mk_taddress(Domain, Addr, Port),
+ {TD, TA}
+ end
+ catch
+ throw:{error, TReason} ->
+ throw({discarded, {badarg, Domain, TReason}})
+ end,
+
Max = get_max_message_size(),
AgentMax = get_agent_max_message_size(Addr, Port),
PduMS = pdu_ms(Max, AgentMax, HS),
@@ -170,14 +183,14 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
?vtrace("process_v1_v2c_msg -> was a pdu", []),
Log(Msg),
inc_snmp_in(Pdu),
- MsgData = {Community, sec_model(Vsn)},
+ MsgData = {Community, sec_model(Vsn), TDomain, TAddress},
{ok, Vsn, Pdu, PduMS, MsgData};
Trap when is_record(Trap, trappdu) ->
?vtrace("process_v1_v2c_msg -> was a trap", []),
Log(Msg),
inc_snmp_in(Trap),
- MsgData = {Community, sec_model(Vsn)},
+ MsgData = {Community, sec_model(Vsn), TDomain, TAddress},
{ok, Vsn, Trap, PduMS, MsgData};
{'EXIT', Reason} ->
@@ -185,11 +198,7 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
"~n Reason: ~p", [Reason]),
inc(snmpInASNParseErrs),
{discarded, Reason}
- end;
-process_v1_v2c_msg(_Vsn, _NoteStore, _Msg, TDomain,
- _Addr, _Port,
- _Comm, _HS, _Data, _Log) ->
- {discarded, {badarg, TDomain}}.
+ end.
pdu_ms(MgrMMS, AgentMMS, HS) when AgentMMS < MgrMMS ->
AgentMMS - HS;
@@ -482,8 +491,8 @@ generate_msg('version-3', NoteStore, Pdu,
generate_v3_msg(NoteStore, Pdu,
SecModel, SecName, SecLevel, CtxEngineID, CtxName,
TargetName, Log);
-generate_msg(Vsn, _NoteStore, Pdu, {Community, _SecModel}, Log) ->
- generate_v1_v2c_msg(Vsn, Pdu, Community, Log).
+generate_msg(Vsn, _NoteStore, Pdu, {Comm, _SecModel}, Log) ->
+ generate_v1_v2c_msg(Vsn, Pdu, Comm, Log).
generate_v3_msg(NoteStore, Pdu,
@@ -627,6 +636,8 @@ generate_response_msg('version-3', Pdu,
generate_v3_response_msg(Pdu, MsgID, SecModel, SecName, SecLevel,
CtxEngineID, CtxName, SecData, Log);
generate_response_msg(Vsn, Pdu, {Comm, _SecModel}, Log) ->
+ generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log);
+generate_response_msg(Vsn, Pdu, {Comm, _SecModel, _TDomain, _TAddress}, Log) ->
generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log).
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index 3d248fff57..4d6bd9aa33 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -28,7 +28,8 @@
start_link/2,
stop/1,
send_pdu/6, % Backward compatibillity
- send_pdu/7,
+ send_pdu/7, % Backward compatibillity
+ send_pdu/8,
inform_response/4,
@@ -101,16 +102,21 @@ stop(Pid) ->
send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) ->
send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)
+send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) ->
+ Domain = snmpm_config:default_transport_domain(),
+ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo).
+
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo)
when is_record(Pdu, pdu) ->
?d("send_pdu -> entry with"
"~n Pid: ~p"
"~n Pdu: ~p"
"~n Vsn: ~p"
"~n MsgData: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Addr, Port]),
- cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}).
+ "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]),
+ cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}).
note_store(Pid, NoteStore) ->
call(Pid, {note_store, NoteStore}).
@@ -380,15 +386,17 @@ handle_call(Req, From, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}, State) ->
+handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo},
+ State) ->
?vlog("received send_pdu message with"
"~n Pdu: ~p"
"~n Vsn: ~p"
"~n MsgData: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Pdu, Vsn, MsgData, Addr, Port]),
+ "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]),
maybe_process_extra_info(ExtraInfo),
- maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State),
+ maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State),
{noreply, State};
handle_cast({inform_response, Ref, Addr, Port}, State) ->
@@ -545,8 +553,9 @@ handle_recv_msg(Addr, Port, Bytes,
mpd_state = MpdState,
sock = Sock,
log = Log} = State) ->
+ Domain = snmp_conf:which_domain(Addr), % What the ****...
Logger = logger(Log, read, Addr, Port),
- case (catch snmpm_mpd:process_msg(Bytes, snmpUDPDomain, Addr, Port,
+ case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port,
MpdState, NoteStore, Logger)) of
{ok, Vsn, Pdu, MS, ACM} ->
@@ -734,17 +743,17 @@ irgc_stop(Ref) ->
(catch erlang:cancel_timer(Ref)).
-maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port,
+maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port,
#state{filter = FilterMod} = State) ->
case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
- handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State)
+ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State)
end.
-handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port,
+handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
#state{server = Pid,
note_store = NoteStore,
sock = Sock,
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index b8d7cf6375..484954addb 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -161,7 +161,8 @@
{id,
user_id,
reg_type,
- target,
+ target,
+ domain,
addr,
port,
type,
@@ -1175,11 +1176,12 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_GET_TIMEOUT(SendOpts),
@@ -1190,6 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get,
@@ -1227,11 +1230,12 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_GET_NEXT_TIMEOUT(SendOpts),
@@ -1242,6 +1246,7 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_next,
@@ -1285,10 +1290,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
NonRep, MaxRep, Extra, State),
?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1300,6 +1306,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_bulk,
@@ -1339,11 +1346,12 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, VarsAndVals, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_SET_TIMEOUT(SendOpts),
@@ -1354,6 +1362,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = set,
@@ -1391,10 +1400,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
Extra, State),
?vdebug("handle_async_get -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_TIMEOUT(SendOpts),
@@ -1402,6 +1412,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get,
@@ -1439,17 +1450,19 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts),
Req = #request{id = ReqId,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_next,
@@ -1494,10 +1507,11 @@ handle_async_get_bulk(Pid,
"~n SendOpts: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
NonRep, MaxRep, Extra, State),
?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts),
@@ -1505,6 +1519,7 @@ handle_async_get_bulk(Pid,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_bulk,
@@ -1541,17 +1556,19 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, VarsAndVals, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_async_set -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_SET_TIMEOUT(SendOpts),
Req = #request{id = ReqId,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = set,
@@ -2907,7 +2924,7 @@ do_gc(Key, Now) ->
%%
%%----------------------------------------------------------------------
-send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_get_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{net_if = NetIf,
net_if_mod = Mod,
mini_mib = MiniMIB}) ->
@@ -2918,34 +2935,39 @@ send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
"~n Pdu: ~p"
"~n Vsn: ~p"
"~n MsgData: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Mod, NetIf, Pdu, Vsn, MsgData, Addr, Port]),
- (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)),
+ "~n Port: ~p",
+ [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port]),
+ Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData,
+ Domain, Addr, Port, ExtraInfo)),
+ ?vtrace("send_get_request -> send result:"
+ "~n ~p", [Res]),
Pdu#pdu.request_id.
-send_get_next_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(get_next, Oids, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
-send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, Port,
NonRep, MaxRep, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
-send_set_request(VarsAndVals, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(set, VarsAndVals, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
%% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo,
@@ -3181,10 +3203,11 @@ agent_data(TargetName, SendOpts) ->
{Comm, SecModel}
end,
+ Domain = agent_data_item(tdomain, Info),
Addr = agent_data_item(address, Info),
Port = agent_data_item(port, Info),
RegType = agent_data_item(reg_type, Info),
- {ok, RegType, Addr, Port, version(Version), MsgData};
+ {ok, RegType, Domain, Addr, Port, version(Version), MsgData};
Error ->
Error
end.
diff --git a/lib/snmp/src/manager/snmpm_usm.erl b/lib/snmp/src/manager/snmpm_usm.erl
index ef2070a90e..497d6d6102 100644
--- a/lib/snmp/src/manager/snmpm_usm.erl
+++ b/lib/snmp/src/manager/snmpm_usm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index cb5b3bbfbd..7249def24e 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -37,7 +37,9 @@
check_timer/1,
+ all_domains/0,
check_domain/1,
+ all_tdomains/0,
check_tdomain/1,
mk_tdomain/1,
which_domain/1,
@@ -345,6 +347,25 @@ check_sec_level(BadSecLevel) ->
%% ---------
+all_tdomains() ->
+ [
+ ?transportDomainUdpIpv4,
+ ?transportDomainUdpIpv6,
+ ?transportDomainUdpIpv4z,
+ ?transportDomainUdpIpv6z,
+ ?transportDomainTcpIpv4,
+ ?transportDomainTcpIpv6,
+ ?transportDomainTcpIpv4z,
+ ?transportDomainTcpIpv6z,
+ ?transportDomainSctpIpv4,
+ ?transportDomainSctpIpv6,
+ ?transportDomainSctpIpv4z,
+ ?transportDomainSctpIpv6z,
+ ?transportDomainLocal,
+ ?transportDomainUdpDns,
+ ?transportDomainTcpDns,
+ ?transportDomainSctpDns
+ ].
check_tdomain(TDomain) ->
SupportedTDomains =
@@ -353,25 +374,7 @@ check_tdomain(TDomain) ->
?transportDomainUdpIpv4,
?transportDomainUdpIpv6
],
- AllTDomains =
- [
- ?transportDomainUdpIpv4,
- ?transportDomainUdpIpv6,
- ?transportDomainUdpIpv4z,
- ?transportDomainUdpIpv6z,
- ?transportDomainTcpIpv4,
- ?transportDomainTcpIpv6,
- ?transportDomainTcpIpv4z,
- ?transportDomainTcpIpv6z,
- ?transportDomainSctpIpv4,
- ?transportDomainSctpIpv6,
- ?transportDomainSctpIpv4z,
- ?transportDomainSctpIpv6z,
- ?transportDomainLocal,
- ?transportDomainUdpDns,
- ?transportDomainTcpDns,
- ?transportDomainSctpDns
- ],
+ AllTDomains = all_tdomains(),
case lists:member(TDomain, SupportedTDomains) of
true ->
ok;
@@ -388,7 +391,7 @@ check_tdomain(TDomain) ->
%% ---------
mk_tdomain(snmpUDPDomain) ->
- ?snmpUDPDomain;
+ mk_tdomain(transportDomainUdpIpv4);
mk_tdomain(transportDomainUdpIpv4) ->
?transportDomainUdpIpv4;
mk_tdomain(transportDomainUdpIpv6) ->
@@ -474,6 +477,26 @@ do_check_timer(WaitFor, Factor, Incr, Retry) ->
%% ---------
+all_domains() ->
+ [
+ transportDomainUdpIpv4,
+ transportDomainUdpIpv6,
+ transportDomainUdpIpv4z,
+ transportDomainUdpIpv6z,
+ transportDomainTcpIpv4,
+ transportDomainTcpIpv6,
+ transportDomainTcpIpv4z,
+ transportDomainTcpIpv6z,
+ transportDomainSctpIpv4,
+ transportDomainSctpIpv6,
+ transportDomainSctpIpv4z,
+ transportDomainSctpIpv6z,
+ transportDomainLocal,
+ transportDomainUdpDns,
+ transportDomainTcpDns,
+ transportDomainSctpDns
+ ].
+
check_domain(Domain) ->
SupportedDomains =
[
@@ -481,25 +504,7 @@ check_domain(Domain) ->
transportDomainUdpIpv4,
transportDomainUdpIpv6
],
- AllDomains =
- [
- transportDomainUdpIpv4,
- transportDomainUdpIpv6,
- transportDomainUdpIpv4z,
- transportDomainUdpIpv6z,
- transportDomainTcpIpv4,
- transportDomainTcpIpv6,
- transportDomainTcpIpv4z,
- transportDomainTcpIpv6z,
- transportDomainSctpIpv4,
- transportDomainSctpIpv6,
- transportDomainSctpIpv4z,
- transportDomainSctpIpv6z,
- transportDomainLocal,
- transportDomainUdpDns,
- transportDomainTcpDns,
- transportDomainSctpDns
- ],
+ AllDomains = all_domains(),
case lists:member(Domain, SupportedDomains) of
true ->
ok;
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index 813942225e..6ab20e3e48 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -337,7 +337,7 @@ config_agent_sys() ->
{dir, ATLDir},
{size, ATLSize},
{repair, ATLRepair},
- {seqno, ATLSeqNo}]}];
+ {seqno, ATLSeqNo}]}];
no ->
[]
end,
@@ -568,7 +568,7 @@ config_agent_snmp(Dir, Vsns) ->
false ->
ok
end,
- i("The following agent files were written: agent.conf, "
+ i("The following agent files where written: agent.conf, "
"community.conf,~n"
"standard.conf, target_addr.conf, "
"target_params.conf, ~n"
@@ -776,7 +776,7 @@ config_manager_snmp(Dir, Vsns) ->
Users, Agents, Usms)) of
ok ->
i("~n- - - - - - - - - - - - -"),
- i("The following manager files were written: "
+ i("The following manager files where written: "
"manager.conf, agents.conf " ++
case lists:member(v3, Vsns) of
true ->
@@ -2350,7 +2350,9 @@ write_sys_config_file_manager_atl_opt(Fid, {type, Type}) ->
write_sys_config_file_manager_atl_opt(Fid, {size, Size}) ->
ok = io:format(Fid, "{size, ~w}", [Size]);
write_sys_config_file_manager_atl_opt(Fid, {repair, Rep}) ->
- ok = io:format(Fid, "{repair, ~w}", [Rep]).
+ ok = io:format(Fid, "{repair, ~w}", [Rep]);
+write_sys_config_file_manager_atl_opt(Fid, {seqno, SeqNo}) ->
+ ok = io:format(Fid, "{seqno, ~w}", [SeqNo]).
header() ->
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index 7930e37c66..2c781810ef 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/misc/snmp_misc.erl b/lib/snmp/src/misc/snmp_misc.erl
index 6adef06ab9..a061dcd97c 100644
--- a/lib/snmp/src/misc/snmp_misc.erl
+++ b/lib/snmp/src/misc/snmp_misc.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl
index 82618a0b86..0788d86b2d 100644
--- a/lib/snmp/src/misc/snmp_pdus.erl
+++ b/lib/snmp/src/misc/snmp_pdus.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile
index 0e9c73081d..5530805bc1 100644
--- a/lib/snmp/test/Makefile
+++ b/lib/snmp/test/Makefile
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index acf62f5646..468280db02 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl
index 3ae2409997..a18d9f3201 100644
--- a/lib/snmp/test/snmp_agent_test_lib.erl
+++ b/lib/snmp/test/snmp_agent_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index 2e6020ae7a..cee11ba97a 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -47,6 +47,7 @@
module_identity/1,
agent_capabilities/1,
module_compliance/1,
+ warnings_as_errors/1,
otp_6150/1,
otp_8574/1,
@@ -97,9 +98,10 @@ all() ->
description,
oid_conflicts,
imports,
- module_identity,
- agent_capabilities,
- module_compliance,
+ module_identity,
+ agent_capabilities,
+ module_compliance,
+ warnings_as_errors,
{group, tickets}
].
@@ -152,6 +154,8 @@ description(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
oid_conflicts(suite) -> [];
oid_conflicts(Config) when is_list(Config) ->
put(tname,oid_conflicts),
@@ -165,18 +169,24 @@ oid_conflicts(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
imports(suite) ->
[];
imports(Config) when is_list(Config) ->
?SKIP(not_yet_implemented).
+%%======================================================================
+
module_identity(suite) ->
[];
module_identity(Config) when is_list(Config) ->
?SKIP(not_yet_implemented).
+%%======================================================================
+
agent_capabilities(suite) ->
[];
agent_capabilities(Config) when is_list(Config) ->
@@ -218,6 +228,8 @@ agent_capabilities(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
module_compliance(suite) ->
[];
module_compliance(Config) when is_list(Config) ->
@@ -259,6 +271,31 @@ module_compliance(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
+warnings_as_errors(suite) ->
+ ["OTP-9437"];
+warnings_as_errors(Config) when is_list(Config) ->
+ put(tname,warnings_as_errors),
+ p("starting with Config: ~p~n", [Config]),
+ Dir = ?config(comp_dir, Config),
+ MibDir = ?config(mib_dir, Config),
+ MibFile = join(MibDir, "OTP8574-MIB.mib"),
+ OutFile = join(Dir, "OTP8574-MIB.bin"),
+ Opts = [{group_check, false},
+ {outdir, Dir},
+ {verbosity, trace},
+ relaxed_row_name_assign_check],
+ {error, compilation_failed} =
+ snmpc:compile(MibFile, [warnings_as_errors|Opts]),
+ false = filelib:is_regular(OutFile),
+ {ok, _} = snmpc:compile(MibFile, Opts),
+ true = filelib:is_regular(OutFile),
+ ok.
+
+
+%%======================================================================
+
otp_6150(suite) ->
[];
otp_6150(Config) when is_list(Config) ->
@@ -273,6 +310,8 @@ otp_6150(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
otp_8574(suite) ->
[];
otp_8574(Config) when is_list(Config) ->
@@ -304,6 +343,8 @@ otp_8574(Config) when is_list(Config) ->
end.
+%%======================================================================
+
otp_8595(suite) ->
[];
otp_8595(Config) when is_list(Config) ->
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index 6bd62df655..d18f20d359 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -61,6 +61,7 @@
register_agent1/1,
register_agent2/1,
+ register_agent3/1,
info/1,
@@ -383,12 +384,12 @@ end_per_testcase2(Case, Config) ->
all() ->
[
{group, start_and_stop_tests},
- {group, misc_tests},
+ {group, misc_tests},
{group, user_tests},
- {group, agent_tests},
+ {group, agent_tests},
{group, request_tests},
{group, event_tests},
- discovery,
+ discovery,
{group, tickets}
].
@@ -417,7 +418,8 @@ groups() ->
{agent_tests, [],
[
register_agent1,
- register_agent2
+ register_agent2,
+ register_agent3
]
},
{request_tests, [],
@@ -477,14 +479,14 @@ groups() ->
},
{event_tests, [],
[
- trap1,
- trap2,
- inform1,
- inform2,
- inform3,
- inform4,
- inform_swarm,
- report
+ trap1%% ,
+ %% trap2,
+ %% inform1,
+ %% inform2,
+ %% inform3,
+ %% inform4,
+ %% inform_swarm,
+ %% report
]
},
{tickets, [],
@@ -1134,6 +1136,7 @@ register_agent1(suite) ->
register_agent1(Config) when is_list(Config) ->
process_flag(trap_exit, true),
put(tname,ra1),
+
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1164,7 +1167,7 @@ register_agent1(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) calvin & hobbe"),
+ p("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
@@ -1293,7 +1296,7 @@ register_agent2(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) calvin & hobbe"),
+ p("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
@@ -1348,7 +1351,7 @@ register_agent2(Config) when is_list(Config) ->
end,
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
-
+
p("unregister user user_alfa"),
?line ok = mgr_unregister_user(ManagerNode, user_alfa),
@@ -1377,7 +1380,157 @@ register_agent2(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user hobbe"),
+ p("unregister user user_beta"),
+ ?line ok = mgr_unregister_user(ManagerNode, user_beta),
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ ?SLEEP(1000),
+
+ p("stop snmp application (with only manager)"),
+ ?line ok = stop_snmp(ManagerNode),
+
+ ?SLEEP(1000),
+
+ stop_node(ManagerNode),
+
+ ?SLEEP(1000),
+
+ p("end"),
+ ok.
+
+
+%%======================================================================
+
+register_agent3(doc) ->
+ ["Test registration of agents with the NEW interface functions "
+ "and specifying transport domain"];
+register_agent3(suite) ->
+ [];
+register_agent3(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ put(tname, ra3),
+ p("starting with Config: ~p~n", [Config]),
+
+ ManagerNode = start_manager_node(),
+
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
+ LocalHost = snmp_test_lib:localhost(),
+
+
+ write_manager_conf(ConfDir),
+
+ Opts = [{server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {note_store, [{verbosity, trace}]},
+ {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
+
+
+ p("load snmp application"),
+ ?line ok = load_snmp(ManagerNode),
+
+ p("set manager env for the snmp application"),
+ ?line ok = set_mgr_env(ManagerNode, Opts),
+
+ p("starting snmp application (with only manager)"),
+ ?line ok = start_snmp(ManagerNode),
+
+ p("started"),
+
+ ?SLEEP(1000),
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("register user(s) user_alfa & user_beta"),
+ ?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
+ ?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("register agent(s)"),
+ TargetName1 = "agent2",
+ ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName1,
+ [{tdomain, transportDomainUdpIpv4},
+ {address, LocalHost},
+ {port, 5001},
+ {engine_id, "agentEngineId-1"}]),
+ TargetName2 = "agent3",
+ ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName2,
+ [{tdomain, transportDomainUdpIpv6},
+ {address, LocalHost},
+ {port, 5002},
+ {engine_id, "agentEngineId-2"}]),
+ TargetName3 = "agent4",
+ ?line {error, {unsupported_domain, _} = Reason4} =
+ mgr_register_agent(ManagerNode, user_beta, TargetName3,
+ [{tdomain, transportDomainTcpIpv4},
+ {address, LocalHost},
+ {port, 5003},
+ {engine_id, "agentEngineId-3"}]),
+ p("Expected registration failure: ~p", [Reason4]),
+ TargetName4 = "agent5",
+ ?line {error, {unknown_domain, _} = Reason5} =
+ mgr_register_agent(ManagerNode, user_beta, TargetName4,
+ [{tdomain, transportDomainUdpIpv4_bad},
+ {address, LocalHost},
+ {port, 5004},
+ {engine_id, "agentEngineId-4"}]),
+ p("Expected registration failure: ~p", [Reason5]),
+
+ p("verify all agent(s): expect 2"),
+ case mgr_which_agents(ManagerNode) of
+ Agents1 when length(Agents1) =:= 2 ->
+ p("all agents: ~p~n", [Agents1]),
+ ok;
+ Agents1 ->
+ ?FAIL({agent_registration_failure, Agents1})
+ end,
+
+ p("verify user_alfa agent(s)"),
+ case mgr_which_agents(ManagerNode, user_alfa) of
+ Agents2 when length(Agents2) =:= 2 ->
+ p("calvin agents: ~p~n", [Agents2]),
+ ok;
+ Agents2 ->
+ ?FAIL({agent_registration_failure, Agents2})
+ end,
+
+ p("verify user_beta agent(s)"),
+ case mgr_which_agents(ManagerNode, user_beta) of
+ Agents3 when length(Agents3) =:= 0 ->
+ p("hobbe agents: ~p~n", [Agents3]),
+ ok;
+ Agents3 ->
+ ?FAIL({agent_registration_failure, Agents3})
+ end,
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("unregister user user_alfa"),
+ ?line ok = mgr_unregister_user(ManagerNode, user_alfa),
+
+ p("verify all agent(s): expect 0"),
+ case mgr_which_agents(ManagerNode) of
+ Agents4 when length(Agents4) =:= 0 ->
+ p("all agents: ~p~n", [Agents4]),
+ ok;
+ Agents4 ->
+ ?FAIL({agent_unregistration_failure, Agents4})
+ end,
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("verify all agent(s): expect 0"),
+ case mgr_which_agents(ManagerNode) of
+ [] ->
+ ok;
+ Agents5 ->
+ p("all agents: ~p~n", [Agents5]),
+ ?FAIL({agent_unregistration_failure, Agents5})
+ end,
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("unregister user user_beta"),
?line ok = mgr_unregister_user(ManagerNode, user_beta),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
diff --git a/lib/snmp/test/snmp_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl
index 30b5dd1fc7..1b62b04960 100644
--- a/lib/snmp/test/snmp_manager_user.erl
+++ b/lib/snmp/test/snmp_manager_user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/snmp_pdus_test.erl b/lib/snmp/test/snmp_pdus_test.erl
index 197797c816..07b6d6b657 100644
--- a/lib/snmp/test/snmp_pdus_test.erl
+++ b/lib/snmp/test/snmp_pdus_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/snmp/test/test_config/Makefile b/lib/snmp/test/test_config/Makefile
index d7bebbc431..d65bb8abe2 100644
--- a/lib/snmp/test/test_config/Makefile
+++ b/lib/snmp/test/test_config/Makefile
@@ -155,23 +155,23 @@ release_spec:
release_tests_spec: clean opt
$(INSTALL_DIR) $(RELSYSDIR)
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
$(INSTALL_DIR) $(RELSYSDIR)/agent
- chmod -f -R u+w $(RELSYSDIR)/agent
+ chmod -R u+w $(RELSYSDIR)/agent
$(INSTALL_DIR) $(RELSYSDIR)/agent/conf
- chmod -f -R u+w $(RELSYSDIR)/agent/conf
+ chmod -R u+w $(RELSYSDIR)/agent/conf
$(INSTALL_DIR) $(RELSYSDIR)/agent/db
- chmod -f -R u+w $(RELSYSDIR)/agent/db
+ chmod -R u+w $(RELSYSDIR)/agent/db
$(INSTALL_DIR) $(RELSYSDIR)/agent/log
- chmod -f -R u+w $(RELSYSDIR)/agent/log
+ chmod -R u+w $(RELSYSDIR)/agent/log
$(INSTALL_DIR) $(RELSYSDIR)/manager
- chmod -f -R u+w $(RELSYSDIR)/manager
+ chmod -R u+w $(RELSYSDIR)/manager
$(INSTALL_DIR) $(RELSYSDIR)/manager/conf
- chmod -f -R u+w $(RELSYSDIR)/manager/conf
+ chmod -R u+w $(RELSYSDIR)/manager/conf
$(INSTALL_DIR) $(RELSYSDIR)/manager/db
- chmod -f -R u+w $(RELSYSDIR)/manager/db
+ chmod -R u+w $(RELSYSDIR)/manager/db
$(INSTALL_DIR) $(RELSYSDIR)/manager/log
- chmod -f -R u+w $(RELSYSDIR)/manager/log
+ chmod -R u+w $(RELSYSDIR)/manager/log
$(INSTALL_DATA) $(SYS_CONFIG_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(AGENT_CONFIG_FILES) $(RELSYSDIR)/agent/conf
$(INSTALL_DATA) $(MANAGER_CONFIG_FILES) $(RELSYSDIR)/manager/conf
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 29228fc59b..08251ab9ea 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -17,6 +17,6 @@
#
# %CopyrightEnd%
-SNMP_VSN = 4.20
+SNMP_VSN = 4.21
PRE_VSN =
APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 71f3941577..6fc4fdc43d 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,20 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 2.0.8</title>
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Calling ssh_sftp:stop_channel/1 resulted in that the trap_exit flag was
+ set to true for the invoking process.</p>
+ <p>
+ Own Id: OTP-9386 Aux Id: seq11865</p>
+ </item>
+ </list>
+ </section>
+</section>
+
<section><title>Ssh 2.0.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 974145836c..150b7d86dd 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,13 +19,19 @@
{"%VSN%",
[
- {"2.0.6", [{load_module, ssh_userreg, soft_purge, soft_purge, []}]},
+ {"2.0.7", [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
+ {"2.0.6", [{load_module, ssh_userreg, soft_purge, soft_purge, []},
+ {load_module, ssh_sftp, soft_purge, soft_purge, []}]},
{"2.0.5", [{load_module, ssh_userreg, soft_purge, soft_purge, []},
+ {load_module, ssh_sftp, soft_purge, soft_purge, []},
{load_module, ssh_connection_handler, soft_purge, soft_purge, [ssh_userreg]}]}
],
[
- {"2.0.6", [{load_module, ssh_userreg, soft_purge, soft_purge, []}]},
+ {"2.0.7", [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
+ {"2.0.6", [{load_module, ssh_userreg, soft_purge, soft_purge, []},
+ {load_module, ssh_sftp, soft_purge, soft_purge, []}]},
{"2.0.5", [{load_module, ssh_userreg, soft_purge, soft_purge, []},
+ {load_module, ssh_sftp, soft_purge, soft_purge, []},
{load_module, ssh_connection_handler, soft_purge, soft_purge, [ssh_userreg]}]}
]
}.
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index 59e09fdd0f..f000558100 100755
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -130,9 +130,9 @@ start_channel(Host, Port, Opts) ->
end.
stop_channel(Pid) ->
- case process_info(Pid, [trap_exit]) of
- [{trap_exit, Bool}] ->
- process_flag(trap_exit, true),
+ case is_process_alive(Pid) of
+ true ->
+ OldValue = process_flag(trap_exit, true),
link(Pid),
exit(Pid, ssh_sftp_stop_channel),
receive
@@ -145,9 +145,9 @@ stop_channel(Pid) ->
ok
end
end,
- process_flag(trap_exit, Bool),
+ process_flag(trap_exit, OldValue),
ok;
- undefined ->
+ false ->
ok
end.
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 5a2a6de24a..1820924ed6 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -115,7 +115,7 @@ release_tests_spec: opt
$(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) ssh.spec ssh.cover $(RELSYSDIR)
$(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) $(RELSYSDIR)
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
release_docs_spec:
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index d79038df29..fe2b915d17 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 2.0.7
+SSH_VSN = 2.0.8
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/c_src/Makefile.in b/lib/ssl/c_src/Makefile.in
index da716f7c40..6e413e7e8e 100644
--- a/lib/ssl/c_src/Makefile.in
+++ b/lib/ssl/c_src/Makefile.in
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+# Copyright Ericsson AB 1999-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/ssl/c_src/esock_openssl.c b/lib/ssl/c_src/esock_openssl.c
index 2621c9934e..0bc42958f0 100644
--- a/lib/ssl/c_src/esock_openssl.c
+++ b/lib/ssl/c_src/esock_openssl.c
@@ -1024,7 +1024,7 @@ static void info_callback(const SSL *ssl, int where, int ret)
}
}
-/* This function is called whenever a SSL_CTX *ctx structure is
+/* This function is called whenever an SSL_CTX *ctx structure is
* freed.
*/
static void callback_data_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index b2d17925fd..e090b4e1ef 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -554,7 +554,7 @@
Own Id: OTP-8224</p>
</item>
<item>
- <p>A ssl:ssl_accept/3 could crash a connection if the
+ <p>An ssl:ssl_accept/3 could crash a connection if the
timing was wrong.</p> <p>Removed info message if the
socket closed without a proper disconnect from the ssl
layer. </p> <p>ssl:send/2 is now blocking until the
@@ -770,7 +770,7 @@
<item>
<p>
The new ssl implementation released as a alfa in this
- version supports upgrading of a tcp connection to a ssl
+ version supports upgrading of a tcp connection to an ssl
connection so that http client and servers may implement
RFC 2817.</p>
<p>
@@ -789,7 +789,7 @@
very crippled as the control of the ssl-socket was deep
down in openssl making it hard if not impossible to
support all inet options, ipv6 and upgrade of a tcp
- connection to a ssl connection. The alfa version has a
+ connection to an ssl connection. The alfa version has a
few limitations that will be removed before the ssl-4.0
release. Main differences and limitations in the alfa are
listed below.</p>
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 0da6bbee5b..0c4c8796be 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -35,7 +35,7 @@
<title>SSL</title>
<list type="bulleted">
- <item>ssl requires the crypto an public_key applications.</item>
+ <item>ssl requires the crypto and public_key applications.</item>
<item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item>
<item>For security reasons sslv2 is not supported.</item>
<item>Ephemeral Diffie-Hellman cipher suites are supported
@@ -216,7 +216,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
application is encountered. Additionally it will be called
when a certificate is considered valid by the path validation
to allow access to each certificate in the path to the user
- application. Note that the it will differentiate between the
+ 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
@@ -326,10 +326,10 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
</item>
<tag>{fail_if_no_peer_cert, boolean()}</tag>
- <item>Used together with {verify, verify_peer} by a ssl server.
+ <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 a invalid
+ false it will only fail if the client sends an invalid
certificate (an empty certificate is considered valid).
</item>
@@ -343,10 +343,10 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
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 meaning full if <c>reuse_sessions</c> is set to true.
+ 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 of type ciphersuite().
+ and CipherSuite is of type ciphersuite().
</item>
</taglist>
@@ -355,7 +355,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<section>
<title>General</title>
- <p>When a 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>
@@ -396,7 +396,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<name>connect(Socket, SslOptions, Timeout) -> {ok, SslSocket}
| {error, Reason}</name>
<fsummary> Upgrades a gen_tcp, or
- equivalent, connected socket to a ssl socket. </fsummary>
+ equivalent, connected socket to an ssl socket. </fsummary>
<type>
<v>Socket = socket()</v>
<v>SslOptions = [ssloption()]</v>
@@ -405,7 +405,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<v>Reason = term()</v>
</type>
<desc> <p>Upgrades a gen_tcp, or equivalent,
- connected socket to a ssl socket i.e. performs the
+ connected socket to an ssl socket i.e. performs the
client-side ssl handshake.</p>
</desc>
</func>
@@ -428,12 +428,12 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<func>
<name>close(SslSocket) -> ok | {error, Reason}</name>
- <fsummary>Close a ssl connection</fsummary>
+ <fsummary>Close an ssl connection</fsummary>
<type>
<v>SslSocket = sslsocket()</v>
<v>Reason = term()</v>
</type>
- <desc><p>Close a ssl connection.</p>
+ <desc><p>Close an ssl connection.</p>
</desc>
</func>
@@ -450,7 +450,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<v>Reason = term()</v>
</type>
<desc><p>Assigns a new controlling process to the ssl-socket. A
- controlling process is the owner of a ssl-socket, and receives
+ controlling process is the owner of an ssl-socket, and receives
all messages from the socket.</p>
</desc>
</func>
@@ -480,7 +480,6 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
</func>
<func>
- <name>getopts(Socket) -> </name>
<name>getopts(Socket, OptionNames) ->
{ok, [socketoption()]} | {error, Reason}</name>
<fsummary>Get the value of the specified options.</fsummary>
@@ -489,8 +488,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<v>OptionNames = [atom()]</v>
</type>
<desc>
- <p>Get the value of the specified socket options, if no
- options are specified all options are returned.
+ <p>Get the value of the specified socket options.
</p>
</desc>
</func>
@@ -498,14 +496,14 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
<func>
<name>listen(Port, Options) ->
{ok, ListenSocket} | {error, Reason}</name>
- <fsummary>Creates a 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 a ssl listen socket.</p>
+ <p>Creates an ssl listen socket.</p>
</desc>
</func>
@@ -589,6 +587,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
the socket is closed.</p>
</desc>
</func>
+
<func>
<name>setopts(Socket, Options) -> ok | {error, Reason}</name>
<fsummary>Set socket options.</fsummary>
@@ -648,7 +647,7 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} |
</type>
<desc>
<p> Upgrades a gen_tcp, or
- equivalent, socket to a ssl socket i.e. performs the
+ equivalent, socket to an ssl socket i.e. performs the
ssl server-side handshake.</p>
<p><warning>Note that the listen socket should be in {active, false} mode
before telling the client that the server is ready to upgrade
diff --git a/lib/ssl/doc/src/ssl_protocol.xml b/lib/ssl/doc/src/ssl_protocol.xml
index 6936408881..ca5cc8bc7a 100644
--- a/lib/ssl/doc/src/ssl_protocol.xml
+++ b/lib/ssl/doc/src/ssl_protocol.xml
@@ -31,11 +31,11 @@
</p>
<p>By default erlang ssl is run over the TCP/IP protocol even
- though you could plug in an other reliable transport protocol
+ though you could plug in any other reliable transport protocol
with the same API as gen_tcp.</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 a ssl
+ 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
implementing virtual hosting.
diff --git a/lib/ssl/doc/src/using_ssl.xml b/lib/ssl/doc/src/using_ssl.xml
index 605290b6f9..ab837a156a 100644
--- a/lib/ssl/doc/src/using_ssl.xml
+++ b/lib/ssl/doc/src/using_ssl.xml
@@ -56,7 +56,7 @@
<code type="erl">1 server> ssl:start().
ok</code>
- <p>Create a ssl listen socket</p>
+ <p>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>
@@ -90,7 +90,7 @@ ok</code>
<section>
<title>Upgrade example</title>
- <note><p> To upgrade a TCP/IP connection to a ssl connection the
+ <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>
@@ -114,7 +114,7 @@ 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 a ssl connection, otherwhise
+ to upgrade a connection to an ssl connection, otherwhise
ssl handshake messages may be deliverd to the wrong process.</p>
<code type="erl">4 server> inet:setopts(Socket, [{active, false}]).
ok</code>
@@ -124,7 +124,7 @@ ok</code>
{certfile, "cert.pem"}, {keyfile, "key.pem"}]).
{ok,{sslsocket,[...]}}</code>
- <p> Upgrade to a ssl connection. Note that the client and server
+ <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>
<code type="erl">3 client>{ok, SSLSocket} = ssl:connect(Socket, [{cacertfile, "cacerts.pem"},
diff --git a/lib/ssl/examples/src/Makefile b/lib/ssl/examples/src/Makefile
index ae5881d49b..c5f31b689c 100644
--- a/lib/ssl/examples/src/Makefile
+++ b/lib/ssl/examples/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+# Copyright Ericsson AB 2003-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index cf8867245b..29674f30da 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -1,6 +1,7 @@
%% -*- erlang -*-
{"%VSN%",
[
+ {"4.1.5", [{restart_application, ssl}]},
{"4.1.4", [{restart_application, ssl}]},
{"4.1.3", [{restart_application, ssl}]},
{"4.1.2", [{restart_application, ssl}]},
@@ -9,6 +10,7 @@
{"4.0.1", [{restart_application, ssl}]}
],
[
+ {"4.1.5", [{restart_application, ssl}]},
{"4.1.4", [{restart_application, ssl}]},
{"4.1.3", [{restart_application, ssl}]},
{"4.1.2", [{restart_application, ssl}]},
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 0ced6707eb..46e4b98c98 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -104,7 +104,7 @@ stop() ->
{ok, #sslsocket{}} | {error, reason()}.
%%
-%% Description: Connect to a ssl server.
+%% Description: Connect to an ssl server.
%%--------------------------------------------------------------------
connect(Socket, SslOptions) when is_port(Socket) ->
connect(Socket, SslOptions, infinity).
@@ -112,7 +112,7 @@ connect(Socket, SslOptions) when is_port(Socket) ->
connect(Socket, SslOptions0, Timeout) when is_port(Socket) ->
EmulatedOptions = emulated_options(),
{ok, InetValues} = inet:getopts(Socket, EmulatedOptions),
- inet:setopts(Socket, internal_inet_values()),
+ ok = inet:setopts(Socket, internal_inet_values()),
try handle_options(SslOptions0 ++ InetValues, client) of
{ok, #config{cb=CbInfo, ssl=SslOptions, emulated=EmOpts}} ->
case inet:peername(Socket) of
@@ -151,7 +151,7 @@ connect(Host, Port, Options0, Timeout) ->
-spec listen(port_num(), [option()]) ->{ok, #sslsocket{}} | {error, reason()}.
%%
-%% Description: Creates a ssl listen socket.
+%% Description: Creates an ssl listen socket.
%%--------------------------------------------------------------------
listen(_Port, []) ->
{error, enooptions};
@@ -177,7 +177,7 @@ listen(Port, Options0) ->
-spec transport_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}} |
{error, reason()}.
%%
-%% Description: Performs transport accept on a ssl listen socket
+%% Description: Performs transport accept on an ssl listen socket
%%--------------------------------------------------------------------
transport_accept(ListenSocket) ->
transport_accept(ListenSocket, infinity).
@@ -218,7 +218,7 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) ->
ok | {ok, #sslsocket{}} | {error, reason()}.
-spec ssl_accept(port(), [option()], timeout()) -> {ok, #sslsocket{}} | {error, reason()}.
%%
-%% Description: Performs accept on a ssl listen socket. e.i. performs
+%% Description: Performs accept on an ssl listen socket. e.i. performs
%% ssl handshake.
%%--------------------------------------------------------------------
ssl_accept(ListenSocket) ->
@@ -238,7 +238,7 @@ ssl_accept(#sslsocket{} = Socket, Timeout) ->
ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) ->
EmulatedOptions = emulated_options(),
{ok, InetValues} = inet:getopts(Socket, EmulatedOptions),
- inet:setopts(Socket, internal_inet_values()),
+ ok = inet:setopts(Socket, internal_inet_values()),
try handle_options(SslOptions ++ InetValues, server) of
{ok, #config{cb=CbInfo,ssl=SslOpts, emulated=EmOpts}} ->
{ok, Port} = inet:port(Socket),
@@ -252,7 +252,7 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) ->
%%--------------------------------------------------------------------
-spec close(#sslsocket{}) -> term().
%%
-%% Description: Close a ssl connection
+%% Description: Close an ssl connection
%%--------------------------------------------------------------------
close(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _, _}}}, fd = new_ssl}) ->
CbMod:close(ListenSocket);
@@ -406,25 +406,51 @@ cipher_suites(openssl) ->
%%
%% Description: Gets options
%%--------------------------------------------------------------------
-getopts(#sslsocket{fd = new_ssl, pid = Pid}, OptTags) when is_pid(Pid) ->
- ssl_connection:get_opts(Pid, OptTags);
-getopts(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}, OptTags) ->
- inet:getopts(ListenSocket, OptTags);
-getopts(#sslsocket{} = Socket, Options) ->
+getopts(#sslsocket{fd = new_ssl, pid = Pid}, OptionTags) when is_pid(Pid), is_list(OptionTags) ->
+ ssl_connection:get_opts(Pid, OptionTags);
+getopts(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}, OptionTags) when is_list(OptionTags) ->
+ try inet:getopts(ListenSocket, OptionTags) of
+ {ok, _} = Result ->
+ Result;
+ {error, InetError} ->
+ {error, {eoptions, {inet_options, OptionTags, InetError}}}
+ catch
+ _:_ ->
+ {error, {eoptions, {inet_options, OptionTags}}}
+ end;
+getopts(#sslsocket{fd = new_ssl}, OptionTags) ->
+ {error, {eoptions, {inet_options, OptionTags}}};
+getopts(#sslsocket{} = Socket, OptionTags) ->
ensure_old_ssl_started(),
- ssl_broker:getopts(Socket, Options).
+ ssl_broker:getopts(Socket, OptionTags).
%%--------------------------------------------------------------------
--spec setopts(#sslsocket{}, [proplist:property()]) -> ok | {error, reason()}.
+-spec setopts(#sslsocket{}, [proplists:property()]) -> ok | {error, reason()}.
%%
%% Description: Sets options
%%--------------------------------------------------------------------
-setopts(#sslsocket{fd = new_ssl, pid = Pid}, Opts0) when is_pid(Pid) ->
- Opts = proplists:expand([{binary, [{mode, binary}]},
- {list, [{mode, list}]}], Opts0),
- ssl_connection:set_opts(Pid, Opts);
-setopts(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}, OptTags) ->
- inet:setopts(ListenSocket, OptTags);
+setopts(#sslsocket{fd = new_ssl, pid = Pid}, Options0) when is_pid(Pid), is_list(Options0) ->
+ try proplists:expand([{binary, [{mode, binary}]},
+ {list, [{mode, list}]}], Options0) of
+ Options ->
+ ssl_connection:set_opts(Pid, Options)
+ catch
+ _:_ ->
+ {error, {eoptions, {not_a_proplist, Options0}}}
+ end;
+
+setopts(#sslsocket{fd = new_ssl, pid = {ListenSocket, _}}, Options) when is_list(Options) ->
+ try inet:setopts(ListenSocket, Options) of
+ ok ->
+ ok;
+ {error, InetError} ->
+ {error, {eoptions, {inet_options, Options, InetError}}}
+ catch
+ _:Error ->
+ {error, {eoptions, {inet_options, Options, Error}}}
+ end;
+setopts(#sslsocket{fd = new_ssl}, Options) ->
+ {error, {eoptions,{not_a_proplist, Options}}};
setopts(#sslsocket{} = Socket, Options) ->
ensure_old_ssl_started(),
ssl_broker:setopts(Socket, Options).
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index 8c0c2bfa5d..422ea6404b 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -30,9 +30,9 @@
-include("ssl_internal.hrl").
-include_lib("public_key/include/public_key.hrl").
--export([trusted_cert_and_path/2,
- certificate_chain/2,
- file_to_certificats/1,
+-export([trusted_cert_and_path/3,
+ certificate_chain/3,
+ file_to_certificats/2,
validate_extension/3,
is_valid_extkey_usage/2,
is_valid_key_usage/2,
@@ -46,14 +46,14 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec trusted_cert_and_path([der_cert()], certdb_ref()) ->
+-spec trusted_cert_and_path([der_cert()], db_handle(), certdb_ref()) ->
{der_cert() | unknown_ca, [der_cert()]}.
%%
%% Description: Extracts the root cert (if not presents tries to
%% look it up, if not found {bad_cert, unknown_ca} will be added verification
%% errors. Returns {RootCert, Path, VerifyErrors}
%%--------------------------------------------------------------------
-trusted_cert_and_path(CertChain, CertDbRef) ->
+trusted_cert_and_path(CertChain, CertDbHandle, CertDbRef) ->
Path = [Cert | _] = lists:reverse(CertChain),
OtpCert = public_key:pkix_decode_cert(Cert, otp),
SignedAndIssuerID =
@@ -66,7 +66,7 @@ trusted_cert_and_path(CertChain, CertDbRef) ->
{ok, IssuerId} ->
{other, IssuerId};
{error, issuer_not_found} ->
- case find_issuer(OtpCert, no_candidate) of
+ case find_issuer(OtpCert, no_candidate, CertDbHandle) of
{ok, IssuerId} ->
{other, IssuerId};
Other ->
@@ -82,7 +82,7 @@ trusted_cert_and_path(CertChain, CertDbRef) ->
{self, _} when length(Path) == 1 ->
{selfsigned_peer, Path};
{_ ,{SerialNr, Issuer}} ->
- case ssl_manager:lookup_trusted_cert(CertDbRef, SerialNr, Issuer) of
+ case ssl_manager:lookup_trusted_cert(CertDbHandle, CertDbRef, SerialNr, Issuer) of
{ok, {BinCert,_}} ->
{BinCert, Path};
_ ->
@@ -92,23 +92,23 @@ trusted_cert_and_path(CertChain, CertDbRef) ->
end.
%%--------------------------------------------------------------------
--spec certificate_chain(undefined | binary(), certdb_ref()) ->
+-spec certificate_chain(undefined | binary(), db_handle(), certdb_ref()) ->
{error, no_cert} | {ok, [der_cert()]}.
%%
%% Description: Return the certificate chain to send to peer.
%%--------------------------------------------------------------------
-certificate_chain(undefined, _CertsDbRef) ->
+certificate_chain(undefined, _, _) ->
{error, no_cert};
-certificate_chain(OwnCert, CertsDbRef) ->
+certificate_chain(OwnCert, CertDbHandle, CertsDbRef) ->
ErlCert = public_key:pkix_decode_cert(OwnCert, otp),
- certificate_chain(ErlCert, OwnCert, CertsDbRef, [OwnCert]).
+ certificate_chain(ErlCert, OwnCert, CertDbHandle, CertsDbRef, [OwnCert]).
%%--------------------------------------------------------------------
--spec file_to_certificats(string()) -> [der_cert()].
+-spec file_to_certificats(string(), term()) -> [der_cert()].
%%
%% Description: Return list of DER encoded certificates.
%%--------------------------------------------------------------------
-file_to_certificats(File) ->
- {ok, List} = ssl_manager:cache_pem_file(File),
+file_to_certificats(File, DbHandle) ->
+ {ok, List} = ssl_manager:cache_pem_file(File, DbHandle),
[Bin || {'Certificate', Bin, not_encrypted} <- List].
%%--------------------------------------------------------------------
-spec validate_extension(term(), #'Extension'{} | {bad_cert, atom()} | valid,
@@ -180,7 +180,7 @@ signature_type(?'id-dsa-with-sha1') ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-certificate_chain(OtpCert, _Cert, CertsDbRef, Chain) ->
+certificate_chain(OtpCert, _Cert, CertDbHandle, CertsDbRef, Chain) ->
IssuerAndSelfSigned =
case public_key:pkix_is_self_signed(OtpCert) of
true ->
@@ -191,11 +191,11 @@ certificate_chain(OtpCert, _Cert, CertsDbRef, Chain) ->
case IssuerAndSelfSigned of
{_, true = SelfSigned} ->
- certificate_chain(CertsDbRef, Chain, ignore, ignore, SelfSigned);
+ certificate_chain(CertDbHandle, CertsDbRef, Chain, ignore, ignore, SelfSigned);
{{error, issuer_not_found}, SelfSigned} ->
- case find_issuer(OtpCert, no_candidate) of
+ case find_issuer(OtpCert, no_candidate, CertDbHandle) of
{ok, {SerialNr, Issuer}} ->
- certificate_chain(CertsDbRef, Chain,
+ certificate_chain(CertDbHandle, CertsDbRef, Chain,
SerialNr, Issuer, SelfSigned);
_ ->
%% Guess the the issuer must be the root
@@ -205,19 +205,19 @@ certificate_chain(OtpCert, _Cert, CertsDbRef, Chain) ->
{ok, lists:reverse(Chain)}
end;
{{ok, {SerialNr, Issuer}}, SelfSigned} ->
- certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, SelfSigned)
+ certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, SelfSigned)
end.
-certificate_chain(_CertsDbRef, Chain, _SerialNr, _Issuer, true) ->
+certificate_chain(_,_, Chain, _SerialNr, _Issuer, true) ->
{ok, lists:reverse(Chain)};
-certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
- case ssl_manager:lookup_trusted_cert(CertsDbRef,
+certificate_chain(CertDbHandle, CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
+ case ssl_manager:lookup_trusted_cert(CertDbHandle, CertsDbRef,
SerialNr, Issuer) of
{ok, {IssuerCert, ErlCert}} ->
ErlCert = public_key:pkix_decode_cert(IssuerCert, otp),
certificate_chain(ErlCert, IssuerCert,
- CertsDbRef, [IssuerCert | Chain]);
+ CertDbHandle, CertsDbRef, [IssuerCert | Chain]);
_ ->
%% The trusted cert may be obmitted from the chain as the
%% counter part needs to have it anyway to be able to
@@ -227,8 +227,8 @@ certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
{ok, lists:reverse(Chain)}
end.
-find_issuer(OtpCert, PrevCandidateKey) ->
- case ssl_manager:issuer_candidate(PrevCandidateKey) of
+find_issuer(OtpCert, PrevCandidateKey, CertDbHandle) ->
+ case ssl_manager:issuer_candidate(PrevCandidateKey, CertDbHandle) of
no_more_candidates ->
{error, issuer_not_found};
{Key, {_Cert, ErlCertCandidate}} ->
@@ -236,7 +236,7 @@ find_issuer(OtpCert, PrevCandidateKey) ->
true ->
public_key:pkix_issuer_id(ErlCertCandidate, self);
false ->
- find_issuer(OtpCert, Key)
+ find_issuer(OtpCert, Key, CertDbHandle)
end
end.
diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl
index 3eceefa304..0560a02110 100644
--- a/lib/ssl/src/ssl_certificate_db.erl
+++ b/lib/ssl/src/ssl_certificate_db.erl
@@ -26,8 +26,8 @@
-include_lib("public_key/include/public_key.hrl").
-export([create/0, remove/1, add_trusted_certs/3,
- remove_trusted_certs/2, lookup_trusted_cert/3, issuer_candidate/1,
- lookup_cached_certs/1, cache_pem_file/4, uncache_pem_file/2, lookup/2]).
+ remove_trusted_certs/2, lookup_trusted_cert/4, issuer_candidate/2,
+ lookup_cached_certs/2, cache_pem_file/4, uncache_pem_file/2, lookup/2]).
-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
@@ -36,19 +36,19 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec create() -> certdb_ref().
+-spec create() -> [db_handle()].
%%
%% Description: Creates a new certificate db.
-%% Note: lookup_trusted_cert/3 may be called from any process but only
+%% Note: lookup_trusted_cert/4 may be called from any process but only
%% the process that called create may call the other functions.
%%--------------------------------------------------------------------
create() ->
- [ets:new(certificate_db_name(), [named_table, set, protected]),
- ets:new(ssl_file_to_ref, [named_table, set, protected]),
+ [ets:new(ssl_otp_certificate_db, [set, protected]),
+ ets:new(ssl_file_to_ref, [set, protected]),
ets:new(ssl_pid_to_file, [bag, private])].
%%--------------------------------------------------------------------
--spec remove(certdb_ref()) -> term().
+-spec remove([db_handle()]) -> term().
%%
%% Description: Removes database db
%%--------------------------------------------------------------------
@@ -56,7 +56,7 @@ remove(Dbs) ->
lists:foreach(fun(Db) -> true = ets:delete(Db) end, Dbs).
%%--------------------------------------------------------------------
--spec lookup_trusted_cert(reference(), serialnumber(), issuer()) ->
+-spec lookup_trusted_cert(db_handle(), certdb_ref(), serialnumber(), issuer()) ->
undefined | {ok, {der_cert(), #'OTPCertificate'{}}}.
%%
@@ -64,19 +64,19 @@ remove(Dbs) ->
%% <SerialNumber, Issuer>. Ref is used as it is specified
%% for each connection which certificates are trusted.
%%--------------------------------------------------------------------
-lookup_trusted_cert(Ref, SerialNumber, Issuer) ->
- case lookup({Ref, SerialNumber, Issuer}, certificate_db_name()) of
+lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
+ case lookup({Ref, SerialNumber, Issuer}, DbHandle) of
undefined ->
undefined;
[Certs] ->
{ok, Certs}
end.
-lookup_cached_certs(File) ->
- ets:lookup(certificate_db_name(), {file, File}).
+lookup_cached_certs(DbHandle, File) ->
+ ets:lookup(DbHandle, {file, File}).
%%--------------------------------------------------------------------
--spec add_trusted_certs(pid(), string() | {der, list()}, certdb_ref()) -> {ok, certdb_ref()}.
+-spec add_trusted_certs(pid(), string() | {der, list()}, [db_handle()]) -> {ok, [db_handle()]}.
%%
%% Description: Adds the trusted certificates from file <File> to the
%% runtime database. Returns Ref that should be handed to lookup_trusted_cert
@@ -100,7 +100,7 @@ add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) ->
insert(Pid, File, PidToFileDb),
{ok, Ref}.
%%--------------------------------------------------------------------
--spec cache_pem_file(pid(), string(), time(), certdb_ref()) -> term().
+-spec cache_pem_file(pid(), string(), time(), [db_handle()]) -> term().
%%
%% Description: Cache file as binary in DB
%%--------------------------------------------------------------------
@@ -112,7 +112,7 @@ cache_pem_file(Pid, File, Time, [CertsDb, _FileToRefDb, PidToFileDb]) ->
{ok, Content}.
%--------------------------------------------------------------------
--spec uncache_pem_file(string(), certdb_ref()) -> no_return().
+-spec uncache_pem_file(string(), [db_handle()]) -> no_return().
%%
%% Description: If a cached file is no longer valid (changed on disk)
%% we must terminate the connections using the old file content, and
@@ -130,7 +130,7 @@ uncache_pem_file(File, [_CertsDb, _FileToRefDb, PidToFileDb]) ->
%%--------------------------------------------------------------------
--spec remove_trusted_certs(pid(), certdb_ref()) -> term().
+-spec remove_trusted_certs(pid(), [db_handle()]) -> term().
%%
%% Description: Removes trusted certs originating from
@@ -161,7 +161,7 @@ remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) ->
end.
%%--------------------------------------------------------------------
--spec issuer_candidate(no_candidate | cert_key() | {file, term()}) ->
+-spec issuer_candidate(no_candidate | cert_key() | {file, term()}, term()) ->
{cert_key(),{der_cert(), #'OTPCertificate'{}}} | no_more_candidates.
%%
%% Description: If a certificat does not define its issuer through
@@ -169,32 +169,30 @@ remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) ->
%% try to find the issuer in the database over known
%% certificates.
%%--------------------------------------------------------------------
-issuer_candidate(no_candidate) ->
- Db = certificate_db_name(),
+issuer_candidate(no_candidate, Db) ->
case ets:first(Db) of
'$end_of_table' ->
no_more_candidates;
{file, _} = Key ->
- issuer_candidate(Key);
+ issuer_candidate(Key, Db);
Key ->
[Cert] = lookup(Key, Db),
{Key, Cert}
end;
-issuer_candidate(PrevCandidateKey) ->
- Db = certificate_db_name(),
+issuer_candidate(PrevCandidateKey, Db) ->
case ets:next(Db, PrevCandidateKey) of
'$end_of_table' ->
no_more_candidates;
{file, _} = Key ->
- issuer_candidate(Key);
+ issuer_candidate(Key, Db);
Key ->
[Cert] = lookup(Key, Db),
{Key, Cert}
end.
%%--------------------------------------------------------------------
--spec lookup(term(), term()) -> term() | undefined.
+-spec lookup(term(), db_handle()) -> term() | undefined.
%%
%% Description: Looks up an element in a certificat <Db>.
%%--------------------------------------------------------------------
@@ -212,9 +210,6 @@ lookup(Key, Db) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-certificate_db_name() ->
- ssl_otp_certificate_db.
-
insert(Key, Data, Db) ->
true = ets:insert(Db, {Key, Data}).
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 2c452837f8..79570c520a 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -70,6 +70,7 @@
%% {{md5_hash, sha_hash}, {prev_md5, prev_sha}} (binary())
tls_handshake_hashes, % see above
tls_cipher_texts, % list() received but not deciphered yet
+ cert_db, %
session, % #session{} from ssl_handshake.hrl
session_cache, %
session_cache_cb, %
@@ -130,7 +131,7 @@ recv(Pid, Length, Timeout) ->
pid(), tuple(), timeout()) ->
{ok, #sslsocket{}} | {error, reason()}.
%%
-%% Description: Connect to a ssl server.
+%% Description: Connect to an ssl server.
%%--------------------------------------------------------------------
connect(Host, Port, Socket, Options, User, CbInfo, Timeout) ->
try start_fsm(client, Host, Port, Socket, Options, User, CbInfo,
@@ -144,7 +145,7 @@ connect(Host, Port, Socket, Options, User, CbInfo, Timeout) ->
pid(), tuple(), timeout()) ->
{ok, #sslsocket{}} | {error, reason()}.
%%
-%% Description: Performs accept on a ssl listen socket. e.i. performs
+%% Description: Performs accept on an ssl listen socket. e.i. performs
%% ssl handshake.
%%--------------------------------------------------------------------
ssl_accept(Port, Socket, Opts, User, CbInfo, Timeout) ->
@@ -184,7 +185,7 @@ socket_control(Socket, Pid, CbModule) ->
%%--------------------------------------------------------------------
-spec close(pid()) -> ok | {error, reason()}.
%%
-%% Description: Close a ssl connection
+%% Description: Close an ssl connection
%%--------------------------------------------------------------------
close(ConnectionPid) ->
case sync_send_all_state_event(ConnectionPid, close) of
@@ -305,12 +306,13 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options,
Hashes0 = ssl_handshake:init_hashes(),
try ssl_init(SSLOpts0, Role) of
- {ok, Ref, CacheRef, OwnCert, Key, DHParams} ->
+ {ok, Ref, CertDbHandle, CacheHandle, OwnCert, Key, DHParams} ->
Session = State0#state.session,
State = State0#state{tls_handshake_hashes = Hashes0,
session = Session#session{own_certificate = OwnCert},
cert_db_ref = Ref,
- session_cache = CacheRef,
+ cert_db = CertDbHandle,
+ session_cache = CacheHandle,
private_key = Key,
diffie_hellman_params = DHParams},
{ok, hello, State, get_timeout(State)}
@@ -500,9 +502,10 @@ certify(#certificate{asn1_certificates = []},
certify(#certificate{} = Cert,
#state{negotiated_version = Version,
role = Role,
+ cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
ssl_options = Opts} = State) ->
- case ssl_handshake:certify(Cert, 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, Role) of
{PeerCert, PublicKeyInfo} ->
@@ -859,23 +862,23 @@ handle_sync_event({set_opts, Opts0}, _From, StateName,
#state{socket_options = Opts1,
socket = Socket,
user_data_buffer = Buffer} = State0) ->
- Opts = set_socket_opts(Socket, Opts0, Opts1, []),
+ {Reply, Opts} = set_socket_opts(Socket, Opts0, Opts1, []),
State1 = State0#state{socket_options = Opts},
if
Opts#socket_options.active =:= false ->
- {reply, ok, StateName, State1, get_timeout(State1)};
+ {reply, Reply, StateName, State1, get_timeout(State1)};
Buffer =:= <<>>, Opts1#socket_options.active =:= false ->
%% Need data, set active once
{Record, State2} = next_record_if_active(State1),
case next_state(StateName, Record, State2) of
{next_state, StateName, State, Timeout} ->
- {reply, ok, StateName, State, Timeout};
+ {reply, Reply, StateName, State, Timeout};
{stop, Reason, State} ->
{stop, Reason, State}
end;
Buffer =:= <<>> ->
%% Active once already set
- {reply, ok, StateName, State1, get_timeout(State1)};
+ {reply, Reply, StateName, State1, get_timeout(State1)};
true ->
case application_data(<<>>, State1) of
Stop = {stop,_,_} ->
@@ -883,7 +886,7 @@ handle_sync_event({set_opts, Opts0}, _From, StateName,
{Record, State2} ->
case next_state(StateName, Record, State2) of
{next_state, StateName, State, Timeout} ->
- {reply, ok, StateName, State, Timeout};
+ {reply, Reply, StateName, State, Timeout};
{stop, Reason, State} ->
{stop, Reason, State}
end
@@ -1044,19 +1047,19 @@ start_fsm(Role, Host, Port, Socket, Opts, User, {CbModule, _,_, _} = CbInfo,
end.
ssl_init(SslOpts, Role) ->
- {ok, CertDbRef, CacheRef, OwnCert} = init_certificates(SslOpts, Role),
+ {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert} = init_certificates(SslOpts, Role),
PrivateKey =
- init_private_key(SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
+ init_private_key(CertDbHandle, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile,
SslOpts#ssl_options.password, Role),
- DHParams = init_diffie_hellman(SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role),
- {ok, CertDbRef, CacheRef, OwnCert, PrivateKey, DHParams}.
+ DHParams = init_diffie_hellman(CertDbHandle, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role),
+ {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert, PrivateKey, DHParams}.
init_certificates(#ssl_options{cacerts = CaCerts,
cacertfile = CACertFile,
certfile = CertFile,
cert = Cert}, Role) ->
- {ok, CertDbRef, CacheRef} =
+ {ok, CertDbRef, CertDbHandle, CacheHandle} =
try
Certs = case CaCerts of
undefined ->
@@ -1064,44 +1067,44 @@ init_certificates(#ssl_options{cacerts = CaCerts,
_ ->
{der, CaCerts}
end,
- {ok, _, _} = ssl_manager:connection_init(Certs, Role)
+ {ok, _, _, _} = ssl_manager:connection_init(Certs, Role)
catch
Error:Reason ->
handle_file_error(?LINE, Error, Reason, CACertFile, ecacertfile,
erlang:get_stacktrace())
end,
- init_certificates(Cert, CertDbRef, CacheRef, CertFile, Role).
+ init_certificates(Cert, CertDbRef, CertDbHandle, CacheHandle, CertFile, Role).
-init_certificates(undefined, CertDbRef, CacheRef, "", _) ->
- {ok, CertDbRef, CacheRef, undefined};
+init_certificates(undefined, CertDbRef, CertDbHandle, CacheHandle, "", _) ->
+ {ok, CertDbRef, CertDbHandle, CacheHandle, undefined};
-init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) ->
+init_certificates(undefined, CertDbRef, CertDbHandle, CacheHandle, CertFile, client) ->
try
- [OwnCert] = ssl_certificate:file_to_certificats(CertFile),
- {ok, CertDbRef, CacheRef, OwnCert}
+ [OwnCert] = ssl_certificate:file_to_certificats(CertFile, CertDbHandle),
+ {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert}
catch _Error:_Reason ->
- {ok, CertDbRef, CacheRef, undefined}
+ {ok, CertDbRef, CertDbHandle, CacheHandle, undefined}
end;
-init_certificates(undefined, CertDbRef, CacheRef, CertFile, server) ->
+init_certificates(undefined, CertDbRef, CertDbHandle, CacheRef, CertFile, server) ->
try
- [OwnCert] = ssl_certificate:file_to_certificats(CertFile),
- {ok, CertDbRef, CacheRef, OwnCert}
+ [OwnCert] = ssl_certificate:file_to_certificats(CertFile, CertDbHandle),
+ {ok, CertDbRef, CertDbHandle, CacheRef, OwnCert}
catch
Error:Reason ->
handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
erlang:get_stacktrace())
end;
-init_certificates(Cert, CertDbRef, CacheRef, _, _) ->
- {ok, CertDbRef, CacheRef, Cert}.
+init_certificates(Cert, CertDbRef, CertDbHandle, CacheRef, _, _) ->
+ {ok, CertDbRef, CertDbHandle, CacheRef, Cert}.
-init_private_key(undefined, "", _Password, _Client) ->
+init_private_key(_, undefined, "", _Password, _Client) ->
undefined;
-init_private_key(undefined, KeyFile, Password, _) ->
+init_private_key(DbHandle, undefined, KeyFile, Password, _) ->
try
- {ok, List} = ssl_manager:cache_pem_file(KeyFile),
+ {ok, List} = ssl_manager:cache_pem_file(KeyFile, DbHandle),
[PemEntry] = [PemEntry || PemEntry = {PKey, _ , _} <- List,
- PKey =:= 'RSAPrivateKey' orelse
+ PKey =:= 'RSAPrivateKey' orelse
PKey =:= 'DSAPrivateKey'],
public_key:pem_entry_decode(PemEntry, Password)
catch
@@ -1110,9 +1113,9 @@ init_private_key(undefined, KeyFile, Password, _) ->
erlang:get_stacktrace())
end;
-init_private_key({rsa, PrivateKey}, _, _,_) ->
+init_private_key(_,{rsa, PrivateKey}, _, _,_) ->
public_key:der_decode('RSAPrivateKey', PrivateKey);
-init_private_key({dsa, PrivateKey},_,_,_) ->
+init_private_key(_,{dsa, PrivateKey},_,_,_) ->
public_key:der_decode('DSAPrivateKey', PrivateKey).
-spec(handle_file_error(_,_,_,_,_,_) -> no_return()).
@@ -1128,15 +1131,15 @@ file_error(Line, Error, Reason, File, Throw, Stack) ->
error_logger:error_report(Report),
throw(Throw).
-init_diffie_hellman(Params, _,_) when is_binary(Params)->
+init_diffie_hellman(_,Params, _,_) when is_binary(Params)->
public_key:der_decode('DHParameter', Params);
-init_diffie_hellman(_,_, client) ->
+init_diffie_hellman(_,_,_, client) ->
undefined;
-init_diffie_hellman(_,undefined, _) ->
+init_diffie_hellman(_,_,undefined, _) ->
?DEFAULT_DIFFIE_HELLMAN_PARAMS;
-init_diffie_hellman(_, DHParamFile, server) ->
+init_diffie_hellman(DbHandle,_, DHParamFile, server) ->
try
- {ok, List} = ssl_manager:cache_pem_file(DHParamFile),
+ {ok, List} = ssl_manager:cache_pem_file(DHParamFile,DbHandle),
case [Entry || Entry = {'DHParameter', _ , _} <- List] of
[Entry] ->
public_key:pem_entry_decode(Entry);
@@ -1180,11 +1183,12 @@ certify_client(#state{client_certificate_requested = true, role = client,
connection_states = ConnectionStates0,
transport_cb = Transport,
negotiated_version = Version,
+ cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
session = #session{own_certificate = OwnCert},
socket = Socket,
tls_handshake_hashes = Hashes0} = State) ->
- Certificate = ssl_handshake:certificate(OwnCert, CertDbRef, client),
+ Certificate = ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, client),
{BinCert, ConnectionStates1, Hashes1} =
encode_handshake(Certificate, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinCert),
@@ -1365,9 +1369,10 @@ certify_server(#state{transport_cb = Transport,
negotiated_version = Version,
connection_states = ConnectionStates,
tls_handshake_hashes = Hashes,
+ cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
session = #session{own_certificate = OwnCert}} = State) ->
- case ssl_handshake:certificate(OwnCert, CertDbRef, server) of
+ case ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, server) of
CertMsg = #certificate{} ->
{BinCertMsg, NewConnectionStates, NewHashes} =
encode_handshake(CertMsg, Version, ConnectionStates, Hashes),
@@ -1454,12 +1459,13 @@ rsa_key_exchange(_, _) ->
request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
connection_states = ConnectionStates0,
+ cert_db = CertDbHandle,
cert_db_ref = CertDbRef,
tls_handshake_hashes = Hashes0,
negotiated_version = Version,
socket = Socket,
transport_cb = Transport} = State) ->
- Msg = ssl_handshake:certificate_request(ConnectionStates0, CertDbRef),
+ Msg = ssl_handshake:certificate_request(ConnectionStates0, CertDbHandle, CertDbRef),
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Msg, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
@@ -2040,31 +2046,67 @@ get_socket_opts(Socket, [active | Tags], SockOpts, Acc) ->
get_socket_opts(Socket, Tags, SockOpts,
[{active, SockOpts#socket_options.active} | Acc]);
get_socket_opts(Socket, [Tag | Tags], SockOpts, Acc) ->
- case inet:getopts(Socket, [Tag]) of
+ try inet:getopts(Socket, [Tag]) of
{ok, [Opt]} ->
get_socket_opts(Socket, Tags, SockOpts, [Opt | Acc]);
{error, Error} ->
- {error, Error}
- end.
+ {error, {eoptions, {inet_option, Tag, Error}}}
+ catch
+ %% So that inet behavior does not crash our process
+ _:Error -> {error, {eoptions, {inet_option, Tag, Error}}}
+ end;
+get_socket_opts(_,Opts, _,_) ->
+ {error, {eoptions, {inet_option, Opts, function_clause}}}.
set_socket_opts(_, [], SockOpts, []) ->
- SockOpts;
+ {ok, SockOpts};
set_socket_opts(Socket, [], SockOpts, Other) ->
%% Set non emulated options
- inet:setopts(Socket, Other),
- SockOpts;
-set_socket_opts(Socket, [{mode, Mode}| Opts], SockOpts, Other) ->
+ try inet:setopts(Socket, Other) of
+ ok ->
+ {ok, SockOpts};
+ {error, InetError} ->
+ {{error, {eoptions, {inet_options, Other, InetError}}}, SockOpts}
+ catch
+ _:Error ->
+ %% So that inet behavior does not crash our process
+ {{error, {eoptions, {inet_options, Other, Error}}}, SockOpts}
+ end;
+
+set_socket_opts(Socket, [{mode, Mode}| Opts], SockOpts, Other) when Mode == list; Mode == binary ->
set_socket_opts(Socket, Opts,
SockOpts#socket_options{mode = Mode}, Other);
-set_socket_opts(Socket, [{packet, Packet}| Opts], SockOpts, Other) ->
+set_socket_opts(_, [{mode, _} = Opt| _], SockOpts, _) ->
+ {{error, {eoptions, {inet_opt, Opt}}}, SockOpts};
+set_socket_opts(Socket, [{packet, Packet}| Opts], SockOpts, Other) when Packet == raw;
+ Packet == 0;
+ Packet == 1;
+ Packet == 2;
+ Packet == 4;
+ Packet == asn1;
+ Packet == cdr;
+ Packet == sunrm;
+ Packet == fcgi;
+ Packet == tpkt;
+ Packet == line;
+ Packet == http;
+ Packet == http_bin ->
set_socket_opts(Socket, Opts,
SockOpts#socket_options{packet = Packet}, Other);
-set_socket_opts(Socket, [{header, Header}| Opts], SockOpts, Other) ->
+set_socket_opts(_, [{packet, _} = Opt| _], SockOpts, _) ->
+ {{error, {eoptions, {inet_opt, Opt}}}, SockOpts};
+set_socket_opts(Socket, [{header, Header}| Opts], SockOpts, Other) when is_integer(Header) ->
set_socket_opts(Socket, Opts,
SockOpts#socket_options{header = Header}, Other);
-set_socket_opts(Socket, [{active, Active}| Opts], SockOpts, Other) ->
+set_socket_opts(_, [{header, _} = Opt| _], SockOpts, _) ->
+ {{error,{eoptions, {inet_opt, Opt}}}, SockOpts};
+set_socket_opts(Socket, [{active, Active}| Opts], SockOpts, Other) when Active == once;
+ Active == true;
+ Active == false ->
set_socket_opts(Socket, Opts,
SockOpts#socket_options{active = Active}, Other);
+set_socket_opts(_, [{active, _} = Opt| _], SockOpts, _) ->
+ {{error, {eoptions, {inet_opt, Opt}} }, SockOpts};
set_socket_opts(Socket, [Opt | Opts], SockOpts, Other) ->
set_socket_opts(Socket, Opts, SockOpts, [Opt | Other]).
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 1f4c44d115..4e74aec4ac 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -31,9 +31,9 @@
-include_lib("public_key/include/public_key.hrl").
-export([master_secret/4, client_hello/6, server_hello/4, hello/4,
- hello_request/0, certify/6, certificate/3,
+ hello_request/0, certify/7, certificate/4,
client_certificate_verify/5, certificate_verify/5,
- certificate_request/2, key_exchange/2, server_key_exchange_hash/2,
+ certificate_request/3, key_exchange/2, server_key_exchange_hash/2,
finished/4, verify_connection/5, get_tls_handshake/2,
decode_client_key/3, server_hello_done/0,
encode_handshake/2, init_hashes/0, update_hashes/2,
@@ -106,7 +106,7 @@ hello_request() ->
%%--------------------------------------------------------------------
-spec hello(#server_hello{} | #client_hello{}, #ssl_options{},
- #connection_states{} | {port_num(), #session{}, cache_ref(),
+ #connection_states{} | {port_num(), #session{}, db_handle(),
atom(), #connection_states{}, binary()},
boolean()) -> {tls_version(), session_id(), #connection_states{}}|
{tls_version(), {resumed | new, #session{}},
@@ -173,13 +173,13 @@ hello(#client_hello{client_version = ClientVersion, random = Random,
end.
%%--------------------------------------------------------------------
--spec certify(#certificate{}, term(), integer() | nolimit,
+-spec certify(#certificate{}, db_handle(), certdb_ref(), integer() | nolimit,
verify_peer | verify_none, {fun(), term},
client | server) -> {der_cert(), public_key_info()} | #alert{}.
%%
%% Description: Handles a certificate handshake message
%%--------------------------------------------------------------------
-certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
+certify(#certificate{asn1_certificates = ASN1Certs}, CertDbHandle, CertDbRef,
MaxPathLen, _Verify, VerifyFunAndState, Role) ->
[PeerCert | _] = ASN1Certs,
@@ -208,7 +208,7 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
end,
{TrustedErlCert, CertPath} =
- ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbRef),
+ ssl_certificate:trusted_cert_and_path(ASN1Certs, CertDbHandle, CertDbRef),
case public_key:pkix_path_validation(TrustedErlCert,
CertPath,
@@ -222,13 +222,13 @@ certify(#certificate{asn1_certificates = ASN1Certs}, CertDbRef,
end.
%%--------------------------------------------------------------------
--spec certificate(der_cert(), term(), client | server) -> #certificate{} | #alert{}.
+-spec certificate(der_cert(), db_handle(), certdb_ref(), client | server) -> #certificate{} | #alert{}.
%%
%% Description: Creates a certificate message.
%%--------------------------------------------------------------------
-certificate(OwnCert, CertDbRef, client) ->
+certificate(OwnCert, CertDbHandle, CertDbRef, client) ->
Chain =
- case ssl_certificate:certificate_chain(OwnCert, CertDbRef) of
+ case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
{ok, CertChain} ->
CertChain;
{error, _} ->
@@ -239,8 +239,8 @@ certificate(OwnCert, CertDbRef, client) ->
end,
#certificate{asn1_certificates = Chain};
-certificate(OwnCert, CertDbRef, server) ->
- case ssl_certificate:certificate_chain(OwnCert, CertDbRef) of
+certificate(OwnCert, CertDbHandle, CertDbRef, server) ->
+ case ssl_certificate:certificate_chain(OwnCert, CertDbHandle, CertDbRef) of
{ok, Chain} ->
#certificate{asn1_certificates = Chain};
{error, _} ->
@@ -302,17 +302,17 @@ certificate_verify(Signature, {?'id-dsa' = Algorithm, PublicKey, PublicKeyParams
%%--------------------------------------------------------------------
--spec certificate_request(#connection_states{}, certdb_ref()) ->
+-spec certificate_request(#connection_states{}, db_handle(), certdb_ref()) ->
#certificate_request{}.
%%
%% Description: Creates a certificate_request message, called by the server.
%%--------------------------------------------------------------------
-certificate_request(ConnectionStates, CertDbRef) ->
+certificate_request(ConnectionStates, CertDbHandle, CertDbRef) ->
#connection_state{security_parameters =
#security_parameters{cipher_suite = CipherSuite}} =
ssl_record:pending_connection_state(ConnectionStates, read),
Types = certificate_types(CipherSuite),
- Authorities = certificate_authorities(CertDbRef),
+ Authorities = certificate_authorities(CertDbHandle, CertDbRef),
#certificate_request{
certificate_types = Types,
certificate_authorities = Authorities
@@ -1071,8 +1071,8 @@ certificate_types({KeyExchange, _, _, _})
certificate_types(_) ->
<<?BYTE(?RSA_SIGN)>>.
-certificate_authorities(CertDbRef) ->
- Authorities = certificate_authorities_from_db(CertDbRef),
+certificate_authorities(CertDbHandle, CertDbRef) ->
+ Authorities = certificate_authorities_from_db(CertDbHandle, CertDbRef),
Enc = fun(#'OTPCertificate'{tbsCertificate=TBSCert}) ->
OTPSubj = TBSCert#'OTPTBSCertificate'.subject,
DNEncodedBin = public_key:pkix_encode('Name', OTPSubj, otp),
@@ -1084,18 +1084,18 @@ certificate_authorities(CertDbRef) ->
end,
list_to_binary([Enc(Cert) || {_, Cert} <- Authorities]).
-certificate_authorities_from_db(CertDbRef) ->
- certificate_authorities_from_db(CertDbRef, no_candidate, []).
+certificate_authorities_from_db(CertDbHandle, CertDbRef) ->
+ certificate_authorities_from_db(CertDbHandle, CertDbRef, no_candidate, []).
-certificate_authorities_from_db(CertDbRef, PrevKey, Acc) ->
- case ssl_manager:issuer_candidate(PrevKey) of
+certificate_authorities_from_db(CertDbHandle,CertDbRef, PrevKey, Acc) ->
+ case ssl_manager:issuer_candidate(PrevKey, CertDbHandle) of
no_more_candidates ->
lists:reverse(Acc);
{{CertDbRef, _, _} = Key, Cert} ->
- certificate_authorities_from_db(CertDbRef, Key, [Cert|Acc]);
+ certificate_authorities_from_db(CertDbHandle, CertDbRef, Key, [Cert|Acc]);
{Key, _Cert} ->
%% skip certs not from this ssl connection
- certificate_authorities_from_db(CertDbRef, Key, Acc)
+ certificate_authorities_from_db(CertDbHandle, CertDbRef, Key, Acc)
end.
digitally_signed(Hash, #'RSAPrivateKey'{} = Key) ->
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index c28daa271e..cc66246068 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -33,8 +33,8 @@
-type session_id() :: 0 | binary().
-type tls_version() :: {integer(), integer()}.
-type tls_atom_version() :: sslv3 | tlsv1.
--type cache_ref() :: term().
--type certdb_ref() :: term().
+-type certdb_ref() :: reference().
+-type db_handle() :: term().
-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | dh_anon.
-type der_cert() :: binary().
-type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}.
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 5a2d0c9496..b02815bfd8 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -28,8 +28,8 @@
%% Internal application API
-export([start_link/1,
- connection_init/2, cache_pem_file/1,
- lookup_trusted_cert/3, issuer_candidate/1, client_session_id/4,
+ connection_init/2, cache_pem_file/2,
+ lookup_trusted_cert/4, issuer_candidate/2, client_session_id/4,
server_session_id/4,
register_session/2, register_session/3, invalidate_session/2,
invalidate_session/3]).
@@ -50,7 +50,8 @@
session_cache_cb,
session_lifetime,
certificate_db,
- session_validation_timer
+ session_validation_timer,
+ last_delay_timer %% Keep for testing purposes
}).
-define('24H_in_msec', 8640000).
@@ -72,45 +73,45 @@ start_link(Opts) ->
%%--------------------------------------------------------------------
-spec connection_init(string()| {der, list()}, client | server) ->
- {ok, reference(), cache_ref()}.
+ {ok, certdb_ref(), db_handle(), db_handle()}.
%%
%% Description: Do necessary initializations for a new connection.
%%--------------------------------------------------------------------
connection_init(Trustedcerts, Role) ->
call({connection_init, Trustedcerts, Role}).
%%--------------------------------------------------------------------
--spec cache_pem_file(string()) -> {ok, term()} | {error, reason()}.
+-spec cache_pem_file(string(), term()) -> {ok, term()} | {error, reason()}.
%%
%% Description: Cach a pem file and return its content.
%%--------------------------------------------------------------------
-cache_pem_file(File) ->
+cache_pem_file(File, DbHandle) ->
try file:read_file_info(File) of
{ok, #file_info{mtime = LastWrite}} ->
- cache_pem_file(File, LastWrite)
+ cache_pem_file(File, LastWrite, DbHandle)
catch
_:Reason ->
{error, Reason}
end.
%%--------------------------------------------------------------------
--spec lookup_trusted_cert(reference(), serialnumber(), issuer()) ->
+-spec lookup_trusted_cert(term(), reference(), serialnumber(), issuer()) ->
undefined |
{ok, {der_cert(), #'OTPCertificate'{}}}.
%%
%% Description: Lookup the trusted cert with Key = {reference(),
%% serialnumber(), issuer()}.
%% --------------------------------------------------------------------
-lookup_trusted_cert(Ref, SerialNumber, Issuer) ->
- ssl_certificate_db:lookup_trusted_cert(Ref, SerialNumber, Issuer).
+lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) ->
+ ssl_certificate_db:lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer).
%%--------------------------------------------------------------------
--spec issuer_candidate(cert_key() | no_candidate) ->
+-spec issuer_candidate(cert_key() | no_candidate, term()) ->
{cert_key(),
{der_cert(),
#'OTPCertificate'{}}} | no_more_candidates.
%%
%% Description: Return next issuer candidate.
%%--------------------------------------------------------------------
-issuer_candidate(PrevCandidateKey) ->
- ssl_certificate_db:issuer_candidate(PrevCandidateKey).
+issuer_candidate(PrevCandidateKey, DbHandle) ->
+ ssl_certificate_db:issuer_candidate(PrevCandidateKey, DbHandle).
%%--------------------------------------------------------------------
-spec client_session_id(host(), port_num(), #ssl_options{},
der_cert() | undefined) -> session_id().
@@ -192,19 +193,20 @@ init([Opts]) ->
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call({{connection_init, "", _Role}, Pid}, _From,
- #state{session_cache = Cache} = State) ->
+ #state{certificate_db = [CertDb |_],
+ session_cache = Cache} = State) ->
erlang:monitor(process, Pid),
- Result = {ok, make_ref(), Cache},
+ Result = {ok, make_ref(),CertDb, Cache},
{reply, Result, State};
handle_call({{connection_init, Trustedcerts, _Role}, Pid}, _From,
- #state{certificate_db = Db,
+ #state{certificate_db = [CertDb|_] =Db,
session_cache = Cache} = State) ->
erlang:monitor(process, Pid),
Result =
try
{ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, Trustedcerts, Db),
- {ok, Ref, Cache}
+ {ok, Ref, CertDb, Cache}
catch
_:Reason ->
{error, Reason}
@@ -265,20 +267,25 @@ handle_cast({register_session, Port, Session},
CacheCb:update(Cache, {Port, NewSession#session.session_id}, NewSession),
{noreply, State};
-handle_cast({invalidate_session, Host, Port,
+%%% When a 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.
+handle_cast({invalidate_session, Host, Port,
#session{session_id = ID} = Session},
#state{session_cache = Cache,
session_cache_cb = CacheCb} = State) ->
CacheCb:update(Cache, {{Host, Port}, ID}, Session#session{is_resumable = false}),
- timer:apply_after(?CLEAN_SESSION_DB, CacheCb, delete, {{Host, Port}, ID}),
- {noreply, State};
+ TRef =
+ erlang:send_after(delay_time(), self(), {delayed_clean_session, {{Host, Port}, ID}}),
+ {noreply, State#state{last_delay_timer = TRef}};
handle_cast({invalidate_session, Port, #session{session_id = ID} = Session},
#state{session_cache = Cache,
session_cache_cb = CacheCb} = State) ->
CacheCb:update(Cache, {Port, ID}, Session#session{is_resumable = false}),
- timer:apply_after(?CLEAN_SESSION_DB, CacheCb, delete, {Port, ID}),
- {noreply, State};
+ TRef =
+ erlang:send_after(delay_time(), self(), {delayed_clean_session, {Port, ID}}),
+ {noreply, State#state{last_delay_timer = TRef}};
handle_cast({recache_pem, File, LastWrite, Pid, From},
#state{certificate_db = [_, FileToRefDb, _]} = State0) ->
@@ -312,6 +319,12 @@ handle_info(validate_sessions, #state{session_cache_cb = CacheCb,
start_session_validator(Cache, CacheCb, LifeTime),
{noreply, State#state{session_validation_timer = Timer}};
+handle_info({delayed_clean_session, Key}, #state{session_cache = Cache,
+ session_cache_cb = CacheCb
+ } = State) ->
+ CacheCb:delete(Cache, Key),
+ {noreply, State};
+
handle_info({'EXIT', _, _}, State) ->
%% Session validator died!! Do we need to take any action?
%% maybe error log
@@ -399,8 +412,8 @@ session_validation({{Port, _}, Session}, LifeTime) ->
validate_session(Port, Session, LifeTime),
LifeTime.
-cache_pem_file(File, LastWrite) ->
- case ssl_certificate_db:lookup_cached_certs(File) of
+cache_pem_file(File, LastWrite, DbHandle) ->
+ case ssl_certificate_db:lookup_cached_certs(DbHandle,File) of
[{_, {Mtime, Content}}] ->
case LastWrite of
Mtime ->
@@ -411,3 +424,11 @@ cache_pem_file(File, LastWrite) ->
[] ->
call({cache_pem, File, LastWrite})
end.
+
+delay_time() ->
+ case application:get_env(ssl, session_delay_cleanup_time) of
+ {ok, Time} when is_integer(Time) ->
+ Time;
+ _ ->
+ ?CLEAN_SESSION_DB
+ end.
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index f1c0073965..72091fdd5f 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -62,6 +62,8 @@
-compile(inline).
+-define(INITIAL_BYTES, 5).
+
%%====================================================================
%% Internal application API
%%====================================================================
@@ -340,7 +342,7 @@ get_tls_records_aux(<<?BYTE(?CHANGE_CIPHER_SPEC),?BYTE(MajVer),?BYTE(MinVer),
get_tls_records_aux(Rest, [#ssl_tls{type = ?CHANGE_CIPHER_SPEC,
version = {MajVer, MinVer},
fragment = Data} | Acc]);
-%% Matches a ssl v2 client hello message.
+%% Matches an ssl v2 client hello message.
%% The server must be able to receive such messages, from clients that
%% are willing to use ssl v3 or higher, but have ssl v2 compatibility.
get_tls_records_aux(<<1:1, Length0:15, Data0:Length0/binary, Rest/binary>>,
@@ -360,16 +362,20 @@ get_tls_records_aux(<<1:1, Length0:15, Data0:Length0/binary, Rest/binary>>,
get_tls_records_aux(<<0:1, _CT:7, ?BYTE(_MajVer), ?BYTE(_MinVer),
?UINT16(Length), _/binary>>,
- _Acc) when Length > ?MAX_CIPHER_TEXT_LENGTH->
+ _Acc) when Length > ?MAX_CIPHER_TEXT_LENGTH ->
?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
get_tls_records_aux(<<1:1, Length0:15, _/binary>>,_Acc)
- when Length0 > ?MAX_CIPHER_TEXT_LENGTH->
+ when Length0 > ?MAX_CIPHER_TEXT_LENGTH ->
?ALERT_REC(?FATAL, ?RECORD_OVERFLOW);
get_tls_records_aux(Data, Acc) ->
- {lists:reverse(Acc), Data}.
-
+ case size(Data) =< ?MAX_CIPHER_TEXT_LENGTH + ?INITIAL_BYTES of
+ true ->
+ {lists:reverse(Acc), Data};
+ false ->
+ ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE)
+ end.
%%--------------------------------------------------------------------
-spec protocol_version(tls_atom_version() | tls_version()) ->
tls_version() | tls_atom_version().
diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl
index dc4b7a711c..85c9fcb61c 100644
--- a/lib/ssl/src/ssl_session.erl
+++ b/lib/ssl/src/ssl_session.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -48,7 +48,7 @@ is_new(_ClientSuggestion, _ServerDecision) ->
true.
%%--------------------------------------------------------------------
--spec id({host(), port_num(), #ssl_options{}}, cache_ref(), atom(),
+-spec id({host(), port_num(), #ssl_options{}}, db_handle(), atom(),
undefined | binary()) -> binary().
%%
%% Description: Should be called by the client side to get an id
@@ -63,7 +63,7 @@ id(ClientInfo, Cache, CacheCb, OwnCert) ->
end.
%%--------------------------------------------------------------------
--spec id(port_num(), binary(), #ssl_options{}, cache_ref(),
+-spec id(port_num(), binary(), #ssl_options{}, db_handle(),
atom(), seconds(), binary()) -> binary().
%%
%% Description: Should be called by the server side to get an id
diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl
index 823bf7acfa..66610817be 100644
--- a/lib/ssl/src/ssl_session_cache.erl
+++ b/lib/ssl/src/ssl_session_cache.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -31,7 +31,7 @@
-type key() :: {{host(), port_num()}, session_id()} | {port_num(), session_id()}.
%%--------------------------------------------------------------------
--spec init(list()) -> cache_ref(). %% Returns reference to the cache (opaque)
+-spec init(list()) -> db_handle(). %% Returns reference to the cache (opaque)
%%
%% Description: Return table reference. Called by ssl_manager process.
%%--------------------------------------------------------------------
@@ -39,7 +39,7 @@ init(_) ->
ets:new(cache_name(), [set, protected]).
%%--------------------------------------------------------------------
--spec terminate(cache_ref()) -> any(). %%
+-spec terminate(db_handle()) -> any().
%%
%% Description: Handles cache table at termination of ssl manager.
%%--------------------------------------------------------------------
@@ -47,7 +47,7 @@ terminate(Cache) ->
ets:delete(Cache).
%%--------------------------------------------------------------------
--spec lookup(cache_ref(), key()) -> #session{} | undefined.
+-spec lookup(db_handle(), key()) -> #session{} | undefined.
%%
%% Description: Looks up a cach entry. Should be callable from any
%% process.
@@ -61,7 +61,7 @@ lookup(Cache, Key) ->
end.
%%--------------------------------------------------------------------
--spec update(cache_ref(), key(), #session{}) -> any().
+-spec update(db_handle(), key(), #session{}) -> any().
%%
%% Description: Caches a new session or updates a already cached one.
%% Will only be called from the ssl_manager process.
@@ -70,7 +70,7 @@ update(Cache, Key, Session) ->
ets:insert(Cache, {Key, Session}).
%%--------------------------------------------------------------------
--spec delete(cache_ref(), key()) -> any().
+-spec delete(db_handle(), key()) -> any().
%%
%% Description: Delets a cache entry.
%% Will only be called from the ssl_manager process.
@@ -79,7 +79,7 @@ delete(Cache, Key) ->
ets:delete(Cache, Key).
%%--------------------------------------------------------------------
--spec foldl(fun(), term(), cache_ref()) -> term().
+-spec foldl(fun(), term(), db_handle()) -> term().
%%
%% Description: Calls Fun(Elem, AccIn) on successive elements of the
%% cache, starting with AccIn == Acc0. Fun/2 must return a new
@@ -91,7 +91,7 @@ foldl(Fun, Acc0, Cache) ->
ets:foldl(Fun, Acc0, Cache).
%%--------------------------------------------------------------------
--spec select_session(cache_ref(), {host(), port_num()} | port_num()) -> [#session{}].
+-spec select_session(db_handle(), {host(), port_num()} | port_num()) -> [#session{}].
%%
%% Description: Selects a session that could be reused. Should be callable
%% from any process.
diff --git a/lib/ssl/src/ssl_ssl2.erl b/lib/ssl/src/ssl_ssl2.erl
index b1005b1acb..30a3a5fc98 100644
--- a/lib/ssl/src/ssl_ssl2.erl
+++ b/lib/ssl/src/ssl_ssl2.erl
@@ -20,7 +20,7 @@
%%
%%----------------------------------------------------------------------
%% Purpose: Handles sslv2 hello as clients supporting sslv2 and higher
-%% will send a sslv2 hello.
+%% will send an sslv2 hello.
%%----------------------------------------------------------------------
-module(ssl_ssl2).
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
index 53b2223035..5be07cad2c 100644
--- a/lib/ssl/test/Makefile
+++ b/lib/ssl/test/Makefile
@@ -61,8 +61,10 @@ HRL_FILES = ssl_test_MACHINE.hrl
HRL_FILES_SRC = \
ssl_int.hrl \
+ ssl_internal.hrl\
ssl_alert.hrl \
- ssl_handshake.hrl
+ ssl_handshake.hrl \
+ ssl_record.hrl
HRL_FILES_INC =
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 4f0907027f..37a021e7cf 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -25,11 +25,12 @@
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
--include("test_server_line.hrl").
-include_lib("public_key/include/public_key.hrl").
-include("ssl_alert.hrl").
-include("ssl_int.hrl").
+-include("ssl_internal.hrl").
+-include("ssl_record.hrl").
-define('24H_in_sec', 86400).
-define(TIMEOUT, 60000).
@@ -208,8 +209,12 @@ all() ->
empty_protocol_versions, controlling_process,
controller_dies, client_closes_socket, peercert,
connect_dist, peername, sockname, socket_options,
+ invalid_inet_get_option, invalid_inet_get_option_not_list,
+ invalid_inet_get_option_improper_list,
+ invalid_inet_set_option, invalid_inet_set_option_not_list,
+ invalid_inet_set_option_improper_list,
misc_ssl_options, versions, cipher_suites, upgrade,
- upgrade_with_timeout, tcp_connect, ipv6, ekeyfile,
+ upgrade_with_timeout, tcp_connect, tcp_connect_big, ipv6, ekeyfile,
ecertfile, ecacertfile, eoptions, shutdown,
shutdown_write, shutdown_both, shutdown_error,
ciphers_rsa_signed_certs, ciphers_rsa_signed_certs_ssl3,
@@ -252,7 +257,7 @@ all() ->
%%different_ca_peer_sign,
no_reuses_session_server_restart_new_cert,
no_reuses_session_server_restart_new_cert_file, reuseaddr,
- hibernate
+ hibernate, connect_twice
].
groups() ->
@@ -808,8 +813,218 @@ socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
{ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
ssl:setopts(Socket, [{nodelay, true}]),
{ok,[{nodelay, true}]} = ssl:getopts(Socket, [nodelay]),
+ {ok, All} = ssl:getopts(Socket, []),
+ test_server:format("All opts ~p~n", [All]),
ok.
+
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option(doc) ->
+ ["Test handling of invalid inet options in getopts"];
+
+invalid_inet_get_option(suite) ->
+ [];
+
+invalid_inet_get_option(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, get_invalid_inet_option, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+get_invalid_inet_option(Socket) ->
+ {error, {eoptions, {inet_option, foo, _}}} = ssl:getopts(Socket, [foo]),
+ ok.
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_not_list(doc) ->
+ ["Test handling of invalid type in getopts"];
+
+invalid_inet_get_option_not_list(suite) ->
+ [];
+
+invalid_inet_get_option_not_list(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, get_invalid_inet_option_not_list, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+get_invalid_inet_option_not_list(Socket) ->
+ {error, {eoptions, {inet_options, some_invalid_atom_here}}}
+ = ssl:getopts(Socket, some_invalid_atom_here),
+ ok.
+
+%%--------------------------------------------------------------------
+invalid_inet_get_option_improper_list(doc) ->
+ ["Test handling of invalid type in getopts"];
+
+invalid_inet_get_option_improper_list(suite) ->
+ [];
+
+invalid_inet_get_option_improper_list(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, get_invalid_inet_option_improper_list, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+get_invalid_inet_option_improper_list(Socket) ->
+ {error, {eoptions, {inet_option, foo,_}}} = ssl:getopts(Socket, [packet | foo]),
+ ok.
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option(doc) ->
+ ["Test handling of invalid inet options in setopts"];
+
+invalid_inet_set_option(suite) ->
+ [];
+
+invalid_inet_set_option(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, set_invalid_inet_option, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+set_invalid_inet_option(Socket) ->
+ {error, {eoptions, {inet_opt, {packet, foo}}}} = ssl:setopts(Socket, [{packet, foo}]),
+ {error, {eoptions, {inet_opt, {header, foo}}}} = ssl:setopts(Socket, [{header, foo}]),
+ {error, {eoptions, {inet_opt, {active, foo}}}} = ssl:setopts(Socket, [{active, foo}]),
+ {error, {eoptions, {inet_opt, {mode, foo}}}} = ssl:setopts(Socket, [{mode, foo}]),
+ ok.
+%%--------------------------------------------------------------------
+invalid_inet_set_option_not_list(doc) ->
+ ["Test handling of invalid type in setopts"];
+
+invalid_inet_set_option_not_list(suite) ->
+ [];
+
+invalid_inet_set_option_not_list(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, set_invalid_inet_option_not_list, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+set_invalid_inet_option_not_list(Socket) ->
+ {error, {eoptions, {not_a_proplist, some_invalid_atom_here}}}
+ = ssl:setopts(Socket, some_invalid_atom_here),
+ ok.
+
+%%--------------------------------------------------------------------
+invalid_inet_set_option_improper_list(doc) ->
+ ["Test handling of invalid tye in setopts"];
+
+invalid_inet_set_option_improper_list(suite) ->
+ [];
+
+invalid_inet_set_option_improper_list(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, set_invalid_inet_option_improper_list, []}},
+ {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, []}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+set_invalid_inet_option_improper_list(Socket) ->
+ {error, {eoptions, {not_a_proplist, [{packet, 0} | {foo, 2}]}}} =
+ ssl:setopts(Socket, [{packet, 0} | {foo, 2}]),
+ ok.
+
%%--------------------------------------------------------------------
misc_ssl_options(doc) ->
["Test what happens when we give valid options"];
@@ -1097,6 +1312,41 @@ tcp_connect(Config) when is_list(Config) ->
end
end.
+tcp_connect_big(doc) ->
+ ["Test what happens when a tcp tries to connect, i,e. a bad big (ssl) packet is sent first"];
+
+tcp_connect_big(suite) ->
+ [];
+
+tcp_connect_big(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
+ test_server:format("Testcase ~p connected to Server ~p ~n", [self(), Server]),
+
+ 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>>),
+
+ receive
+ {tcp_closed, Socket} ->
+ receive
+ {Server, {error, timeout}} ->
+ test_server:fail("hangs");
+ {Server, {error, Error}} ->
+ test_server:format("Error ~p", [Error])
+ end
+ end.
dummy(_Socket) ->
%% Should not happen as the ssl connection will not be established
@@ -1659,7 +1909,7 @@ reuse_session(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client0 =
@@ -1681,7 +1931,7 @@ reuse_session(Config) when is_list(Config) ->
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
@@ -1697,7 +1947,7 @@ reuse_session(Config) when is_list(Config) ->
Client2 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, [{reuse_sessions, false}
| ClientOpts]}]),
receive
@@ -1713,7 +1963,7 @@ reuse_session(Config) when is_list(Config) ->
Server1 =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, [{reuse_sessions, false} | ServerOpts]}]),
Port1 = ssl_test_lib:inet_port(Server1),
@@ -1737,7 +1987,7 @@ reuse_session(Config) when is_list(Config) ->
Client4 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port1}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
@@ -1756,9 +2006,6 @@ reuse_session(Config) when is_list(Config) ->
ssl_test_lib:close(Client3),
ssl_test_lib:close(Client4).
-session_info_result(Socket) ->
- ssl:session_info(Socket).
-
%%--------------------------------------------------------------------
reuse_session_expired(doc) ->
["Test sessions is not reused when it has expired"];
@@ -1774,7 +2021,7 @@ reuse_session_expired(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client0 =
@@ -1796,7 +2043,7 @@ reuse_session_expired(Config) when is_list(Config) ->
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
@@ -1815,7 +2062,7 @@ reuse_session_expired(Config) when is_list(Config) ->
Client2 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client2, SessionInfo} ->
@@ -1844,7 +2091,7 @@ server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, [{reuse_session, fun(_,_,_,_) ->
false
end} |
@@ -1870,7 +2117,7 @@ server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
@@ -3179,7 +3426,7 @@ no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client0 =
@@ -3207,7 +3454,7 @@ no_reuses_session_server_restart_new_cert(Config) when is_list(Config) ->
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
@@ -3238,7 +3485,7 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
{from, self()},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{options, NewServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
Client0 =
@@ -3268,7 +3515,7 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) ->
Client1 =
ssl_test_lib:start_client([{node, ClientNode},
{port, Port}, {host, Hostname},
- {mfa, {?MODULE, session_info_result, []}},
+ {mfa, {ssl_test_lib, session_info_result, []}},
{from, self()}, {options, ClientOpts}]),
receive
{Client1, SessionInfo} ->
@@ -3304,6 +3551,7 @@ reuseaddr(Config) when is_list(Config) ->
{options, [{active, false} | ClientOpts]}]),
test_server:sleep(?SLEEP),
ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
Server1 =
ssl_test_lib:start_server([{node, ServerNode}, {port, Port},
@@ -3361,6 +3609,54 @@ hibernate(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+
+connect_twice(doc) ->
+ [""];
+connect_twice(suite) ->
+ [];
+connect_twice(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ClientOpts]}]),
+ Server ! listen,
+
+ {Client1, #sslsocket{}} =
+ ssl_test_lib:start_client([return_socket,
+ {node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{keepalive, true},{active, false}
+ | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:check_result(Server, ok, Client1, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ssl_test_lib:close(Client1).
+
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
@@ -3438,7 +3734,7 @@ session_cache_process_mnesia(suite) ->
session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
-session_cache_process(Type,Config) when is_list(Config) ->
+session_cache_process(_Type,Config) when is_list(Config) ->
reuse_session(Config).
init([Type]) ->
diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl
index a43b9ab586..5ea45018e6 100644
--- a/lib/ssl/test/ssl_session_cache_SUITE.erl
+++ b/lib/ssl/test/ssl_session_cache_SUITE.erl
@@ -26,9 +26,11 @@
-include_lib("common_test/include/ct.hrl").
+-define(DELAY, 500).
-define(SLEEP, 500).
-define(TIMEOUT, 60000).
-define(LONG_TIMEOUT, 600000).
+
-behaviour(ssl_session_cache_api).
%% For the session cache tests
@@ -95,6 +97,16 @@ 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 = test_server:timetrap(?TIMEOUT),
+ 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];
+
init_per_testcase(_TestCase, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
@@ -128,6 +140,10 @@ end_per_testcase(session_cache_process_mnesia, Config) ->
ssl:stop(),
ssl:start(),
end_per_testcase(default_action, Config);
+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) ->
Dog = ?config(watchdog, Config),
case Dog of
@@ -148,7 +164,8 @@ end_per_testcase(_TestCase, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [session_cache_process_list,
+ [session_cleanup,
+ session_cache_process_list,
session_cache_process_mnesia].
groups() ->
@@ -159,7 +176,95 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+%%--------------------------------------------------------------------
+session_cleanup(doc) ->
+ ["Test that sessions are cleand up eventually, so that the session table "
+ "does not grow and grow ..."];
+session_cleanup(suite) ->
+ [];
+session_cleanup(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, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = state(Prop),
+ Cache = element(2, State),
+ SessionTimer = element(6, 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}),
+
+ true = CSession =/= undefined,
+ true = SSession =/= undefined,
+
+ %% Make sure session has expired and been cleaned up
+ check_timer(SessionTimer),
+ test_server:sleep(?DELAY *2), %% Delay time + some extra time
+
+ DelayTimer = get_delay_timer(),
+
+ check_timer(DelayTimer),
+
+ test_server:sleep(?SLEEP), %% Make sure clean has had to run
+
+ undefined = ssl_session_cache:lookup(Cache, {{Hostname, Port}, Id}),
+ undefined = ssl_session_cache:lookup(Cache, {Port, Id}),
+
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+state([{data,[{"State", State}]} | _]) ->
+ State;
+state([_ | Rest]) ->
+ state(Rest).
+
+check_timer(Timer) ->
+ case erlang:read_timer(Timer) of
+ false ->
+ {status, _, _, _} = sys:get_status(whereis(ssl_manager)),
+ ok;
+ Int ->
+ test_server:sleep(Int),
+ check_timer(Timer)
+ end.
+get_delay_timer() ->
+ {status, _, _, StatusInfo} = sys:get_status(whereis(ssl_manager)),
+ [_, _,_, _, Prop] = StatusInfo,
+ State = state(Prop),
+ case element(7, State) of
+ undefined ->
+ test_server:sleep(?SLEEP),
+ get_delay_timer();
+ DelayTimer ->
+ DelayTimer
+ end.
+%%--------------------------------------------------------------------
session_cache_process_list(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -176,7 +281,6 @@ session_cache_process_mnesia(suite) ->
session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
-
%%--------------------------------------------------------------------
%%% Session cache API callbacks
%%--------------------------------------------------------------------
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 40bbdf1dbd..b7916b96eb 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -670,3 +670,6 @@ cipher_result(Socket, Result) ->
Other ->
{unexpected, Other}
end.
+
+session_info_result(Socket) ->
+ ssl:session_info(Socket).
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 0e80e42637..8286201df4 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 4.1.5
+SSL_VSN = 4.1.6
diff --git a/lib/stdlib/doc/src/calendar.xml b/lib/stdlib/doc/src/calendar.xml
index 4876b37127..f8db48e00c 100644
--- a/lib/stdlib/doc/src/calendar.xml
+++ b/lib/stdlib/doc/src/calendar.xml
@@ -75,13 +75,13 @@
<datatypes>
<datatype>
- <name name="t_datetime"/>
+ <name name="datetime"/>
</datatype>
<datatype>
- <name name="t_datetime1970"/>
+ <name name="datetime1970"/>
</datatype>
<datatype>
- <name name="t_date"/>
+ <name name="date"/>
</datatype>
<datatype>
<name name="year"/>
@@ -100,7 +100,7 @@
<name name="day"/>
</datatype>
<datatype>
- <name name="t_time"/>
+ <name name="time"/>
</datatype>
<datatype>
<name name="hour"/>
@@ -118,12 +118,7 @@
<name name="ldom"/>
</datatype>
<datatype>
- <name name="t_now"/>
- <desc><p>See <seealso marker="erts:erlang#now/0">erlang:now/0</seealso>.</p>
- </desc>
- </datatype>
- <datatype>
- <name name="t_yearweeknum"/>
+ <name name="yearweeknum"/>
</datatype>
<datatype>
<name name="weeknum"/>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index d15383c621..e35b5adace 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -438,7 +438,7 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
<fsummary>Initialize process and internal state name and state data.</fsummary>
<type>
<v>Args = term()</v>
- <v>Return = {ok,StateName,StateData} | {ok,StateName,StateData,Timeout}</v>
+ <v>Result = {ok,StateName,StateData} | {ok,StateName,StateData,Timeout}</v>
<v>&nbsp;&nbsp;| {ok,StateName,StateData,hibernate}</v>
<v>&nbsp;&nbsp;| {stop,Reason} | ignore</v>
<v>&nbsp;StateName = atom()</v>
@@ -639,9 +639,9 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
<v>StateName = atom()</v>
<v>StateData = term()</v>
<v>Result = {next_state,NextStateName,NewStateData}</v>
- <v>&nbsp;>&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
- <v>&nbsp;>&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
- <v>&nbsp;>&nbsp;| {stop,Reason,NewStateData}</v>
+ <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,Timeout}</v>
+ <v>&nbsp;&nbsp;| {next_state,NextStateName,NewStateData,hibernate}</v>
+ <v>&nbsp;&nbsp;| {stop,Reason,NewStateData}</v>
<v>&nbsp;NextStateName = atom()</v>
<v>&nbsp;NewStateData = term()</v>
<v>&nbsp;Timeout = int()>0 | infinity</v>
diff --git a/lib/stdlib/doc/src/io.xml b/lib/stdlib/doc/src/io.xml
index af9c75d546..667d758e29 100644
--- a/lib/stdlib/doc/src/io.xml
+++ b/lib/stdlib/doc/src/io.xml
@@ -439,7 +439,7 @@ ok</pre>
<item>
<p>Prints the argument with the <c>string</c> syntax. The
argument is, if no Unicode translation modifier is present, an
- <seealso marker="erts:erlang#iolist_definition">I/O list</seealso>, a binary, or an atom. If the Unicode translation modifier ('t') is in effect, the argument is unicode:chardata(), meaning that binaries are in UTF-8. The characters
+ iolist(), a binary, or an atom. If the Unicode translation modifier ('t') is in effect, the argument is unicode:chardata(), meaning that binaries are in UTF-8. The characters
are printed without quotes. The string is first truncated
by the given precision and then padded and justified
to the given field width. The default precision is the field width.</p>
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index c2676b1de5..60c0b91212 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -30,6 +30,187 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 1.17.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The default value <c>undefined</c> was added to
+ records field types in such a way that the result was not
+ always a well-formed type. This bug has been fixed. </p>
+ <p>
+ Own Id: OTP-9147</p>
+ </item>
+ <item>
+ <p>
+ Update index file atomically</p>
+ <p>
+ Since the log_mf_h index file might be read by other
+ processes than the error handler (e.g. by the rb tool),
+ this file should be updated atomically. This will avoid
+ hitting the time gap between opening the file in write
+ mode (and thus emptying the file) and the actual update
+ with the new contents. To do this, a temporary file is
+ written, and the file:rename/1 used to replace the real
+ index file.</p>
+ <p>
+ Own Id: OTP-9148</p>
+ </item>
+ <item>
+ <p>
+ Fixed various typos across the documentation (Thanks to
+ Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9154</p>
+ </item>
+ <item>
+ <p>
+ Supervisors should not save child-specs for temporary
+ processes when they terminate as they should not be
+ restarted. Saving the temporary child spec will result in
+ that you can not start a new temporary process with the
+ same child spec as an already terminated temporary
+ process. Since R14B02 you can not restart a temporary
+ temporary process as arguments are no longer saved, it
+ has however always been semantically incorrect to restart
+ a temporary process. Thanks to Filipe David Manana for
+ reporting this and suggesting a solution.</p>
+ <p>
+ Own Id: OTP-9167 Aux Id: OTP-9064 </p>
+ </item>
+ <item>
+ <p>
+ Various small documentation fixes (Thanks to Bernard
+ Duggan)</p>
+ <p>
+ Own Id: OTP-9172</p>
+ </item>
+ <item>
+ <p>
+ Fix format_status bug for unregistered gen_event
+ processes</p>
+ <p>
+ Port the gen_fsm code for format_status to gen_event in
+ order to prevent a lists:concat([...,pid()]) crash when
+ calling sys:get_status/1 on an unregistered gen_event
+ process.</p>
+ <p>
+ Refactor format_status header code from gen_* behaviours
+ to module gen.</p>
+ <p>
+ Extend the format_status tests in gen_event_SUITE to
+ cover format_status bugs with anonymous gen_event
+ processes. (Thanks To Geoff Cant)</p>
+ <p>
+ Own Id: OTP-9218</p>
+ </item>
+ <item>
+ <p>
+ List of pids changed to 'set' in supervisor for dynamic
+ temporary children. Accessing the list would not scale
+ well when adding/deleting many children. (Thanks to
+ Evgeniy Khramtsov)</p>
+ <p>
+ Own Id: OTP-9242</p>
+ </item>
+ <item>
+ <p>
+ Change pool module to attempt to attach to nodes that are
+ already running</p>
+ <p>
+ The pool module prints out an error message and takes no
+ further action for nodes that are already running. This
+ patch changes that behavior so that if the return from
+ slave:start/3 is {already_running, Node} then an attempt
+ to attach to the node is still made. This makes sense
+ because the node has been specified by the user in the
+ .hosts.erlang file indicating a wish for the node to be
+ part of the pool and a manual attach can be successfully
+ made after the pool is started.(Thanks to Kelly
+ McLaughlin)</p>
+ <p>
+ Own Id: OTP-9244</p>
+ </item>
+ <item>
+ <p>
+ unicode: document 16#FFFE and 16#FFFF (non chars)(Thanks
+ to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9256</p>
+ </item>
+ <item>
+ <p>
+ re: remove gratuitous "it " in manpage (Thanks to Tuncer
+ Ayaz)</p>
+ <p>
+ Own Id: OTP-9307</p>
+ </item>
+ <item>
+ <p> A bug in erl_eval(3) has been fixed. </p>
+ <p>
+ Own Id: OTP-9322</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Add <c>timer:tc/1</c> and remove the catch in <c>tc/2</c>
+ and <c>tc/3</c>. The time measuring functions will thus
+ no longer trap exits, errors or throws caused by the
+ measured function.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-9169</p>
+ </item>
+ <item>
+ <p>
+ Allow supervisor:terminate_child(SupRef,Pid) for
+ simple_one_for_one supervisors</p>
+ <p>
+ supervisor:terminate_child/2 was earlier not allowed if
+ the supervisor used restart strategy simple_one_for_one.
+ This is now changed so that children of this type of
+ supervisors can be terminated by specifying the child's
+ Pid.</p>
+ <p>
+ (Thanks to Vance Shipley.)</p>
+ <p>
+ Own Id: OTP-9201</p>
+ </item>
+ <item>
+ <p> Types and specifications have been added. </p>
+ <p>
+ Own Id: OTP-9267</p>
+ </item>
+ <item>
+ <p> Erlang types and specifications are used for
+ documentation. </p>
+ <p>
+ Own Id: OTP-9271</p>
+ </item>
+ <item>
+ <p>Allow Dets tablenames to be arbitrary terms.</p>
+ <p>
+ Own Id: OTP-9282</p>
+ </item>
+ <item>
+ <p> A specification that could cause problems for
+ Dialyzer has been fixed. An opaque type in erl_eval has
+ been turned in to a ordinary type. This is a temporary
+ fix. </p>
+ <p>
+ Own Id: OTP-9333</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 1.17.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index 416df1f02c..b48ad8c1f3 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -52,7 +52,7 @@
<tag>UCS-4</tag>
<item>Basically the same as UTF-32, but without some Unicode semantics, defined by IEEE and has little use as a separate encoding standard. For all normal (and possibly abnormal) usages, UTF-32 and UCS-4 are interchangeable.</item>
</taglist>
-<p>Certain ranges of characters are left unused and certain ranges are even deemed invalid. The most notable invalid range is 16#D800 - 16#DFFF, as the UTF-16 encoding does not allow for encoding of these numbers. It can be speculated that the UTF-16 encoding standard was, from the beginning, expected to be able to hold all Unicode characters in one 16-bit entity, but then had to be extended, leaving a whole in the Unicode range to cope with backward compatibility.</p>
+<p>Certain ranges of characters are left unused and certain ranges are even deemed invalid. The most notable invalid range is 16#D800 - 16#DFFF, as the UTF-16 encoding does not allow for encoding of these numbers. It can be speculated that the UTF-16 encoding standard was, from the beginning, expected to be able to hold all Unicode characters in one 16-bit entity, but then had to be extended, leaving a hole in the Unicode range to cope with backward compatibility.</p>
<p>Additionally, the codepoint 16#FEFF is used for byte order marks (BOM's) and use of that character is not encouraged in other contexts than that. It actually is valid though, as the character "ZWNBS" (Zero Width Non Breaking Space). BOM's are used to identify encodings and byte order for programs where such parameters are not known in advance. Byte order marks are more seldom used than one could expect, put their use is becoming more widely spread as they provide the means for programs to make educated guesses about the Unicode format of a certain file.</p>
</section>
<section>
diff --git a/lib/stdlib/src/calendar.erl b/lib/stdlib/src/calendar.erl
index 8d1071209e..0320e0cd0e 100644
--- a/lib/stdlib/src/calendar.erl
+++ b/lib/stdlib/src/calendar.erl
@@ -63,7 +63,7 @@
%% Types
%%----------------------------------------------------------------------
--export_type([t_now/0]).
+-export_type([date/0, time/0, datetime/0, datetime1970/0]).
-type year() :: non_neg_integer().
-type year1970() :: 1970..10000. % should probably be 1970..
@@ -76,15 +76,11 @@
-type ldom() :: 28 | 29 | 30 | 31. % last day of month
-type weeknum() :: 1..53.
--type t_now() :: {MegaSecs :: non_neg_integer(),
- Secs :: non_neg_integer(),
- MicroSecs :: non_neg_integer()}.
-
--type t_date() :: {year(),month(),day()}.
--type t_time() :: {hour(),minute(),second()}.
--type t_datetime() :: {t_date(),t_time()}.
--type t_datetime1970() :: {{year1970(),month(),day()},t_time()}.
--type t_yearweeknum() :: {year(),weeknum()}.
+-type date() :: {year(),month(),day()}.
+-type time() :: {hour(),minute(),second()}.
+-type datetime() :: {date(),time()}.
+-type datetime1970() :: {{year1970(),month(),day()},time()}.
+-type yearweeknum() :: {year(),weeknum()}.
%%----------------------------------------------------------------------
@@ -123,7 +119,7 @@ date_to_gregorian_days(Year, Month, Day) when is_integer(Day), Day > 0 ->
end.
-spec date_to_gregorian_days(Date) -> Days when
- Date :: t_date(),
+ Date :: date(),
Days :: non_neg_integer().
date_to_gregorian_days({Year, Month, Day}) ->
date_to_gregorian_days(Year, Month, Day).
@@ -135,7 +131,7 @@ date_to_gregorian_days({Year, Month, Day}) ->
%% January 1st.
%%
-spec datetime_to_gregorian_seconds(DateTime) -> Seconds when
- DateTime :: t_datetime(),
+ DateTime :: datetime(),
Seconds :: non_neg_integer().
datetime_to_gregorian_seconds({Date, Time}) ->
?SECONDS_PER_DAY*date_to_gregorian_days(Date) +
@@ -155,14 +151,14 @@ day_of_the_week(Year, Month, Day) ->
(date_to_gregorian_days(Year, Month, Day) + 5) rem 7 + 1.
-spec day_of_the_week(Date) -> daynum() when
- Date:: t_date().
+ Date:: date().
day_of_the_week({Year, Month, Day}) ->
day_of_the_week(Year, Month, Day).
%% gregorian_days_to_date(Days) = {Year, Month, Day}
%%
--spec gregorian_days_to_date(Days) -> t_date() when
+-spec gregorian_days_to_date(Days) -> date() when
Days :: non_neg_integer().
gregorian_days_to_date(Days) ->
{Year, DayOfYear} = day_to_year(Days),
@@ -172,7 +168,7 @@ gregorian_days_to_date(Days) ->
%% gregorian_seconds_to_datetime(Secs)
%%
--spec gregorian_seconds_to_datetime(Seconds) -> t_datetime() when
+-spec gregorian_seconds_to_datetime(Seconds) -> datetime() when
Seconds :: non_neg_integer().
gregorian_seconds_to_datetime(Secs) when Secs >= 0 ->
Days = Secs div ?SECONDS_PER_DAY,
@@ -198,7 +194,7 @@ is_leap_year1(_) -> false.
%%
%% Calculates the iso week number for the current date.
%%
--spec iso_week_number() -> t_yearweeknum().
+-spec iso_week_number() -> yearweeknum().
iso_week_number() ->
{Date, _} = local_time(),
iso_week_number(Date).
@@ -207,8 +203,8 @@ iso_week_number() ->
%%
%% Calculates the iso week number for the given date.
%%
--spec iso_week_number(Date) -> t_yearweeknum() when
- Date :: t_date().
+-spec iso_week_number(Date) -> yearweeknum() when
+ Date :: date().
iso_week_number({Year, Month, Day}) ->
D = date_to_gregorian_days({Year, Month, Day}),
W01_1_Year = gregorian_days_of_iso_w01_1(Year),
@@ -260,7 +256,7 @@ last_day_of_the_month1(_, M) when is_integer(M), M > 0, M < 13 ->
%% local_time()
%%
%% Returns: {date(), time()}, date() = {Y, M, D}, time() = {H, M, S}.
--spec local_time() -> t_datetime().
+-spec local_time() -> datetime().
local_time() ->
erlang:localtime().
@@ -268,20 +264,20 @@ local_time() ->
%% local_time_to_universal_time(DateTime)
%%
-spec local_time_to_universal_time(DateTime1) -> DateTime2 when
- DateTime1 :: t_datetime1970(),
- DateTime2 :: t_datetime1970().
+ DateTime1 :: datetime1970(),
+ DateTime2 :: datetime1970().
local_time_to_universal_time(DateTime) ->
erlang:localtime_to_universaltime(DateTime).
--spec local_time_to_universal_time(t_datetime1970(),
+-spec local_time_to_universal_time(datetime1970(),
'true' | 'false' | 'undefined') ->
- t_datetime1970().
+ datetime1970().
local_time_to_universal_time(DateTime, IsDst) ->
erlang:localtime_to_universaltime(DateTime, IsDst).
-spec local_time_to_universal_time_dst(DateTime1) -> [DateTime] when
- DateTime1 :: t_datetime1970(),
- DateTime :: t_datetime1970().
+ DateTime1 :: datetime1970(),
+ DateTime :: datetime1970().
local_time_to_universal_time_dst(DateTime) ->
UtDst = erlang:localtime_to_universaltime(DateTime, true),
Ut = erlang:localtime_to_universaltime(DateTime, false),
@@ -309,14 +305,14 @@ local_time_to_universal_time_dst(DateTime) ->
%% = MilliSec = integer()
%% Returns: {date(), time()}, date() = {Y, M, D}, time() = {H, M, S}.
%%
--spec now_to_datetime(Now) -> t_datetime1970() when
- Now :: t_now().
+-spec now_to_datetime(Now) -> datetime1970() when
+ Now :: erlang:timestamp().
now_to_datetime({MSec, Sec, _uSec}) ->
Sec0 = MSec*1000000 + Sec + ?DAYS_FROM_0_TO_1970*?SECONDS_PER_DAY,
gregorian_seconds_to_datetime(Sec0).
--spec now_to_universal_time(Now) -> t_datetime1970() when
- Now :: t_now().
+-spec now_to_universal_time(Now) -> datetime1970() when
+ Now :: erlang:timestamp().
now_to_universal_time(Now) ->
now_to_datetime(Now).
@@ -325,8 +321,8 @@ now_to_universal_time(Now) ->
%%
%% Args: Now = now()
%%
--spec now_to_local_time(Now) -> t_datetime1970() when
- Now :: t_now().
+-spec now_to_local_time(Now) -> datetime1970() when
+ Now :: erlang:timestamp().
now_to_local_time({MSec, Sec, _uSec}) ->
erlang:universaltime_to_localtime(
now_to_universal_time({MSec, Sec, _uSec})).
@@ -338,7 +334,7 @@ now_to_local_time({MSec, Sec, _uSec}) ->
-spec seconds_to_daystime(Seconds) -> {Days, Time} when
Seconds :: integer(),
Days :: integer(),
- Time :: t_time().
+ Time :: time().
seconds_to_daystime(Secs) ->
Days0 = Secs div ?SECONDS_PER_DAY,
Secs0 = Secs rem ?SECONDS_PER_DAY,
@@ -356,7 +352,7 @@ seconds_to_daystime(Secs) ->
%% Wraps.
%%
-type secs_per_day() :: 0..?SECONDS_PER_DAY.
--spec seconds_to_time(Seconds) -> t_time() when
+-spec seconds_to_time(Seconds) -> time() when
Seconds :: secs_per_day().
seconds_to_time(Secs) when Secs >= 0, Secs < ?SECONDS_PER_DAY ->
Secs0 = Secs rem ?SECONDS_PER_DAY,
@@ -375,10 +371,10 @@ seconds_to_time(Secs) when Secs >= 0, Secs < ?SECONDS_PER_DAY ->
%% Year = Month = Day = Hour = Minute = Sec = integer()
%%
-spec time_difference(T1, T2) -> {Days, Time} when
- T1 :: t_datetime(),
- T2 :: t_datetime(),
+ T1 :: datetime(),
+ T2 :: datetime(),
Days :: integer(),
- Time :: t_time().
+ Time :: time().
time_difference({{Y1, Mo1, D1}, {H1, Mi1, S1}},
{{Y2, Mo2, D2}, {H2, Mi2, S2}}) ->
Secs = datetime_to_gregorian_seconds({{Y2, Mo2, D2}, {H2, Mi2, S2}}) -
@@ -390,7 +386,7 @@ time_difference({{Y1, Mo1, D1}, {H1, Mi1, S1}},
%% time_to_seconds(Time)
%%
-spec time_to_seconds(Time) -> secs_per_day() when
- Time :: t_time().
+ Time :: time().
time_to_seconds({H, M, S}) when is_integer(H), is_integer(M), is_integer(S) ->
H * ?SECONDS_PER_HOUR +
M * ?SECONDS_PER_MINUTE + S.
@@ -399,15 +395,15 @@ time_to_seconds({H, M, S}) when is_integer(H), is_integer(M), is_integer(S) ->
%% universal_time()
%%
%% Returns: {date(), time()}, date() = {Y, M, D}, time() = {H, M, S}.
--spec universal_time() -> t_datetime().
+-spec universal_time() -> datetime().
universal_time() ->
erlang:universaltime().
%% universal_time_to_local_time(DateTime)
%%
--spec universal_time_to_local_time(DateTime) -> t_datetime() when
- DateTime :: t_datetime1970().
+-spec universal_time_to_local_time(DateTime) -> datetime() when
+ DateTime :: datetime1970().
universal_time_to_local_time(DateTime) ->
erlang:universaltime_to_localtime(DateTime).
@@ -429,7 +425,7 @@ valid_date1(_, _, _) ->
false.
-spec valid_date(Date) -> boolean() when
- Date :: t_date().
+ Date :: date().
valid_date({Y, M, D}) ->
valid_date(Y, M, D).
diff --git a/lib/stdlib/src/erl_eval.erl b/lib/stdlib/src/erl_eval.erl
index 46288cf467..515ea2ebb7 100644
--- a/lib/stdlib/src/erl_eval.erl
+++ b/lib/stdlib/src/erl_eval.erl
@@ -43,7 +43,7 @@
-type(name() :: term()).
-type(value() :: term()).
-type(bindings() :: [{name(), value()}]).
--opaque(binding_struct() :: orddict:orddict()).
+-type(binding_struct() :: orddict:orddict()).
-type(lfun_value_handler() :: fun((Name :: atom(),
Arguments :: [term()]) ->
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index 718ca2e91a..10b2ed2e49 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -408,7 +408,12 @@ set_attr(line, {Line,Column}, Fun) when ?ALINE(Line), ?COLUMN(Column) ->
end;
set_attr(line=Tag, Attrs, Fun) when is_list(Attrs) ->
{line,Line} = lists:keyfind(Tag, 1, Attrs),
- lists:keyreplace(Tag, 1, Attrs, {line,Fun(Line)});
+ case lists:keyreplace(Tag, 1, Attrs, {line,Fun(Line)}) of
+ [{line,Ln}] when ?ALINE(Ln) ->
+ Ln;
+ As ->
+ As
+ end;
set_attr(T1, T2, T3) ->
erlang:error(badarg, [T1,T2,T3]).
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index fd85c7aef5..306834e845 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -798,30 +798,10 @@ set_extracted_file_info(Name, #tar_header{mode=Mode, mtime=Mtime}) ->
%% Makes all directories leading up to the file.
-make_dirs(Name, Type) ->
- make_dirs1(filename:split(Name), Type).
-
-make_dirs1([Dir, Next|Rest], Type) ->
- case file:read_file_info(Dir) of
- {ok, #file_info{type=directory}} ->
- make_dirs1([filename:join(Dir, Next)|Rest], Type);
- {ok, #file_info{}} ->
- throw({error, enotdir});
- {error, _} ->
- case file:make_dir(Dir) of
- ok ->
- make_dirs1([filename:join(Dir, Next)|Rest], Type);
- {error, Reason} ->
- throw({error, Reason})
- end
- end;
-make_dirs1([_], file) -> ok;
-make_dirs1([Dir], dir) ->
- file:make_dir(Dir);
-make_dirs1([], _) ->
- %% There must be something wrong here. The list was not supposed
- %% to be empty.
- throw({error, enoent}).
+make_dirs(Name, file) ->
+ filelib:ensure_dir(Name);
+make_dirs(Name, dir) ->
+ filelib:ensure_dir(filename:join(Name,"*")).
%% Prints the message on if the verbose option is given (for reading).
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 54c7283abf..165e03e506 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -100,7 +100,7 @@ fwrite(Format, Args) ->
-spec fread(Format, String) -> Result when
Format :: string(),
String :: string(),
- Result :: {'ok', InputList :: chars(), LeftOverChars :: string()}
+ Result :: {'ok', InputList :: [term()], LeftOverChars :: string()}
| {'more', RestFormat :: string(),
Nchars :: non_neg_integer(),
InputStack :: chars()}
@@ -115,7 +115,7 @@ fread(Chars, Format) ->
Format :: string(),
Return :: {'more', Continuation1 :: continuation()}
| {'done', Result, LeftOverChars :: string()},
- Result :: {'ok', InputList :: chars()}
+ Result :: {'ok', InputList :: [term()]}
| 'eof'
| {'error', What :: term()}.
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 52aa4d073c..ded1346097 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -24,6 +24,10 @@
-import(lists, [reverse/1,reverse/2]).
+-define(is_whitespace(C),
+ ((C) =:= $\s orelse (C) =:= $\t
+ orelse (C) =:= $\r orelse (C) =:= $\n)).
+
%%-----------------------------------------------------------------------
%% fread(Continuation, CharList, FormatString)
@@ -106,31 +110,27 @@ fread_line(Format0, Line, N0, Results0, More, Newline) ->
fread(Format, Line) ->
fread(Format, Line, 0, []).
-fread([$~|Format0], Line, N, Results) ->
+fread([$~|Format0]=AllFormat, Line, N, Results) ->
{Format,F,Sup,Unicode} = fread_field(Format0),
- fread1(Format, F, Sup, Unicode, Line, N, Results, Format0);
-fread([$\s|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\t|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\r|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\n|Format], Line, N, Results) ->
+ fread1(Format, F, Sup, Unicode, Line, N, Results, AllFormat);
+fread([C|Format], Line, N, Results) when ?is_whitespace(C) ->
fread_skip_white(Format, Line, N, Results);
fread([C|Format], [C|Line], N, Results) ->
fread(Format, Line, N+1, Results);
fread([_F|_Format], [_C|_Line], _N, _Results) ->
fread_error(input);
+fread([_|_]=Format, [], N, Results) ->
+ {more,Format,N,Results};
+fread([_|_], eof, 0, []) ->
+ %% This is at start of input so no error.
+ eof;
+fread([_|_], eof, _N, _Results) ->
+ %% This is an error as there is no more input.
+ fread_error(input);
fread([], Line, _N, Results) ->
{ok,reverse(Results),Line}.
-fread_skip_white(Format, [$\s|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\t|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\r|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\n|Line], N, Results) ->
+fread_skip_white(Format, [C|Line], N, Results) when ?is_whitespace(C) ->
fread_skip_white(Format, Line, N+1, Results);
fread_skip_white(Format, Line, N, Results) ->
fread(Format, Line, N, Results).
@@ -166,9 +166,9 @@ fread1([$l|Format], _F, Sup, _U, Line, N, Res, _AllFormat) ->
fread(Format, Line, N, fread_result(Sup, N, Res));
fread1(_Format, _F, _Sup, _U, [], N, Res, AllFormat) ->
%% Need more input here.
- {more,[$~|AllFormat],N,Res};
-fread1(_Format, _F, _Sup, _U, eof, _N, [], _AllFormat) ->
- %% This is at start of format string so no error.
+ {more,AllFormat,N,Res};
+fread1(_Format, _F, _Sup, _U, eof, 0, [], _AllFormat) ->
+ %% This is at start of input so no error.
eof;
fread1(_Format, _F, _Sup, _U, eof, _N, _Res, _AllFormat) ->
%% This is an error as there is no more input.
@@ -386,26 +386,16 @@ fread_string_cs(Line0, N0, true) ->
%% fread_digits(Line, N, Base, Characters)
%% Read segments of things, return "thing" characters in reverse order.
-fread_skip_white([$\s|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\t|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\r|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\n|Line]) -> fread_skip_white(Line);
+fread_skip_white([C|Line]) when ?is_whitespace(C) ->
+ fread_skip_white(Line);
fread_skip_white(Line) -> Line.
-fread_skip_white([$\s|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\t|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\r|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\n|Line], N) ->
+fread_skip_white([C|Line], N) when ?is_whitespace(C) ->
fread_skip_white(Line, N+1);
fread_skip_white(Line, N) -> {Line,N}.
-fread_skip_latin1_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\n|Line], N, Cs) -> {[$\n|Line],N,Cs};
+fread_skip_latin1_nonwhite([C|Line], N, Cs) when ?is_whitespace(C) ->
+ {[C|Line],N,Cs};
fread_skip_latin1_nonwhite([C|Line], N, []) when C > 255 ->
{[C|Line],N,error};
fread_skip_latin1_nonwhite([C|Line], N, Cs) when C > 255 ->
@@ -414,10 +404,8 @@ fread_skip_latin1_nonwhite([C|Line], N, Cs) ->
fread_skip_latin1_nonwhite(Line, N+1, [C|Cs]);
fread_skip_latin1_nonwhite([], N, Cs) -> {[],N,Cs}.
-fread_skip_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
-fread_skip_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
-fread_skip_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};
-fread_skip_nonwhite([$\n|Line], N, Cs) -> {[$\n|Line],N,Cs};
+fread_skip_nonwhite([C|Line], N, Cs) when ?is_whitespace(C) ->
+ {[C|Line],N,Cs};
fread_skip_nonwhite([C|Line], N, Cs) ->
fread_skip_nonwhite(Line, N+1, [C|Cs]);
fread_skip_nonwhite([], N, Cs) -> {[],N,Cs}.
diff --git a/lib/stdlib/src/queue.erl b/lib/stdlib/src/queue.erl
index 4c6b4d710b..afe917b151 100644
--- a/lib/stdlib/src/queue.erl
+++ b/lib/stdlib/src/queue.erl
@@ -56,16 +56,14 @@
new() -> {[],[]}. %{RearList,FrontList}
%% O(1)
--spec is_queue(Term) -> boolean() when
- Term :: term().
+-spec is_queue(Term :: term()) -> boolean().
is_queue({R,F}) when is_list(R), is_list(F) ->
true;
is_queue(_) ->
false.
%% O(1)
--spec is_empty(Q) -> boolean() when
- Q :: queue().
+-spec is_empty(Q :: queue()) -> boolean().
is_empty({[],[]}) ->
true;
is_empty({In,Out}) when is_list(In), is_list(Out) ->
@@ -74,16 +72,14 @@ is_empty(Q) ->
erlang:error(badarg, [Q]).
%% O(len(Q))
--spec len(Q) -> non_neg_integer() when
- Q :: queue().
+-spec len(Q :: queue()) -> non_neg_integer().
len({R,F}) when is_list(R), is_list(F) ->
length(R)+length(F);
len(Q) ->
erlang:error(badarg, [Q]).
%% O(len(Q))
--spec to_list(Q) -> list() when
- Q :: queue().
+-spec to_list(Q :: queue()) -> list().
to_list({In,Out}) when is_list(In), is_list(Out) ->
Out++lists:reverse(In, []);
to_list(Q) ->
@@ -92,8 +88,7 @@ to_list(Q) ->
%% Create queue from list
%%
%% O(length(L))
--spec from_list(L) -> queue() when
- L :: list().
+-spec from_list(L :: list()) -> queue().
from_list(L) when is_list(L) ->
f2r(L);
from_list(L) ->
@@ -102,9 +97,7 @@ from_list(L) ->
%% Return true or false depending on if element is in queue
%%
%% O(length(Q)) worst case
--spec member(Item, Q) -> boolean() when
- Item :: term(),
- Q :: queue().
+-spec member(Item :: term(), Q :: queue()) -> boolean().
member(X, {R,F}) when is_list(R), is_list(F) ->
lists:member(X, R) orelse lists:member(X, F);
member(X, Q) ->
@@ -117,10 +110,7 @@ member(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in(Item, Q1) -> Q2 when
- Item :: term(),
- Q1 :: queue(),
- Q2 :: queue().
+-spec in(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
in(X, {[_]=In,[]}) ->
{[X], In};
in(X, {In,Out}) when is_list(In), is_list(Out) ->
@@ -132,10 +122,7 @@ in(X, Q) ->
%% Put at least one element in each list, if it is cheap
%%
%% O(1)
--spec in_r(Item, Q1) -> Q2 when
- Item :: term(),
- Q1 :: queue(),
- Q2 :: queue().
+-spec in_r(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
in_r(X, {[],[_]=F}) ->
{F,[X]};
in_r(X, {R,F}) when is_list(R), is_list(F) ->
@@ -146,10 +133,9 @@ in_r(X, Q) ->
%% Take from head/front
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out(Q1) -> Result when
- Q1 :: queue(),
- Q2 :: queue(),
- Result :: {{value, Item :: term()}, Q2} | {empty, Q1}.
+-spec out(Q1 :: queue()) ->
+ {{value, Item :: term()}, Q2 :: queue()} |
+ {empty, Q1 :: queue()}.
out({[],[]}=Q) ->
{empty,Q};
out({[V],[]}) ->
@@ -167,10 +153,9 @@ out(Q) ->
%% Take from tail/rear
%%
%% O(1) amortized, O(len(Q)) worst case
--spec out_r(Q1) -> Result when
- Q1 :: queue(),
- Q2 :: queue(),
- Result :: {{value, Item :: term()}, Q2} | {empty, Q1}.
+-spec out_r(Q1 :: queue()) ->
+ {{value, Item :: term()}, Q2 :: queue()} |
+ {empty, Q1 :: queue()}.
out_r({[],[]}=Q) ->
{empty,Q};
out_r({[],[V]}) ->
@@ -191,9 +176,7 @@ out_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get(Q) -> Item when
- Q :: queue(),
- Item :: term().
+-spec get(Q :: queue()) -> Item :: term().
get({[],[]}=Q) ->
erlang:error(empty, [Q]);
get({R,F}) when is_list(R), is_list(F) ->
@@ -212,9 +195,7 @@ get([_|R], []) -> % malformed queue -> O(len(Q))
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec get_r(Q) -> Item when
- Q :: queue(),
- Item :: term().
+-spec get_r(Q :: queue()) -> Item :: term().
get_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
get_r({[H|_],F}) when is_list(F) ->
@@ -229,9 +210,7 @@ get_r(Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek(Q) -> 'empty' | {'value',Item} when
- Q :: queue(),
- Item :: term().
+-spec peek(Q :: queue()) -> empty | {value,Item :: term()}.
peek({[],[]}) ->
empty;
peek({R,[H|_]}) when is_list(R) ->
@@ -246,9 +225,7 @@ peek(Q) ->
%% Return the last element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec peek_r(Q) -> 'empty' | {'value',Item} when
- Q :: queue(),
- Item :: term().
+-spec peek_r(Q :: queue()) -> empty | {value,Item :: term()}.
peek_r({[],[]}) ->
empty;
peek_r({[H|_],F}) when is_list(F) ->
@@ -263,9 +240,7 @@ peek_r(Q) ->
%% Remove the first element and return resulting queue
%%
%% O(1) amortized
--spec drop(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec drop(Q1 :: queue()) -> Q2 :: queue().
drop({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop({[_],[]}) ->
@@ -283,9 +258,7 @@ drop(Q) ->
%% Remove the last element and return resulting queue
%%
%% O(1) amortized
--spec drop_r(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec drop_r(Q1 :: queue()) -> Q2 :: queue().
drop_r({[],[]}=Q) ->
erlang:error(empty, [Q]);
drop_r({[],[_]}) ->
@@ -306,9 +279,7 @@ drop_r(Q) ->
%% Return reversed queue
%%
%% O(1)
--spec reverse(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec reverse(Q1 :: queue()) -> Q2 :: queue().
reverse({R,F}) when is_list(R), is_list(F) ->
{F,R};
reverse(Q) ->
@@ -318,10 +289,7 @@ reverse(Q) ->
%%
%% Q2 empty: O(1)
%% else: O(len(Q1))
--spec join(Q1, Q2) -> Q3 when
- Q1 :: queue(),
- Q2 :: queue(),
- Q3 :: queue().
+-spec join(Q1 :: queue(), Q2 :: queue()) -> Q3 :: queue().
join({R,F}=Q, {[],[]}) when is_list(R), is_list(F) ->
Q;
join({[],[]}, {R,F}=Q) when is_list(R), is_list(F) ->
@@ -335,11 +303,8 @@ join(Q1, Q2) ->
%%
%% N = 0..len(Q)
%% O(max(N, len(Q)))
--spec split(N, Q1) -> {Q2,Q3} when
- N :: non_neg_integer(),
- Q1 :: queue(),
- Q2 :: queue(),
- Q3 :: queue().
+-spec split(N :: non_neg_integer(), Q1 :: queue()) ->
+ {Q2 :: queue(),Q3 :: queue()}.
split(0, {R,F}=Q) when is_list(R), is_list(F) ->
{{[],[]},Q};
split(N, {R,F}=Q) when is_integer(N), N >= 1, is_list(R), is_list(F) ->
@@ -380,10 +345,8 @@ split_r1_to_f2(N, [X|R1], F1, R2, F2) ->
%%
%% Fun(_) -> List: O(length(List) * len(Q))
%% else: O(len(Q)
--spec filter(Fun, Q1) -> Q2 when
- Fun :: fun((Item :: term()) -> boolean() | list()),
- Q1 :: queue(),
- Q2 :: queue().
+-spec filter(Fun, Q1 :: queue()) -> Q2 :: queue() when
+ Fun :: fun((Item :: term()) -> boolean() | list()).
filter(Fun, {R0,F0}) when is_function(Fun, 1), is_list(R0), is_list(F0) ->
F = filter_f(Fun, F0),
R = filter_r(Fun, R0),
@@ -459,10 +422,7 @@ filter_r(Fun, [X|R0]) ->
%% Cons to head
%%
--spec cons(Item, Q1) -> Q2 when
- Item :: term(),
- Q1 :: queue(),
- Q2 :: queue().
+-spec cons(Item :: term(), Q1 :: queue()) -> Q2 :: queue().
cons(X, Q) ->
in_r(X, Q).
@@ -471,9 +431,7 @@ cons(X, Q) ->
%% Return the first element in the queue
%%
%% O(1) since the queue is supposed to be well formed
--spec head(Q) -> Item when
- Q :: queue(),
- Item :: term().
+-spec head(Q :: queue()) -> Item :: term().
head({[],[]}=Q) ->
erlang:error(empty, [Q]);
head({R,F}) when is_list(R), is_list(F) ->
@@ -483,9 +441,7 @@ head(Q) ->
%% Remove head element and return resulting queue
%%
--spec tail(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec tail(Q1 :: queue()) -> Q2 :: queue().
tail(Q) ->
drop(Q).
@@ -493,35 +449,22 @@ tail(Q) ->
%% Cons to tail
%%
--spec snoc(Q1, Item) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue(),
- Item :: term().
+-spec snoc(Q1 :: queue(), Item :: term()) -> Q2 :: queue().
snoc(Q, X) ->
in(X, Q).
%% Return last element
--spec daeh(Q) -> Item when
- Q :: queue(),
- Item :: term().
+-spec daeh(Q :: queue()) -> Item :: term().
daeh(Q) -> get_r(Q).
--spec last(Q) -> Item when
- Q :: queue(),
- Item :: term().
+-spec last(Q :: queue()) -> Item :: term().
last(Q) -> get_r(Q).
%% Remove last element and return resulting queue
--spec liat(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec liat(Q1 :: queue()) -> Q2 :: queue().
liat(Q) -> drop_r(Q).
--spec lait(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec lait(Q1 :: queue()) -> Q2 :: queue().
lait(Q) -> drop_r(Q). %% Oops, mis-spelled 'tail' reversed. Forget this one.
--spec init(Q1) -> Q2 when
- Q1 :: queue(),
- Q2 :: queue().
+-spec init(Q1 :: queue()) -> Q2 :: queue().
init(Q) -> drop_r(Q).
%%--------------------------------------------------------------------------
diff --git a/lib/stdlib/src/slave.erl b/lib/stdlib/src/slave.erl
index d79ee676d9..de0179da59 100644
--- a/lib/stdlib/src/slave.erl
+++ b/lib/stdlib/src/slave.erl
@@ -72,7 +72,7 @@ start_pseudo(_,_,_) -> ok. %% It's already there
%% This relay can be used to relay all messages directed to a process.
--spec relay(Pid) -> none() when
+-spec relay(Pid) -> no_return() when
Pid :: pid().
relay({badrpc,Reason}) ->
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index 89fae05e4f..689e42051f 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.erl
@@ -199,9 +199,9 @@ tc(M, F, A) ->
%% Calculate the time difference (in microseconds) of two
%% erlang:now() timestamps, T2-T1.
%%
--spec now_diff(T1, T2) -> Tdiff when
- T1 :: calendar:t_now(),
- T2 :: calendar:t_now(),
+-spec now_diff(T2, T1) -> Tdiff when
+ T1 :: erlang:timestamp(),
+ T2 :: erlang:timestamp(),
Tdiff :: integer().
now_diff({A2, B2, C2}, {A1, B1, C1}) ->
((A2-A1)*1000000 + B2-B1)*1000000 + C2-C1.
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index 524d709431..c82c8159b6 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -223,7 +223,7 @@ openzip_open(F, Options) ->
do_openzip_open(F, Options) ->
Opts = get_openzip_options(Options),
#openzip_opts{output = Output, open_opts = OpO, cwd = CWD} = Opts,
- Input = get_zip_input(F),
+ Input = get_input(F),
In0 = Input({open, F, OpO -- [write]}, []),
{[#zip_comment{comment = C} | Files], In1} =
get_central_dir(In0, fun raw_file_info_etc/5, Input),
@@ -489,7 +489,7 @@ do_list_dir(F, Options) ->
%% Print zip directory in short form
-spec(t(Archive) -> ok when
- Archive :: file:name() | binary | ZipHandle,
+ Archive :: file:name() | binary() | ZipHandle,
ZipHandle :: pid()).
t(F) when is_pid(F) -> zip_t(F);
@@ -513,7 +513,7 @@ do_t(F, RawPrint) ->
%% Print zip directory in long form (like ls -l)
-spec(tt(Archive) -> ok when
- Archive :: file:name() | binary | ZipHandle,
+ Archive :: file:name() | binary() | ZipHandle,
ZipHandle :: pid()).
tt(F) when is_pid(F) -> zip_tt(F);
@@ -1174,7 +1174,7 @@ zip_get(Pid) when is_pid(Pid) ->
zip_close(Pid) when is_pid(Pid) ->
request(self(), Pid, close).
--spec(zip_get(FileName, ZipHandle) -> {ok, [Result]} | {error, Reason} when
+-spec(zip_get(FileName, ZipHandle) -> {ok, Result} | {error, Reason} when
FileName :: file:name(),
ZipHandle :: pid(),
Result :: file:name() | {file:name(), binary()},
@@ -1183,7 +1183,7 @@ zip_close(Pid) when is_pid(Pid) ->
zip_get(FileName, Pid) when is_pid(Pid) ->
request(self(), Pid, {get, FileName}).
--spec(zip_list_dir(ZipHandle) -> Result | {error, Reason} when
+-spec(zip_list_dir(ZipHandle) -> {ok, Result} | {error, Reason} when
Result :: [zip_comment() | zip_file()],
ZipHandle :: pid(),
Reason :: term()).
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index 31a4f94294..4298b2c701 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -737,6 +737,10 @@ set_attribute() ->
(catch {foo, erl_scan:set_attribute(line, [], F2)}), % type error
?line {'EXIT',{badarg,_}} =
(catch {foo, erl_scan:set_attribute(column, [], F2)}), % type error
+
+ %% OTP-9412
+ ?line 8 = erl_scan:set_attribute(line, [{line,{nos,'X',8}}],
+ fun({nos,_V,VL}) -> VL end),
ok.
column_errors() ->
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 9d348b5f1a..9341300f90 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -72,6 +72,7 @@
exit_many_many_tables_owner/1]).
-export([write_concurrency/1, heir/1, give_away/1, setopts/1]).
-export([bad_table/1, types/1]).
+-export([otp_9423/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Convenience for manual testing
@@ -143,7 +144,8 @@ all() ->
otp_8166, exit_large_table_owner,
exit_many_large_table_owner, exit_many_tables_owner,
exit_many_many_tables_owner, write_concurrency, heir,
- give_away, setopts, bad_table, types].
+ give_away, setopts, bad_table, types,
+ otp_9423].
groups() ->
[{new, [],
@@ -5420,7 +5422,39 @@ types_do(Opts) ->
?line verify_etsmem(EtsMem).
-
+otp_9423(doc) -> ["vm-deadlock caused by race between ets:delete and others on write_concurrency table"];
+otp_9423(Config) when is_list(Config) ->
+ InitF = fun(_) -> {0,0} end,
+ ExecF = fun({S,F}) ->
+ receive
+ stop ->
+ io:format("~p got stop\n", [self()]),
+ [end_of_work | {"Succeded=",S,"Failed=",F}]
+ after 0 ->
+ %%io:format("~p (~p) doing lookup\n", [self(), {S,F}]),
+ try ets:lookup(otp_9423, key) of
+ [] -> {S+1,F}
+ catch
+ error:badarg -> {S,F+1}
+ end
+ end
+ end,
+ FiniF = fun(R) -> R end,
+ case run_workers(InitF, ExecF, FiniF, infinite, 1) of
+ Pids when is_list(Pids) ->
+ %%[P ! start || P <- Pids],
+ repeat(fun() -> ets:new(otp_9423, [named_table, public, {write_concurrency,true}]),
+ ets:delete(otp_9423)
+ end, 10000),
+ [P ! stop || P <- Pids],
+ wait_pids(Pids),
+ ok;
+
+ Skipped -> Skipped
+ end.
+
+
+
%
% Utility functions:
@@ -5434,21 +5468,30 @@ add_lists([E1|T1], [E2|T2], Acc) ->
add_lists(T1, T2, [E1+E2 | Acc]).
run_workers(InitF,ExecF,FiniF,Laps) ->
+ run_workers(InitF,ExecF,FiniF,Laps, 0).
+run_workers(InitF,ExecF,FiniF,Laps, Exclude) ->
case erlang:system_info(smp_support) of
true ->
- run_workers_do(InitF,ExecF,FiniF,Laps);
+ run_workers_do(InitF,ExecF,FiniF,Laps, Exclude);
false ->
{skipped,"No smp support"}
end.
-
+
run_workers_do(InitF,ExecF,FiniF,Laps) ->
- NumOfProcs = erlang:system_info(schedulers),
+ run_workers_do(InitF,ExecF,FiniF,Laps, 0).
+run_workers_do(InitF,ExecF,FiniF,Laps, Exclude) ->
+ ?line NumOfProcs = case erlang:system_info(schedulers) of
+ N when (N > Exclude) -> N - Exclude
+ end,
io:format("smp starting ~p workers\n",[NumOfProcs]),
Seeds = [{ProcN,random:uniform(9999)} || ProcN <- lists:seq(1,NumOfProcs)],
Parent = self(),
Pids = [spawn_link(fun()-> worker(Seed,InitF,ExecF,FiniF,Laps,Parent,NumOfProcs) end)
|| Seed <- Seeds],
- wait_pids(Pids).
+ case Laps of
+ infinite -> Pids;
+ _ -> wait_pids(Pids)
+ end.
worker({ProcN,Seed}, InitF, ExecF, FiniF, Laps, Parent, NumOfProcs) ->
io:format("smp worker ~p, seed=~p~n",[self(),Seed]),
@@ -5463,6 +5506,8 @@ worker_loop(0, _, State) ->
State;
worker_loop(_, _, [end_of_work|State]) ->
State;
+worker_loop(infinite, ExecF, State) ->
+ worker_loop(infinite,ExecF,ExecF(State));
worker_loop(N, ExecF, State) ->
worker_loop(N-1,ExecF,ExecF(State)).
@@ -5517,20 +5562,21 @@ etsmem() ->
case erlang:system_info({allocator,ets_alloc}) of
false -> undefined;
MemInfo ->
- MSBCS = lists:foldl(
- fun ({instance, _, L}, Acc) ->
- {value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
- {value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
- [MBCS,SBCS | Acc]
- end,
- [],
- MemInfo),
+ CS = lists:foldl(
+ fun ({instance, _, L}, Acc) ->
+ {value,{_,SBMBCS}} = lists:keysearch(sbmbcs, 1, L),
+ {value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
+ {value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
+ [SBMBCS,MBCS,SBCS | Acc]
+ end,
+ [],
+ MemInfo),
lists:foldl(
fun(L, {Bl0,BlSz0}) ->
{value,{_,Bl,_,_}} = lists:keysearch(blocks, 1, L),
{value,{_,BlSz,_,_}} = lists:keysearch(blocks_size, 1, L),
{Bl0+Bl,BlSz0+BlSz}
- end, {0,0}, MSBCS)
+ end, {0,0}, CS)
end},
{Mem,AllTabs}.
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 54a98985cd..bb02a879c2 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -27,7 +27,7 @@
otp_6282/1, otp_6354/1, otp_6495/1, otp_6517/1, otp_6502/1,
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_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1]).
%-define(debug, true).
@@ -62,7 +62,7 @@ all() ->
otp_6282, otp_6354, otp_6495, otp_6517, otp_6502,
manpage, otp_6708, otp_7084, otp_7421,
io_lib_collect_line_3_wb, cr_whitespace_in_string,
- io_fread_newlines, otp_8989].
+ io_fread_newlines, otp_8989, io_lib_fread_literal].
groups() ->
[].
@@ -1995,3 +1995,29 @@ otp_8989(Suite) when is_list(Suite) ->
?line "Hel " = fmt("~-4.*s", [3,Hello]),
?line "Hel " = fmt("~*.*s", [-4,3,Hello]),
ok.
+
+io_lib_fread_literal(doc) ->
+ "OTP-9439 io_lib:fread bug for literate at end";
+io_lib_fread_literal(Suite) when is_list(Suite) ->
+ ?line {more,"~d",0,""} = io_lib:fread("~d", ""),
+ ?line {error,{fread,integer}} = io_lib:fread("~d", " "),
+ ?line {more,"~d",1,""} = io_lib:fread(" ~d", " "),
+ ?line {ok,[17],"X"} = io_lib:fread(" ~d", " 17X"),
+ %%
+ ?line {more,"d",0,""} = io_lib:fread("d", ""),
+ ?line {error,{fread,input}} = io_lib:fread("d", " "),
+ ?line {more,"d",1,""} = io_lib:fread(" d", " "),
+ ?line {ok,[],"X"} = io_lib:fread(" d", " dX"),
+ %%
+ ?line {done,eof,_} = io_lib:fread([], eof, "~d"),
+ ?line {done,eof,_} = io_lib:fread([], eof, " ~d"),
+ ?line {more,C1} = io_lib:fread([], " \n", " ~d"),
+ ?line {done,{error,{fread,input}},_} = io_lib:fread(C1, eof, " ~d"),
+ ?line {done,{ok,[18]},""} = io_lib:fread(C1, "18\n", " ~d"),
+ %%
+ ?line {done,eof,_} = io_lib:fread([], eof, "d"),
+ ?line {done,eof,_} = io_lib:fread([], eof, " d"),
+ ?line {more,C2} = io_lib:fread([], " \n", " d"),
+ ?line {done,{error,{fread,input}},_} = io_lib:fread(C2, eof, " d"),
+ ?line {done,{ok,[]},[]} = io_lib:fread(C2, "d\n", " d"),
+ ok.
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index c79a5002fb..ff5e4c629a 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -114,10 +114,9 @@ end_per_group(_GroupName, Config) ->
Config.
init_per_testcase(count_children_memory, Config) ->
- MemoryState = erlang:system_info(allocator),
- case count_children_allocator_test(MemoryState) of
- true -> Config;
- false ->
+ try erlang:memory() of
+ _ -> Config
+ catch error:notsup ->
{skip, "+Meamin used during test; erlang:memory/1 not available"}
end;
init_per_testcase(_Case, Config) ->
@@ -1032,17 +1031,6 @@ count_children_memory(Config) when is_list(Config) ->
[terminate(SupPid, Pid, child, kill) || {undefined, Pid, worker, _Modules} <- Children3],
[1,0,0,0] = get_child_counts(sup_test).
-count_children_allocator_test(MemoryState) ->
- Allocators = [temp_alloc, eheap_alloc, binary_alloc, ets_alloc,
- driver_alloc, sl_alloc, ll_alloc, fix_alloc, std_alloc,
- sys_alloc],
- MemoryStateList = element(4, MemoryState),
- AllocTypes = [lists:keyfind(Alloc, 1, MemoryStateList)
- || Alloc <- Allocators],
- AllocStates = [lists:keyfind(e, 1, AllocValue)
- || {_Type, AllocValue} <- AllocTypes],
- lists:all(fun(State) -> State == {e, true} end, AllocStates).
-
%%-------------------------------------------------------------------------
do_not_save_start_parameters_for_temporary_children(doc) ->
["Temporary children shall not be restarted so they should not "
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index d5f2cd52d4..7233c061ef 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -375,7 +375,8 @@ zip_options(Config) when is_list(Config) ->
ok = file:set_cwd(?config(data_dir, Config)),
%% Create a zip archive
- {ok, Zip} = zip:zip("filename_not_used.zip", Names, [memory, {cwd, PrivDir}]),
+ {ok, {_,Zip}} =
+ zip:zip("filename_not_used.zip", Names, [memory, {cwd, PrivDir}]),
%% Open archive
{ok, ZipSrv} = zip:zip_open(Zip, [memory]),
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index c0956030cf..9d4ed17774 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 1.17.4
+STDLIB_VSN = 1.17.5
diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml
index 3f5eb7231e..ec2dd762b8 100644
--- a/lib/syntax_tools/doc/src/notes.xml
+++ b/lib/syntax_tools/doc/src/notes.xml
@@ -31,6 +31,25 @@
<p>This document describes the changes made to the Syntax_Tools
application.</p>
+<section><title>Syntax_Tools 1.6.7.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> In a file containing declarations and comments
+ without any empty lines between them, the
+ <c>recomment_forms()</c> function would associate a
+ multi-line comment with the declaration above it rather
+ than the one following it. (Thanks to Richard Carlsson
+ and Kostis Sagonas.) </p>
+ <p>
+ Own Id: OTP-9180</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Syntax_Tools 1.6.7</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk
index 2e23f6aef9..cc7ea944f9 100644
--- a/lib/syntax_tools/vsn.mk
+++ b/lib/syntax_tools/vsn.mk
@@ -1 +1 @@
-SYNTAX_TOOLS_VSN = 1.6.7
+SYNTAX_TOOLS_VSN = 1.6.7.1
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index 3a10bb209d..50923b1b03 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -32,6 +32,65 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.4.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ It was previously not possible to use timetrap value
+ 'infinity' with ct:timetrap/1. This has been fixed.</p>
+ <p>
+ Own Id: OTP-9159</p>
+ </item>
+ <item>
+ <p>
+ A bug that made it impossible to cancel the previous
+ timetrap when calling ct:timetrap/1 has been corrected.</p>
+ <p>
+ Own Id: OTP-9233 Aux Id: OTP-9159 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ When running tests with auto-compilation disabled, Common
+ Test could only display the test suite source code on
+ html format in the test case log if the source file was
+ located in the same directory as the pre-compiled suite.
+ This has been modified so that Common Test now tries to
+ locate the source file by means of the test suite module
+ info (Suite:module_info/1). As a result, a suite may now
+ be compiled to a different output directory (e.g.
+ $MYTEST/bin) than the source code directory (e.g.
+ $MYTEST/src), without the source-code-to-html generation
+ being affected.</p>
+ <p>
+ Own Id: OTP-9138</p>
+ </item>
+ <item>
+ <p>
+ It is now possible to return a tuple {fail,Reason} from
+ init_per_testcase/2. The result is that the associated
+ test case gets logged as failed without ever executing.</p>
+ <p>
+ Own Id: OTP-9160 Aux Id: seq11502 </p>
+ </item>
+ <item>
+ <p>
+ Added DragonflyBSD check in test_server configure.</p>
+ <p>
+ Own Id: OTP-9249</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.4.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in
index ff4ba1dfaf..097853bcfc 100644
--- a/lib/test_server/src/configure.in
+++ b/lib/test_server/src/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script for Erlang.
dnl
dnl %CopyrightBegin%
dnl
-dnl Copyright Ericsson AB 1997-2009. All Rights Reserved.
+dnl Copyright Ericsson AB 1997-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
diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl
index 8332ccfb40..9703478f20 100644
--- a/lib/test_server/src/ts_install.erl
+++ b/lib/test_server/src/ts_install.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index b7c0987845..1dd4a84ce9 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.4.3
+TEST_SERVER_VSN = 3.4.4
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 93bb6b71c9..02d92fc4e7 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,73 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.6.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Change make:files to behave more like erlc</p>
+ <p>
+ This change removes the unnecessary checks on the files
+ when make:files is called and allows the error checking
+ to be done in compile:file, where the error messages are
+ produced. It does not affect the return value.</p>
+ <p>
+ (Thanks to Sam bobroff)</p>
+ <p>
+ Own Id: OTP-9179</p>
+ </item>
+ <item>
+ <p>
+ add user specified compiler options on form reloading</p>
+ <p>
+ In order to be able to test non-exported functions from
+ another (test) module it is necessary to compile the
+ specific module (at least during the test phase) with the
+ export_all compiler option. This allows complete
+ separation of testing and productive code. At the moment
+ it is not possible to combine this with a test code
+ coverage using the cover module. The problem is that when
+ cover compiling a module using cover:compile_* the code
+ is reloaded into the emulator omitting/filtering the
+ passed user options. In my example above the export_all
+ option would be removed and the non-exported functions
+ cannot be called any more. (Thanks to Tobias Schlager)</p>
+ <p>
+ Own Id: OTP-9204</p>
+ </item>
+ <item>
+ <p>
+ Inhibit electric newline after "-&gt;" when inside a type
+ spec</p>
+ <p>
+ The Erlang mode for Emacs inserts a newline after every
+ "-&gt;", which saves you one keystroke when writing a
+ function, but that is inappropriate when writing a type
+ spec, as you'd normally keep the spec on one line. This
+ change inhibits the automatic insertion when the current
+ line starts with "-spec" or "-type".(Thanks to Magnus
+ Henoch)</p>
+ <p>
+ Own Id: OTP-9255</p>
+ </item>
+ <item>
+ <p>
+ Add a check logic to prevent file descriptor leak</p>
+ <p>
+ cover module handle files as raw in export and import.
+ Assert counts of ports are the same at the beginning and
+ at the end of the test case.(Thanks to Shunichi
+ Shinohara)</p>
+ <p>
+ Own Id: OTP-9300</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.6.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml
index 75ffa25311..17de66bb22 100644
--- a/lib/tools/doc/src/xref.xml
+++ b/lib/tools/doc/src/xref.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2010</year>
+ <year>2000</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -1465,8 +1465,8 @@ Evaluates a predefined analysis.
<name>start(NameOrOptions) -> Return</name>
<fsummary>Create an Xref server.</fsummary>
<type>
- <v>Name = atom()()</v>
- <v>XrefOrOptions = Xref | Options</v>
+ <v>NameOrOptions = Name | Options</v>
+ <v>Name = atom()</v>
<v>Options = [Option] | Option</v>
<v>Option = {xref_mode, mode()} | term()</v>
<v>Return = {ok, pid()} | {error, {already_started, pid()}}</v>
@@ -1483,7 +1483,7 @@ Evaluates a predefined analysis.
<name>start(Name, Options) -> Return</name>
<fsummary>Create an Xref server.</fsummary>
<type>
- <v>Name = atom()()</v>
+ <v>Name = atom()</v>
<v>Options = [Option] | Option</v>
<v>Option = {xref_mode, mode()} | term()</v>
<v>Return = {ok, pid()} | {error, {already_started, pid()}}</v>
diff --git a/lib/tools/src/make.erl b/lib/tools/src/make.erl
index e78e2a43a4..5cc8d47faa 100644
--- a/lib/tools/src/make.erl
+++ b/lib/tools/src/make.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 83027cfaa6..6999c695e6 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.6.6.3
+TOOLS_VSN = 2.6.6.4
diff --git a/lib/tv/doc/src/notes.xml b/lib/tv/doc/src/notes.xml
index 388bb82c91..b3f2f5587f 100644
--- a/lib/tv/doc/src/notes.xml
+++ b/lib/tv/doc/src/notes.xml
@@ -30,6 +30,30 @@
</header>
<p>This document describes the changes made to the TV application.</p>
+<section><title>TV 2.1.4.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ tv: Allow table viewer to display refs, ports and small
+ binaries</p>
+ <p>
+ Table viewer displayed #Port, #Ref, or #Bin as place
+ holders for their respective object types in ets and
+ mnesia tables. This can make table viewer difficult to
+ use when viewing tables containing those data types. It
+ doesn't make sense to render large binaries so #Bin will
+ still be used for binaries that exceed 100 bytes. (Thanks
+ to Blaine whittle)</p>
+ <p>
+ Own Id: OTP-9153</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>TV 2.1.4.6</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tv/vsn.mk b/lib/tv/vsn.mk
index 958aa0ea42..43e3d2ebce 100644
--- a/lib/tv/vsn.mk
+++ b/lib/tv/vsn.mk
@@ -1 +1 @@
-TV_VSN = 2.1.4.6
+TV_VSN = 2.1.4.7
diff --git a/lib/typer/vsn.mk b/lib/typer/vsn.mk
index 51561939ac..fe8faabdf8 100644
--- a/lib/typer/vsn.mk
+++ b/lib/typer/vsn.mk
@@ -1 +1 @@
-TYPER_VSN = 0.9
+TYPER_VSN = 0.9.1
diff --git a/lib/webtool/doc/src/notes.xml b/lib/webtool/doc/src/notes.xml
index 5179f37db2..b7e6f0421c 100644
--- a/lib/webtool/doc/src/notes.xml
+++ b/lib/webtool/doc/src/notes.xml
@@ -31,6 +31,22 @@
<p>This document describes the changes made to the Webtool
application.</p>
+<section><title>WebTool 0.8.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Various small documentation fixes (Thanks to Bernard
+ Duggan)</p>
+ <p>
+ Own Id: OTP-9172</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>WebTool 0.8.7</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/webtool/doc/src/webtool_chapter.xml b/lib/webtool/doc/src/webtool_chapter.xml
index 305fbcb8ee..77fcaebb4b 100644
--- a/lib/webtool/doc/src/webtool_chapter.xml
+++ b/lib/webtool/doc/src/webtool_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/webtool/vsn.mk b/lib/webtool/vsn.mk
index 6b76883330..d687b4ff81 100644
--- a/lib/webtool/vsn.mk
+++ b/lib/webtool/vsn.mk
@@ -1 +1 @@
-WEBTOOL_VSN=0.8.7
+WEBTOOL_VSN=0.8.8
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 4282e19769..26d1f892b2 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -31,6 +31,22 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 0.98.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed wx app files on mac and solaris. Thanks Jachym
+ Holecek and Joe Williams.</p>
+ <p>
+ Own Id: OTP-9324</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 0.98.9</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile
index 3cc668375f..46bc06271c 100644
--- a/lib/wx/src/Makefile
+++ b/lib/wx/src/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2008-2010. All Rights Reserved.
+# Copyright Ericsson AB 2008-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -29,8 +29,7 @@ ERL_COMPILE_FLAGS += -I$(ERLINC) +warn_unused_vars
ARCHIVE = wx-$(VSN).ez
-ErlMods = \
- wx \
+ErlMods = wx \
wx_object \
wxe_master \
wxe_server \
@@ -44,7 +43,7 @@ GEN_FILES = $(wildcard gen/wx*.erl) \
gen/glu.erl \
gen/gl.erl
-GEN_MODS = $(GEN_FILES:gen/%.erl= %,\n )
+GEN_MODS = $(GEN_FILES:gen/%.erl=%,)
GEN_HRL = \
$(EGEN)/wxe_debug.hrl \
diff --git a/lib/wx/src/wx.appup.src b/lib/wx/src/wx.appup.src
index c02edd2afb..1102af612e 100644
--- a/lib/wx/src/wx.appup.src
+++ b/lib/wx/src/wx.appup.src
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
@@ -18,5 +18,6 @@
%% %CopyrightEnd%
{"%VSN%",
+ [ ],
[ ]
}.
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index 7c440a7f5b..02899f4115 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 0.98.9
+WX_VSN = 0.98.10
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 654bbbc05d..697823eee2 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -31,6 +31,52 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.2.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix minor typos and improve punctuation in the
+ xmerl_xpath @doc comment (Thanks to Marcus Marinelli)</p>
+ <p>
+ Own Id: OTP-9187</p>
+ </item>
+ <item>
+ <p>
+ Prevent xmerl from over-normalizing character references
+ in attributes</p>
+ <p>
+ Section 3.3.3 of the XML Recommendation gives the rules
+ for attribute-value normalization. One of those rules
+ requires that character references not be re-normalized
+ after being replaced with the referenced characters.
+ (Thanks to Tom Moertel)</p>
+ <p>
+ Own Id: OTP-9274</p>
+ </item>
+ <item>
+ <p> Fixed the default encoding option in SAX parser. </p>
+ <p>
+ Own Id: OTP-9288</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Added the xmerl test suites and examples to the open
+ source distribution. </p>
+ <p>
+ Own Id: OTP-9228</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.2.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/xmerl/include/xmerl_xsd.hrl b/lib/xmerl/include/xmerl_xsd.hrl
index b527accc8c..6dad7d8ff0 100644
--- a/lib/xmerl/include/xmerl_xsd.hrl
+++ b/lib/xmerl/include/xmerl_xsd.hrl
@@ -36,6 +36,7 @@
schema_name,
vsn,
schema_preprocessed=false,
+ external_xsd_base=false,
xsd_base,
xml_options=[],
scope=[],
diff --git a/lib/xmerl/src/xmerl_sax_parser.erl b/lib/xmerl/src/xmerl_sax_parser.erl
index 571feabee0..45e2a928ac 100644
--- a/lib/xmerl/src/xmerl_sax_parser.erl
+++ b/lib/xmerl/src/xmerl_sax_parser.erl
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl
index 22eb641a02..e598c5f56d 100644
--- a/lib/xmerl/src/xmerl_scan.erl
+++ b/lib/xmerl/src/xmerl_scan.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -2276,7 +2276,7 @@ scan_att_chars([H|T], S0, H, Acc, TmpAcc,AttType,IsNorm) -> % End quote
true ->
normalize(Acc,S,IsNorm)
end,
- {lists:reverse(Acc2), T, S2,IsNorm2};
+ {lists:flatten(lists:reverse(Acc2)), T, S2,IsNorm2};
scan_att_chars("&" ++ T, S0, Delim, Acc, TmpAcc,AT,IsNorm) -> % Reference
?bump_col(1),
{ExpRef, T1, S1} = scan_reference(T, S),
diff --git a/lib/xmerl/src/xmerl_xpath.erl b/lib/xmerl/src/xmerl_xpath.erl
index c803af3631..db3d3ac2d6 100644
--- a/lib/xmerl/src/xmerl_xpath.erl
+++ b/lib/xmerl/src/xmerl_xpath.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl
index 1f0793bc58..f003cc74ba 100644
--- a/lib/xmerl/src/xmerl_xsd.erl
+++ b/lib/xmerl/src/xmerl_xsd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -287,10 +287,19 @@ process_schema(Schema) ->
%% error reason. The error reason may be a list of several errors
%% or a single error encountered during the processing.
process_schema(Schema,Options) when is_list(Options) ->
- S = initiate_state(Options,Schema),
- process_schema2(xmerl_scan:file(filename:join(S#xsd_state.xsd_base, Schema)),S,Schema);
-process_schema(Schema,State) when is_record(State,xsd_state) ->
- process_schema2(xmerl_scan:file(filename:join(State#xsd_state.xsd_base, Schema)),State,Schema).
+ State = initiate_state(Options,Schema),
+ process_schema(Schema, State);
+process_schema(Schema, State=#xsd_state{fetch_fun=Fetch})->
+ case Fetch(Schema, State) of
+ {ok,{file,File},_} ->
+ process_schema2(xmerl_scan:file(File), State, Schema);
+ {ok,{string,Str},_} ->
+ process_schema2(xmerl_scan:string(Str), State, Schema);
+ {ok,[],_} ->
+ {error,enoent};
+ Err ->
+ Err
+ end.
process_schema2(Err={error,_},_,_) ->
Err;
@@ -319,12 +328,9 @@ process_schemas(Schemas) ->
%% error reason. The error reason may be a list of several errors
%% or a single error encountered during the processing.
process_schemas(Schemas=[{_,Schema}|_],Options) when is_list(Options) ->
- process_schemas(Schemas,initiate_state(Options,Schema));
+ State = initiate_state(Options,Schema),
+ process_schemas(Schemas, State);
process_schemas([{_NS,Schema}|Rest],State=#xsd_state{fetch_fun=Fetch}) ->
-%% case process_external_schema_once(Schema,if_list_to_atom(NS),State) of
-%% S when is_record(S,xsd_state) ->
-%% case process_schema(filename:join([State#xsd_state.xsd_base,Schema]),State) of
-%% {ok,S} ->
Res=
case Fetch(Schema,State) of
{ok,{file,File},_} ->
@@ -345,20 +351,20 @@ process_schemas([{_NS,Schema}|Rest],State=#xsd_state{fetch_fun=Fetch}) ->
process_schemas([],S) when is_record(S,xsd_state) ->
{ok,S}.
-
initiate_state(Opts,Schema) ->
XSDBase = filename:dirname(Schema),
{{state,S},RestOpts}=new_state(Opts),
S2 = create_tables(S),
- initiate_state2(S2#xsd_state{schema_name = Schema,
- xsd_base = XSDBase,
- fetch_fun = fun fetch/2},RestOpts).
+ S3 = initiate_state2(S2#xsd_state{schema_name = Schema, xsd_base=XSDBase,
+ fetch_fun = fun fetch/2},
+ RestOpts).
+
initiate_state2(S,[]) ->
S;
initiate_state2(S,[{tab2file,Bool}|T]) ->
initiate_state2(S#xsd_state{tab2file=Bool},T);
-initiate_state2(S,[{xsdbase,XSDBase}|T]) ->
- initiate_state2(S#xsd_state{xsd_base=XSDBase},T);
+initiate_state2(S,[{xsdbase, XSDBase}|T]) ->
+ initiate_state2(S#xsd_state{xsd_base=XSDBase, external_xsd_base=true},T);
initiate_state2(S,[{fetch_fun,FetchFun}|T]) ->
initiate_state2(S#xsd_state{fetch_fun=FetchFun},T);
initiate_state2(S,[{fetch_path,FetchPath}|T]) ->
@@ -5232,7 +5238,12 @@ fetch(URI,S) ->
[] -> %% empty systemliteral
[];
_ ->
- filename:join(S#xsd_state.xsd_base, URI)
+ case S#xsd_state.external_xsd_base of
+ true ->
+ filename:join(S#xsd_state.xsd_base, URI);
+ false ->
+ filename:join(S#xsd_state.xsd_base, filename:basename(URI))
+ end
end,
Path = path_locate(S#xsd_state.fetch_path, Filename, Fullname),
?dbg("fetch(~p) -> {file, ~p}.~n", [URI, Path]),
diff --git a/lib/xmerl/src/xmerl_xsd_type.erl b/lib/xmerl/src/xmerl_xsd_type.erl
index 9352f4185d..0f46b1f9aa 100644
--- a/lib/xmerl/src/xmerl_xsd_type.erl
+++ b/lib/xmerl/src/xmerl_xsd_type.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile
index 0f8cd88c13..5a2a585841 100644
--- a/lib/xmerl/test/Makefile
+++ b/lib/xmerl/test/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2010. All Rights Reserved.
+# Copyright Ericsson AB 2004-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -124,4 +124,4 @@ release_tests_spec: opt
@tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -)
@tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -)
@tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -)
- chmod -f -R u+w $(RELSYSDIR)
+ chmod -R u+w $(RELSYSDIR)
diff --git a/lib/xmerl/test/xmerl_SUITE.erl b/lib/xmerl/test/xmerl_SUITE.erl
index 9b65232fe7..0c809dbcb6 100644
--- a/lib/xmerl/test/xmerl_SUITE.erl
+++ b/lib/xmerl/test/xmerl_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -57,7 +57,8 @@ groups() ->
{eventp_tests, [], [sax_parse_and_export]},
{ticket_tests, [],
[ticket_5998, ticket_7211, ticket_7214, ticket_7430,
- ticket_6873, ticket_7496, ticket_8156, ticket_8697]},
+ ticket_6873, ticket_7496, ticket_8156, ticket_8697,
+ ticket_9411]},
{app_test, [], [{xmerl_app_test, all}]},
{appup_test, [], [{xmerl_appup_test, all}]}].
@@ -575,7 +576,17 @@ ticket_8697(Config) ->
?line [16#545C] = HexEntityText,
ok.
+ticket_9411(suite) -> [];
+ticket_9411(doc) ->
+ ["Test that xmerl_scan handles attribute that contains for example &quot"];
+ticket_9411(Config) ->
+ DataDir = ?config(data_dir,Config),
+ ?line {ok, Schema} = xmerl_xsd:process_schema(filename:join([DataDir,"misc/ticket_9411.xsd"])),
+ ?line {ok, Bin} = file:read_file(filename:join([DataDir,"misc/ticket_9411.xml"])),
+ ?line Xml = erlang:binary_to_list(Bin),
+ ?line {E, _} = xmerl_scan:string(Xml),
+ ?line {E, _} = xmerl_xsd:validate(E, Schema).
diff --git a/lib/xmerl/test/xmerl_SUITE_data/misc.tar.gz b/lib/xmerl/test/xmerl_SUITE_data/misc.tar.gz
index c48a6f897b..fef7431845 100644
--- a/lib/xmerl/test/xmerl_SUITE_data/misc.tar.gz
+++ b/lib/xmerl/test/xmerl_SUITE_data/misc.tar.gz
Binary files differ
diff --git a/lib/xmerl/test/xmerl_appup_test.erl b/lib/xmerl/test/xmerl_appup_test.erl
index 88d4a9bc28..80c8d8e4fd 100644
--- a/lib/xmerl/test/xmerl_appup_test.erl
+++ b/lib/xmerl/test/xmerl_appup_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/xmerl/test/xmerl_sax_std_SUITE.erl b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
index 2048cc384f..2b7b59dacf 100644
--- a/lib/xmerl/test/xmerl_sax_std_SUITE.erl
+++ b/lib/xmerl/test/xmerl_sax_std_SUITE.erl
@@ -2,7 +2,7 @@
%%----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% 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
diff --git a/lib/xmerl/test/xmerl_test_lib.erl b/lib/xmerl/test/xmerl_test_lib.erl
index 16f438ca84..a83956c076 100644
--- a/lib/xmerl/test/xmerl_test_lib.erl
+++ b/lib/xmerl/test/xmerl_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/xmerl/test/xmerl_xsd_SUITE.erl b/lib/xmerl/test/xmerl_xsd_SUITE.erl
index 74de42aee5..421fa48054 100644
--- a/lib/xmerl/test/xmerl_xsd_SUITE.erl
+++ b/lib/xmerl/test/xmerl_xsd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -62,7 +62,7 @@ groups() ->
sis2, state2file_file2state, union]},
{ticket_tests, [],
[ticket_6910, ticket_7165, ticket_7190, ticket_7288,
- ticket_7736, ticket_8599]},
+ ticket_7736, ticket_8599, ticket_9410]},
{facets, [],
[length, minLength, maxLength, pattern, enumeration,
whiteSpace, maxInclusive, maxExclusive, minExclusive,
@@ -1146,3 +1146,8 @@ ticket_8599(Config) ->
?line {{xmlElement,persons,persons,_,_,_,_,_,_,_,_,_},_GlobalState} = xmerl_xsd:validate(E, S).
+
+ticket_9410(suite) -> [];
+ticket_9410(Config) ->
+ file:set_cwd(filename:join([?config(data_dir,Config),".."])),
+ ?line {ok, _S} = xmerl_xsd:process_schema("xmerl_xsd_SUITE_data/small.xsd").
diff --git a/lib/xmerl/test/xmerl_xsd_lib.erl b/lib/xmerl/test/xmerl_xsd_lib.erl
index 0b6b1ebc84..e5c2d900ba 100644
--- a/lib/xmerl/test/xmerl_xsd_lib.erl
+++ b/lib/xmerl/test/xmerl_xsd_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/make/otp.mk.in b/make/otp.mk.in
index a4e9dad46f..1ba74a3048 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -239,7 +239,9 @@ FOP = @FOP@
DOCGEN=$(ERL_TOP)/lib/erl_docgen
+ifneq (,$(findstring $(origin SPECS_ESRC),$(DUBIOUS_ORIGINS)))
SPECS_ESRC = ../../src
+endif
SPECS_EXTRACTOR=$(DOCGEN)/priv/bin/specs_gen.escript
# Extract specifications and types from Erlang source files (-spec, -type)
$(SPECDIR)/specs_%.xml: $(SPECS_ESRC)/%.erl
diff --git a/otp_build b/otp_build
index aebb91372c..ed4609435f 100755
--- a/otp_build
+++ b/otp_build
@@ -2,7 +2,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2002-2010. All Rights Reserved.
+# Copyright Ericsson AB 2002-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
diff --git a/system/doc/efficiency_guide/drivers.xml b/system/doc/efficiency_guide/drivers.xml
index 1967fd7ada..fec68ca059 100644
--- a/system/doc/efficiency_guide/drivers.xml
+++ b/system/doc/efficiency_guide/drivers.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2009</year><year>2009</year>
+ <year>2009</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/functions.xml b/system/doc/efficiency_guide/functions.xml
index 6be49dd7c9..42cc81dbae 100644
--- a/system/doc/efficiency_guide/functions.xml
+++ b/system/doc/efficiency_guide/functions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2010</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml
index b75be7d531..440be2b6f8 100644
--- a/system/doc/efficiency_guide/processes.xml
+++ b/system/doc/efficiency_guide/processes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/profiling.xml b/system/doc/efficiency_guide/profiling.xml
index 8be1c7175d..13165a0ede 100644
--- a/system/doc/efficiency_guide/profiling.xml
+++ b/system/doc/efficiency_guide/profiling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/efficiency_guide/tablesDatabases.xml b/system/doc/efficiency_guide/tablesDatabases.xml
index 2f5103a08b..0c32ae2d82 100644
--- a/system/doc/efficiency_guide/tablesDatabases.xml
+++ b/system/doc/efficiency_guide/tablesDatabases.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>