diff options
Diffstat (limited to 'lib')
85 files changed, 3206 insertions, 2873 deletions
diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000000..bdc850f3b7 --- /dev/null +++ b/lib/.gitignore @@ -0,0 +1,464 @@ +# megaco + +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.erl +/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.erl +/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_v1.erl +/megaco/src/binary/megaco_ber_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_v2.erl +/megaco/src/binary/megaco_ber_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_ber_media_gateway_control_v3.erl +/megaco/src/binary/megaco_ber_media_gateway_control_v3.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.erl +/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.erl +/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.hrl +/megaco/src/binary/megaco_per_media_gateway_control_prev3a.erl +/megaco/src/binary/megaco_per_media_gateway_control_prev3a.hrl +/megaco/src/binary/megaco_per_media_gateway_control_prev3b.erl +/megaco/src/binary/megaco_per_media_gateway_control_prev3b.hrl +/megaco/src/binary/megaco_per_media_gateway_control_prev3c.erl +/megaco/src/binary/megaco_per_media_gateway_control_prev3c.hrl +/megaco/src/binary/megaco_per_media_gateway_control_v1.erl +/megaco/src/binary/megaco_per_media_gateway_control_v1.hrl +/megaco/src/binary/megaco_per_media_gateway_control_v2.erl +/megaco/src/binary/megaco_per_media_gateway_control_v2.hrl +/megaco/src/binary/megaco_per_media_gateway_control_v3.erl +/megaco/src/binary/megaco_per_media_gateway_control_v3.hrl +/megaco/src/binary/prebuild.skip +/megaco/src/flex/megaco_flex_scanner_drv.c +/megaco/src/flex/megaco_flex_scanner_drv.flex +/megaco/src/flex/megaco_flex_scanner_drv_mt.c +/megaco/src/flex/megaco_flex_scanner_drv_mt.flex +/megaco/src/text/megaco_text_mini_parser.erl +/megaco/src/text/megaco_text_parser_prev3a.erl +/megaco/src/text/megaco_text_parser_prev3b.erl +/megaco/src/text/megaco_text_parser_prev3c.erl +/megaco/src/text/megaco_text_parser_v1.erl +/megaco/src/text/megaco_text_parser_v2.erl +/megaco/src/text/megaco_text_parser_v3.erl + +# orber & cos* applications + +/cosEvent/include/CosEventChannelAdmin.hrl +/cosEvent/include/CosEventChannelAdmin_ConsumerAdmin.hrl +/cosEvent/include/CosEventChannelAdmin_EventChannel.hrl +/cosEvent/include/CosEventChannelAdmin_ProxyPullConsumer.hrl +/cosEvent/include/CosEventChannelAdmin_ProxyPullSupplier.hrl +/cosEvent/include/CosEventChannelAdmin_ProxyPushConsumer.hrl +/cosEvent/include/CosEventChannelAdmin_ProxyPushSupplier.hrl +/cosEvent/include/CosEventChannelAdmin_SupplierAdmin.hrl +/cosEvent/include/CosEventComm.hrl +/cosEvent/include/CosEventComm_PullConsumer.hrl +/cosEvent/include/CosEventComm_PullSupplier.hrl +/cosEvent/include/CosEventComm_PushConsumer.hrl +/cosEvent/include/CosEventComm_PushSupplier.hrl +/cosEvent/include/oe_CosEventChannelAdmin.hrl +/cosEvent/include/oe_CosEventComm.hrl +/cosEvent/src/CosEventChannelAdmin_AlreadyConnected.erl +/cosEvent/src/CosEventChannelAdmin_ConsumerAdmin.erl +/cosEvent/src/CosEventChannelAdmin_EventChannel.erl +/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer.erl +/cosEvent/src/CosEventChannelAdmin_ProxyPullSupplier.erl +/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer.erl +/cosEvent/src/CosEventChannelAdmin_ProxyPushSupplier.erl +/cosEvent/src/CosEventChannelAdmin_SupplierAdmin.erl +/cosEvent/src/CosEventChannelAdmin_TypeError.erl +/cosEvent/src/CosEventComm_Disconnected.erl +/cosEvent/src/CosEventComm_PullConsumer.erl +/cosEvent/src/CosEventComm_PullSupplier.erl +/cosEvent/src/CosEventComm_PushConsumer.erl +/cosEvent/src/CosEventComm_PushSupplier.erl +/cosEvent/src/oe_CosEventChannelAdmin.erl +/cosEvent/src/oe_CosEventComm.erl +/cosEvent/src/oe_CosEventComm_CAdmin.erl +/cosEvent/src/oe_CosEventComm_CAdmin.hrl +/cosEvent/src/oe_CosEventComm_Channel.erl +/cosEvent/src/oe_CosEventComm_Channel.hrl +/cosEvent/src/oe_CosEventComm_Event.erl +/cosEvent/src/oe_CosEventComm_Event.hrl +/cosEvent/src/oe_CosEventComm_PullerS.erl +/cosEvent/src/oe_CosEventComm_PullerS.hrl +/cosEvent/src/oe_CosEventComm_PusherS.erl +/cosEvent/src/oe_CosEventComm_PusherS.hrl +/cosEvent/src/oe_cosEventApp.erl +/cosEvent/src/oe_cosEventApp.hrl +/cosEventDomain/include/CosEventDomainAdmin.hrl +/cosEventDomain/include/CosEventDomainAdmin_EventDomain.hrl +/cosEventDomain/include/CosEventDomainAdmin_EventDomainFactory.hrl +/cosEventDomain/include/oe_CosEventDomainAdmin.hrl +/cosEventDomain/src/CosEventDomainAdmin.erl +/cosEventDomain/src/CosEventDomainAdmin_AlreadyExists.erl +/cosEventDomain/src/CosEventDomainAdmin_Connection.erl +/cosEventDomain/src/CosEventDomainAdmin_ConnectionIDSeq.erl +/cosEventDomain/src/CosEventDomainAdmin_ConnectionNotFound.erl +/cosEventDomain/src/CosEventDomainAdmin_CycleCreationForbidden.erl +/cosEventDomain/src/CosEventDomainAdmin_CycleSeq.erl +/cosEventDomain/src/CosEventDomainAdmin_DiamondCreationForbidden.erl +/cosEventDomain/src/CosEventDomainAdmin_DiamondSeq.erl +/cosEventDomain/src/CosEventDomainAdmin_DomainIDSeq.erl +/cosEventDomain/src/CosEventDomainAdmin_DomainNotFound.erl +/cosEventDomain/src/CosEventDomainAdmin_EventDomain.erl +/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory.erl +/cosEventDomain/src/CosEventDomainAdmin_MemberIDSeq.erl +/cosEventDomain/src/CosEventDomainAdmin_RouteSeq.erl +/cosEventDomain/src/oe_CosEventDomainAdmin.erl +/cosFileTransfer/include/CosFileTransfer.hrl +/cosFileTransfer/include/CosFileTransfer_Directory.hrl +/cosFileTransfer/include/CosFileTransfer_File.hrl +/cosFileTransfer/include/CosFileTransfer_FileIterator.hrl +/cosFileTransfer/include/CosFileTransfer_FileTransferSession.hrl +/cosFileTransfer/include/CosFileTransfer_VirtualFileSystem.hrl +/cosFileTransfer/include/oe_CosFileTransfer.hrl +/cosFileTransfer/src/CosFileTransfer.erl +/cosFileTransfer/src/CosFileTransfer_AccessLevel.erl +/cosFileTransfer/src/CosFileTransfer_CommandNotImplementedException.erl +/cosFileTransfer/src/CosFileTransfer_Directory.erl +/cosFileTransfer/src/CosFileTransfer_File.erl +/cosFileTransfer/src/CosFileTransfer_FileIterator.erl +/cosFileTransfer/src/CosFileTransfer_FileList.erl +/cosFileTransfer/src/CosFileTransfer_FileNameList.erl +/cosFileTransfer/src/CosFileTransfer_FileNotFoundException.erl +/cosFileTransfer/src/CosFileTransfer_FileTransferSession.erl +/cosFileTransfer/src/CosFileTransfer_FileWrapper.erl +/cosFileTransfer/src/CosFileTransfer_IllegalOperationException.erl +/cosFileTransfer/src/CosFileTransfer_ProtocolAddressList.erl +/cosFileTransfer/src/CosFileTransfer_ProtocolSupport.erl +/cosFileTransfer/src/CosFileTransfer_RequestFailureException.erl +/cosFileTransfer/src/CosFileTransfer_SessionException.erl +/cosFileTransfer/src/CosFileTransfer_SupportedProtocolAddresses.erl +/cosFileTransfer/src/CosFileTransfer_TransferException.erl +/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem.erl +/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_ContentList.erl +/cosFileTransfer/src/oe_CosFileTransfer.erl +/cosNotification/include/CosNotification.hrl +/cosNotification/include/CosNotification_AdminPropertiesAdmin.hrl +/cosNotification/include/CosNotification_QoSAdmin.hrl +/cosNotification/include/CosNotifyChannelAdmin.hrl +/cosNotification/include/CosNotifyChannelAdmin_ConsumerAdmin.hrl +/cosNotification/include/CosNotifyChannelAdmin_EventChannel.hrl +/cosNotification/include/CosNotifyChannelAdmin_EventChannelFactory.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxyConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxyPullConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxyPullSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxyPushConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxyPushSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_ProxySupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPullConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPullSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPushConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPushSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPullConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPullSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPushConsumer.hrl +/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPushSupplier.hrl +/cosNotification/include/CosNotifyChannelAdmin_SupplierAdmin.hrl +/cosNotification/include/CosNotifyComm.hrl +/cosNotification/include/CosNotifyComm_NotifyPublish.hrl +/cosNotification/include/CosNotifyComm_NotifySubscribe.hrl +/cosNotification/include/CosNotifyComm_PullConsumer.hrl +/cosNotification/include/CosNotifyComm_PullSupplier.hrl +/cosNotification/include/CosNotifyComm_PushConsumer.hrl +/cosNotification/include/CosNotifyComm_PushSupplier.hrl +/cosNotification/include/CosNotifyComm_SequencePullConsumer.hrl +/cosNotification/include/CosNotifyComm_SequencePullSupplier.hrl +/cosNotification/include/CosNotifyComm_SequencePushConsumer.hrl +/cosNotification/include/CosNotifyComm_SequencePushSupplier.hrl +/cosNotification/include/CosNotifyComm_StructuredPullConsumer.hrl +/cosNotification/include/CosNotifyComm_StructuredPullSupplier.hrl +/cosNotification/include/CosNotifyComm_StructuredPushConsumer.hrl +/cosNotification/include/CosNotifyComm_StructuredPushSupplier.hrl +/cosNotification/include/CosNotifyFilter.hrl +/cosNotification/include/CosNotifyFilter_Filter.hrl +/cosNotification/include/CosNotifyFilter_FilterAdmin.hrl +/cosNotification/include/CosNotifyFilter_FilterFactory.hrl +/cosNotification/include/CosNotifyFilter_MappingFilter.hrl +/cosNotification/include/oe_CosNotification.hrl +/cosNotification/include/oe_CosNotifyChannelAdmin.hrl +/cosNotification/include/oe_CosNotifyComm.hrl +/cosNotification/include/oe_CosNotifyFilter.hrl +/cosNotification/src/CosNotification.erl +/cosNotification/src/CosNotification_AdminPropertiesAdmin.erl +/cosNotification/src/CosNotification_EventBatch.erl +/cosNotification/src/CosNotification_EventHeader.erl +/cosNotification/src/CosNotification_EventType.erl +/cosNotification/src/CosNotification_EventTypeSeq.erl +/cosNotification/src/CosNotification_FixedEventHeader.erl +/cosNotification/src/CosNotification_NamedPropertyRange.erl +/cosNotification/src/CosNotification_NamedPropertyRangeSeq.erl +/cosNotification/src/CosNotification_Property.erl +/cosNotification/src/CosNotification_PropertyError.erl +/cosNotification/src/CosNotification_PropertyErrorSeq.erl +/cosNotification/src/CosNotification_PropertyRange.erl +/cosNotification/src/CosNotification_PropertySeq.erl +/cosNotification/src/CosNotification_QoSAdmin.erl +/cosNotification/src/CosNotification_StructuredEvent.erl +/cosNotification/src/CosNotification_UnsupportedAdmin.erl +/cosNotification/src/CosNotification_UnsupportedQoS.erl +/cosNotification/src/CosNotifyChannelAdmin_AdminIDSeq.erl +/cosNotification/src/CosNotifyChannelAdmin_AdminLimit.erl +/cosNotification/src/CosNotifyChannelAdmin_AdminLimitExceeded.erl +/cosNotification/src/CosNotifyChannelAdmin_AdminNotFound.erl +/cosNotification/src/CosNotifyChannelAdmin_ChannelIDSeq.erl +/cosNotification/src/CosNotifyChannelAdmin_ChannelNotFound.erl +/cosNotification/src/CosNotifyChannelAdmin_ConnectionAlreadyActive.erl +/cosNotification/src/CosNotifyChannelAdmin_ConnectionAlreadyInactive.erl +/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin.erl +/cosNotification/src/CosNotifyChannelAdmin_EventChannel.erl +/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory.erl +/cosNotification/src/CosNotifyChannelAdmin_NotConnected.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyIDSeq.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyNotFound.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyPullConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyPullSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyPushConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxyPushSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_ProxySupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.erl +/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.erl +/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin.erl +/cosNotification/src/CosNotifyComm_InvalidEventType.erl +/cosNotification/src/CosNotifyComm_NotifyPublish.erl +/cosNotification/src/CosNotifyComm_NotifySubscribe.erl +/cosNotification/src/CosNotifyComm_PullConsumer.erl +/cosNotification/src/CosNotifyComm_PullSupplier.erl +/cosNotification/src/CosNotifyComm_PushConsumer.erl +/cosNotification/src/CosNotifyComm_PushSupplier.erl +/cosNotification/src/CosNotifyComm_SequencePullConsumer.erl +/cosNotification/src/CosNotifyComm_SequencePullSupplier.erl +/cosNotification/src/CosNotifyComm_SequencePushConsumer.erl +/cosNotification/src/CosNotifyComm_SequencePushSupplier.erl +/cosNotification/src/CosNotifyComm_StructuredPullConsumer.erl +/cosNotification/src/CosNotifyComm_StructuredPullSupplier.erl +/cosNotification/src/CosNotifyComm_StructuredPushConsumer.erl +/cosNotification/src/CosNotifyComm_StructuredPushSupplier.erl +/cosNotification/src/CosNotifyFilter_CallbackIDSeq.erl +/cosNotification/src/CosNotifyFilter_CallbackNotFound.erl +/cosNotification/src/CosNotifyFilter_ConstraintExp.erl +/cosNotification/src/CosNotifyFilter_ConstraintExpSeq.erl +/cosNotification/src/CosNotifyFilter_ConstraintIDSeq.erl +/cosNotification/src/CosNotifyFilter_ConstraintInfo.erl +/cosNotification/src/CosNotifyFilter_ConstraintInfoSeq.erl +/cosNotification/src/CosNotifyFilter_ConstraintNotFound.erl +/cosNotification/src/CosNotifyFilter_DuplicateConstraintID.erl +/cosNotification/src/CosNotifyFilter_Filter.erl +/cosNotification/src/CosNotifyFilter_FilterAdmin.erl +/cosNotification/src/CosNotifyFilter_FilterFactory.erl +/cosNotification/src/CosNotifyFilter_FilterIDSeq.erl +/cosNotification/src/CosNotifyFilter_FilterNotFound.erl +/cosNotification/src/CosNotifyFilter_InvalidConstraint.erl +/cosNotification/src/CosNotifyFilter_InvalidGrammar.erl +/cosNotification/src/CosNotifyFilter_InvalidValue.erl +/cosNotification/src/CosNotifyFilter_MappingConstraintInfo.erl +/cosNotification/src/CosNotifyFilter_MappingConstraintInfoSeq.erl +/cosNotification/src/CosNotifyFilter_MappingConstraintPair.erl +/cosNotification/src/CosNotifyFilter_MappingConstraintPairSeq.erl +/cosNotification/src/CosNotifyFilter_MappingFilter.erl +/cosNotification/src/CosNotifyFilter_UnsupportedFilterableData.erl +/cosNotification/src/cosNotification_Grammar.erl +/cosNotification/src/oe_CosNotification.erl +/cosNotification/src/oe_CosNotificationComm.hrl +/cosNotification/src/oe_CosNotificationComm_Event.erl +/cosNotification/src/oe_CosNotificationComm_Event.hrl +/cosNotification/src/oe_CosNotifyChannelAdmin.erl +/cosNotification/src/oe_CosNotifyComm.erl +/cosNotification/src/oe_CosNotifyFilter.erl +/cosNotification/src/oe_cosNotificationAppComm.erl +/cosNotification/src/oe_cosNotificationAppComm.hrl +/cosProperty/include/CosPropertyService.hrl +/cosProperty/include/CosPropertyService_PropertiesIterator.hrl +/cosProperty/include/CosPropertyService_PropertyNamesIterator.hrl +/cosProperty/include/CosPropertyService_PropertySet.hrl +/cosProperty/include/CosPropertyService_PropertySetDef.hrl +/cosProperty/include/CosPropertyService_PropertySetDefFactory.hrl +/cosProperty/include/CosPropertyService_PropertySetFactory.hrl +/cosProperty/include/oe_CosProperty.hrl +/cosProperty/src/CosPropertyService_ConflictingProperty.erl +/cosProperty/src/CosPropertyService_ConstraintNotSupported.erl +/cosProperty/src/CosPropertyService_FixedProperty.erl +/cosProperty/src/CosPropertyService_InvalidPropertyName.erl +/cosProperty/src/CosPropertyService_MultipleExceptions.erl +/cosProperty/src/CosPropertyService_Properties.erl +/cosProperty/src/CosPropertyService_PropertiesIterator.erl +/cosProperty/src/CosPropertyService_Property.erl +/cosProperty/src/CosPropertyService_PropertyDef.erl +/cosProperty/src/CosPropertyService_PropertyDefs.erl +/cosProperty/src/CosPropertyService_PropertyException.erl +/cosProperty/src/CosPropertyService_PropertyExceptions.erl +/cosProperty/src/CosPropertyService_PropertyMode.erl +/cosProperty/src/CosPropertyService_PropertyModes.erl +/cosProperty/src/CosPropertyService_PropertyNames.erl +/cosProperty/src/CosPropertyService_PropertyNamesIterator.erl +/cosProperty/src/CosPropertyService_PropertyNotFound.erl +/cosProperty/src/CosPropertyService_PropertySet.erl +/cosProperty/src/CosPropertyService_PropertySetDef.erl +/cosProperty/src/CosPropertyService_PropertySetDefFactory.erl +/cosProperty/src/CosPropertyService_PropertySetFactory.erl +/cosProperty/src/CosPropertyService_PropertyTypes.erl +/cosProperty/src/CosPropertyService_ReadOnlyProperty.erl +/cosProperty/src/CosPropertyService_UnsupportedMode.erl +/cosProperty/src/CosPropertyService_UnsupportedProperty.erl +/cosProperty/src/CosPropertyService_UnsupportedTypeCode.erl +/cosProperty/src/oe_CosProperty.erl +/cosTime/include/CosTime.hrl +/cosTime/include/CosTime_TIO.hrl +/cosTime/include/CosTime_TimeService.hrl +/cosTime/include/CosTime_UTO.hrl +/cosTime/include/CosTimerEvent.hrl +/cosTime/include/CosTimerEvent_TimerEventHandler.hrl +/cosTime/include/CosTimerEvent_TimerEventService.hrl +/cosTime/include/TimeBase.hrl +/cosTime/include/oe_CosTime.hrl +/cosTime/include/oe_CosTimerEvent.hrl +/cosTime/include/oe_TimeBase.hrl +/cosTime/src/CosTime_TIO.erl +/cosTime/src/CosTime_TimeService.erl +/cosTime/src/CosTime_TimeUnavailable.erl +/cosTime/src/CosTime_UTO.erl +/cosTime/src/CosTimerEvent_TimerEventHandler.erl +/cosTime/src/CosTimerEvent_TimerEventService.erl +/cosTime/src/CosTimerEvent_TimerEventT.erl +/cosTime/src/TimeBase_IntervalT.erl +/cosTime/src/TimeBase_UtcT.erl +/cosTime/src/oe_CosTime.erl +/cosTime/src/oe_CosTimerEvent.erl +/cosTime/src/oe_TimeBase.erl +/cosTransactions/include/CosTransactions.hrl +/cosTransactions/include/CosTransactions_Control.hrl +/cosTransactions/include/CosTransactions_Coordinator.hrl +/cosTransactions/include/CosTransactions_RecoveryCoordinator.hrl +/cosTransactions/include/CosTransactions_Resource.hrl +/cosTransactions/include/CosTransactions_SubtransactionAwareResource.hrl +/cosTransactions/include/CosTransactions_Terminator.hrl +/cosTransactions/include/CosTransactions_TransactionFactory.hrl +/cosTransactions/include/ETraP.hrl +/cosTransactions/include/ETraP_Server.hrl +/cosTransactions/include/oe_CosTransactions.hrl +/cosTransactions/src/CosTransactions_Control.erl +/cosTransactions/src/CosTransactions_Coordinator.erl +/cosTransactions/src/CosTransactions_HeuristicCommit.erl +/cosTransactions/src/CosTransactions_HeuristicHazard.erl +/cosTransactions/src/CosTransactions_HeuristicMixed.erl +/cosTransactions/src/CosTransactions_HeuristicRollback.erl +/cosTransactions/src/CosTransactions_Inactive.erl +/cosTransactions/src/CosTransactions_InvalidControl.erl +/cosTransactions/src/CosTransactions_NoTransaction.erl +/cosTransactions/src/CosTransactions_NotPrepared.erl +/cosTransactions/src/CosTransactions_NotSubtransaction.erl +/cosTransactions/src/CosTransactions_PropagationContext.erl +/cosTransactions/src/CosTransactions_RecoveryCoordinator.erl +/cosTransactions/src/CosTransactions_Resource.erl +/cosTransactions/src/CosTransactions_SubtransactionAwareResource.erl +/cosTransactions/src/CosTransactions_SubtransactionsUnavailable.erl +/cosTransactions/src/CosTransactions_SynchronizationUnavailable.erl +/cosTransactions/src/CosTransactions_Terminator.erl +/cosTransactions/src/CosTransactions_TransIdentity.erl +/cosTransactions/src/CosTransactions_TransactionFactory.erl +/cosTransactions/src/CosTransactions_Unavailable.erl +/cosTransactions/src/CosTransactions_WrongTransaction.erl +/cosTransactions/src/CosTransactions_otid_t.erl +/cosTransactions/src/ETraP_Server.erl +/cosTransactions/src/oe_CosTransactions.erl +/orber/COSS/CosNaming/CosNaming.hrl +/orber/COSS/CosNaming/CosNaming_Binding.erl +/orber/COSS/CosNaming/CosNaming_BindingIterator.erl +/orber/COSS/CosNaming/CosNaming_BindingIterator.hrl +/orber/COSS/CosNaming/CosNaming_BindingList.erl +/orber/COSS/CosNaming/CosNaming_Name.erl +/orber/COSS/CosNaming/CosNaming_NameComponent.erl +/orber/COSS/CosNaming/CosNaming_NamingContext.erl +/orber/COSS/CosNaming/CosNaming_NamingContext.hrl +/orber/COSS/CosNaming/CosNaming_NamingContextExt.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_AlreadyBound.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_CannotProceed.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_InvalidAddress.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_InvalidName.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_NotEmpty.erl +/orber/COSS/CosNaming/CosNaming_NamingContextExt_NotFound.erl +/orber/COSS/CosNaming/CosNaming_NamingContext_AlreadyBound.erl +/orber/COSS/CosNaming/CosNaming_NamingContext_CannotProceed.erl +/orber/COSS/CosNaming/CosNaming_NamingContext_InvalidName.erl +/orber/COSS/CosNaming/CosNaming_NamingContext_NotEmpty.erl +/orber/COSS/CosNaming/CosNaming_NamingContext_NotFound.erl +/orber/COSS/CosNaming/oe_cos_naming.erl +/orber/COSS/CosNaming/oe_cos_naming.hrl +/orber/COSS/CosNaming/oe_cos_naming_ext.erl +/orber/COSS/CosNaming/oe_cos_naming_ext.hrl +/orber/examples/Stack/StackModule.hrl +/orber/examples/Stack/StackModule_EmptyStack.erl +/orber/examples/Stack/StackModule_Stack.erl +/orber/examples/Stack/StackModule_Stack.hrl +/orber/examples/Stack/StackModule_StackFactory.erl +/orber/examples/Stack/StackModule_StackFactory.hrl +/orber/examples/Stack/oe_stack.erl +/orber/examples/Stack/oe_stack.hrl +/orber/src/CORBA.hrl +/orber/src/OrberApp.hrl +/orber/src/OrberApp_IFR.erl +/orber/src/OrberApp_IFR.hrl +/orber/src/erlang.hrl +/orber/src/erlang_binary.erl +/orber/src/erlang_pid.erl +/orber/src/erlang_port.erl +/orber/src/erlang_ref.erl +/orber/src/oe_CORBA.erl +/orber/src/oe_CORBA.hrl +/orber/src/oe_OrberIFR.erl +/orber/src/oe_OrberIFR.hrl +/orber/src/oe_erlang.erl +/orber/src/oe_erlang.hrl diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile index be8755f0ff..d29225f6c9 100644 --- a/lib/asn1/doc/src/Makefile +++ b/lib/asn1/doc/src/Makefile @@ -51,9 +51,7 @@ XML_REF3_FILES = asn1ct.xml \ GEN_XML = \ asn1_spec.xml -XML_PART_FILES = \ - part.xml \ - part_notes.xml +XML_PART_FILES = part.xml XML_HTML_FILE = \ notes_history.xml diff --git a/lib/asn1/doc/src/note.gif b/lib/asn1/doc/src/note.gif Binary files differdeleted file mode 100644 index 6fffe30419..0000000000 --- a/lib/asn1/doc/src/note.gif +++ /dev/null diff --git a/lib/asn1/doc/src/notes_history.xml b/lib/asn1/doc/src/notes_history.xml deleted file mode 100644 index e6c423e79e..0000000000 --- a/lib/asn1/doc/src/notes_history.xml +++ /dev/null @@ -1,1782 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2006</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>ASN1 Release Notes</title> - <prepared>Bertil Karlsson</prepared> - <responsible></responsible> - <docno></docno> - <approved></approved> - <checked></checked> - <date>06-04-24</date> - <rev></rev> - <file>notes_history.sgml</file> - </header> - <p>This document describes the changes made to the asn1 system - from version to version. The intention of this document is to - list all incompatibilities as well as all enhancements and - bug-fixes for every release of the asn1 application. Each release of asn1 - thus constitutes one section in this document. The title of each - section is the version number of asn1.</p> - - - <section> - <title>Asn1 1.4.4.14</title> - - <section> - <title>Improvements and New Features</title> - <list type="bulleted"> - <item> - <p>Data in info/0 in generated code is moved to attribute - asn1_info, thus vsn value remains the same if compiler - options for asn1-spec differs but the generated code is - the same.</p> - <p>Own Id: OTP-6462</p> - </item> - <item> - <p>Dialyzer warnings on asn1 are removed, i.e. dead code - removed.</p> - <p>Own Id: OTP-6506</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.13</title> - - <section> - <title>Improvements and New Features</title> - <list type="bulleted"> - <item> - <p>Now it is possible to use 'asn1config' and 'inline' - options together. It is also possible to use 'inline' on - a single file like: - <c>asn1ct:compile("MyASN1spec.asn",[inline])</c>.</p> - <p>Own Id: OTP-6405</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.12</title> - - <section> - <title>Improvements and New Features</title> - <list type="bulleted"> - <item> - <p>As a complement to the option "{inline,OutputFile}" it is - now possible to use the option "inline". Then asn1 creates - an output file with the name of the source .set file.</p> - <p>Own Id: OTP-6314</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.11</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>When compiling an asn1 source that reference a type in - another source the compiler uses the asn1db file of the - other source to resolve the reference. It also tests - whether the other source has been updated since the - asn1db file was generated. This last test was to brutal - in that it exits compilation when no source was found, - even though a asn1db file existed. Changed behavior from - a brutal exit to a warning.</p> - <p>Own Id: OTP-6143</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.10</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>asn1 encoding failed on BIT STRING with constraint - <c>(SIZE (32..MAX))</c>.</p> - <p>Own Id: OTP-5932</p> - </item> - <item> - <p>Race condition removed in server for variable names for - generated code.</p> - <p>Own Id: OTP-6111</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.9</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>Now exists a default function clause for table lookup of - a table constraint. This causes a nice error instead of a - crash. Did also remove some obsolete funs ({Mod,Fun}) in - generated code.</p> - <p>Own Id: OTP-5783</p> - </item> - <item> - <p>ASN1-compiler failed to derive a value out of an external - reference in some certain cases, when compiling specs so - that the spec with the reference was compiled before the - spec with the defined value.</p> - <p>Own Id: OTP-5812 Aux Id: seq10133 </p> - </item> - <item> - <p>The documentation of how records of embedded types are - named is extended and made clearer by examples and rules. - The section "Naming of Records in .hrl Files" in the - User's Guide is added.</p> - <p>Own Id: OTP-5831 Aux Id: seq10133 </p> - </item> - <item> - <p>The compiler failed to give right name to record/function - of a parameterized type that was referenced through - another instance of a parameterized type in another - module. The fault occurred when modules were compiled in a - certain order. Now the compiler resolves the name - correctly.</p> - <p>Own Id: OTP-5832 Aux Id: seq10133 </p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.8</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>The dynamic sort of SET OF values now correctly handles - values encoded in the "ber_bin, der, optimize" mode, the - value of a SET OF is a list of binaries.</p> - <p>Own Id: OTP-5687</p> - </item> - <item> - <p>Bad code was generated for an INTEGER with value-range. If - the value that was encoded had a lower bound with - negative value it caused a crash. This bug is now - removed.</p> - <p>Own Id: OTP-5688 Aux Id: seq10049 </p> - </item> - <item> - <p>Compiler now handles wrong include paths by returning an - error if a referenced module is not available.</p> - <p>Own Id: OTP-5689</p> - </item> - <item> - <p>The bug causing a runtime error when encoding a type - defined by: <c>BIT STRING {a(1),b(2)}</c> with the value - [] in <c>per_bin</c> mode is now removed.</p> - <p>Own Id: OTP-5710 Aux Id: seq10066 </p> - </item> - </list> - </section> - - <section> - <title>Improvements and New Features</title> - <list type="bulleted"> - <item> - <p>Better handling of filename paths</p> - <p>Own Id: OTP-5701</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.7</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>Effective constraint for <c>per</c> now corrected. For - instance <c>INTEGER (0|15..269)</c> didn't work properly.</p> - <p>Own Id: OTP-5477 Aux Id: OTP-5511 </p> - </item> - <item> - <p>Adjusted compiler so that functions in generated code - only are exported once.</p> - <p>Own Id: OTP-5509</p> - </item> - <item> - <p>Fixed the compiler failure when handling a value range - constraint with an extension mark that had the Lower - bound and/or Upper bound values as an external reference - to a defined value.</p> - <p>Own Id: OTP-5511 Aux Id: OTP-5466 </p> - </item> - <item> - <p>Removed sorting of elements for SEQUENCE OF. It shall - only be done in SET OF.</p> - <p>Own Id: OTP-5602</p> - </item> - <item> - <p>Corrected code that generated code causing badarith - warning.</p> - <p>Own Id: OTP-5616</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.6</title> - - <section> - <title>Known Bugs and Problems</title> - <list type="bulleted"> - <item> - <p>Compiler now correctly crashes when compiling bad values. - Failed for instance on INTEGER value that was a reference - to a defined value. Also solved problem with a union - constraint on an INTEGER.</p> - <p>Own Id: OTP-5457</p> - </item> - <item> - <p>Additional coverage of object set syntax.</p> - <p>Own Id: OTP-5466</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.5</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>A bug due to representation of open_type values is now - fixed. It could cause problem if one used the EXTERNAL - type.</p> - <p>Own Id: OTP-5302</p> - </item> - <item> - <p>Due to an internal error the same code could have been - generated more than one time. This happened for the - exclusive decode functionality.</p> - <p>Own Id: OTP-5378</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.4</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>Empty objects caused problems. There was trouble when an - object set referenced imported objects that in turn - referenced imported types. Lacked support of - SelectionType in object. All these have been attended.</p> - <p>Own Id: OTP-5240</p> - </item> - </list> - </section> - - <section> - <title>Improvements and New Features</title> - <list type="bulleted"> - <item> - <p>Now it is possible to inline asn1 run-time functionality - in the module generated by the asn1 compiler. Thus, it - will be only one module doing all encoding/decoding.</p> - <p>Own Id: OTP-5243</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.3</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>A class that was referenced in two steps caused a - compiler failure. It is now corrected.</p> - <p>Own Id: OTP-5103</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Optionally make it possible to get the un-decoded rest along with - the return value. Compile with option <em>undec_rest</em>.</p> - <p>Own Id: OTP-5104</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.2</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>An error due to unchecked referenced imported type resulted - in missing tag in some table constraint cases. This error is - now corrected. Error occurred during decode in - <c>ber_bin optimized</c> version.</p> - <p>Own Id: OTP-5022</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>When a referenced value in another module in turn referenced a - defined value the compilation crashed. This is due to the new - routines for compilation, that external references are resolved - during compilation, and not by the order in which modules are - compiled. This error is now corrected.</p> - <p>Own Id: OTP-4970</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.4</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Functionality for parameterized class is added. Parsing failures on - WithSyntax spec is corrected.</p> - <p>Own Id: OTP-4893</p> - </item> - <item> - <p>The failure due to Parameterized Type when parameter is an object - set is corrected.</p> - <p>Own Id: OTP-4894</p> - <p>Aux Id: OTP-4893</p> - </item> - <item> - <p>Object Identifier values with two components and the first was a - value reference failed due to parsing conflicts. Now it is - corrected.</p> - <p>Own Id: OTP-4895</p> - </item> - <item> - <p>The erroneous comparison of file name and asn1 module name could - cause compilation failure. The situation for this failure is rare, - it requires that other processes modifies the compiled file during - the compilation procedure. It is now fixed.</p> - <p>Own Id: OTP-4944</p> - <p>Aux Id: seq8429</p> - </item> - <item> - <p>Selective decode was ignored when exclusive decode spec in asn1 - configfile was missing. Selective decode failed when the selected - type was the top type. These bugs are now removed.</p> - <p>Own Id: OTP-4953</p> - <p>Aux Id: seq8436</p> - </item> - <item> - <p>The test interface asn1ct:test/1,2,3 and asn1ct:value/2 failed for - open type and EXTERNAL. The bug is now removed.</p> - <p>Own Id: OTP-4955</p> - <p>Aux Id: seq8438)</p> - </item> - <item> - <p>Two equal functions were generated for two components referencing - the same type when they were picked by the action "parts". The bug - is now fixed.</p> - <p>Own Id: OTP-4957</p> - <p>Aux Id: seq8434</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>INTEGER with named number list and ENUMERATED can now be sub - constrained with names from the names list.</p> - <p>Own Id: OTP-4917</p> - </item> - <item> - <p>Now there is support for SelectionType (X 680 section 29)</p> - <p>Own Id: OTP-4918</p> - </item> - <item> - <p>The compiler now resolves circular dependencies. When asn1 specs - IMPORTS from each other so that there are circular dependencies.</p> - <p>Own Id: OTP-4919</p> - </item> - <item> - <p>Now is the asn1 type UTF8String supported. For user instructions - see documentation.</p> - <p>Own Id: OTP-4965</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.3.1</title> - - <section> - <title>Fixed Bugs and Malfunctions</title> - <list type="bulleted"> - <item> - <p>The <c>{internal_error,...,{ unrecognized_type,...}}</c> - error occurring for a SET type when compiling with options - <c>[ber_bin,optimize,der]</c> is now corrected.</p> - <p>Own Id: OTP-4866</p> - </item> - <item> - <p>False encode of BIT STRING in PER (per_bin,optimize) is fixed. The error occurred when there was a type like BIT STRING (SIZE(C)) and C > 16.</p> - <p>Own Id: OTP-4869</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.3</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Functionality to handle parameterized object sets have been added.</p> - <p>Own Id: OTP-4832</p> - </item> - <item> - <p>Bug causing duplicated function definitions using exclusive decode is removed.</p> - <p>Own Id: OTP-4833)</p> - </item> - <item> - <p>The race condition when loading asn1 driver is solved.</p> - <p>Own Id: OTP-4835</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>A specialized decode, <em>selective decode</em> is now available. It decodes a chosen internal sub-type of a constructed type.</p> - <p>Own Id: OTP-4856)</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.2.2</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Release of Asn1 1.4.2.1 on R7B, The functionality is the same, but - the layer between the driver and the asn1 erlang code is different.</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.2.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>ObjectDescriptor does now work as part of a sequence, set or choice.</p> - <p>Own Id: OTP-4773</p> - </item> - <item> - <p>When a SEQUENCE that have extension mark was decoded inside a - SEQUENCE OF it could cause decode error due to a failure in - restbytes2. It is now corrected.</p> - <p>Own Id: OTP-4791)</p> - </item> - <item> - <p>Now the bug is fixed that caused the compiler crash on an untagged - optional open type.</p> - <p>Own Id: OTP-4792</p> - </item> - <item> - <p>The earlier exit caused by bad in-data is now fixed so it will - return an {error,Reason} tuple.</p> - return an {error,Reason} tuple.</p> - <p>Own Id: OTP-4797</p> - </item> - <item> - <p>Open type encoded with indefinite length is now correct decoded.</p> - <p>Own Id: OTP-4798</p> - </item> - <item> - <p>Now is absent optional open types handled correctly.</p> - <p>Own Id: OTP-4799</p> - </item> - <item> - <p>Now is the necessary functions available for sorting in run-time of - SET and SET OF components.</p> - <p>Own Id: OTP-4809</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.2</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>When a component in a SEQUENCE is a CHOICE (or reference to a CHOICE) - and the SEQUENCE's component and one of the alternatives in the CHOICE - have identical names, an error may occur if one doesn't use the - 'optimized' versions of the compiler. In the older versions (<c>ber, ber_bin, per, per_bin</c>) one could optionally apply a value of a - component as <c>{ComponentName,Value}</c>, and the generated code - chooses the second element of the tuple. However, a value of a CHOICE - must be applied as a tuple: <c>{AlternativeName,Value}</c>. Thus, - in the rare case described above and if the value to the SEQUENCE's - component is not in a tuple notation the - <c>{AlternativeName,Value}</c> will be peeled off in the SEQUENCE - and the value fed to the CHOICE will only be the <c>Value</c> - part of <c>{AlternativeName,Value}</c>, and the encoder crashes. - The best way to avoid this is to use the optimized version of the - compiler where the unnecessary tuple notation - <c>{ComponentName,Value}</c> no longer is allowed. Since it isn't - possible to solve this bug in the compiler.</p> - <p>Own Id: OTP-4693</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Exclusive decode is enabled by a compiler option and a configuration - file. It makes it possible to leave parts of an ASN.1 encoded message - un-decoded.</p> - <p>Own Id: OTP-4744</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.1.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The documentation about how extensibility is handled is now corrected.</p> - <p>Own Id: OTP-4663</p> - </item> - <item> - <p>Function in object now calls the exported function</p> - <p>Own Id: OTP-4665</p> - </item> - <item> - <p>Now is tags for ObjectClassFieldType analyzed correctly.</p> - <p>Own Id: OTP-4666</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Now is the Default value for an ENUMERATED returned as the name from - the NamedList when decoding.</p> - <p>Own Id: OTP-4633</p> - </item> - <item> - <p>It was an internal failure when permitted alphabet constraint existed - together with for instance a size constraint. E.g. when a - referenced type is constrained by a size constraint and the defined - type in turn is constrained by a permitted alphabet constraint.</p> - <p>Own Id: OTP-4559</p> - </item> - <item> - <p>Record is generated in hrl file for a CHOICE with extension mark - that has an internal SEQUENCE/SET definition.</p> - <p>Own Id: OTP-4560</p> - </item> - <item> - <p>Now is the length of a SEQUENCE/SET OF correctly encoded/decoded (PER).</p> - <p>Own Id: OTP-4590</p> - </item> - <item> - <p>The problem with unordered decoded terms when a component is a - ObjectClassFieldType has been solved.</p> - <p>Own Id: OTP-4591</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>More complex definitions with TableConstraints where the SimpleTable - and ComponentRelation are on different levels is now fully - supported.</p> - <p>Own Id: OTP-4631</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.4</title> - - <section> - <title>Fixed errors and malfunctions</title> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Each generated .erl file have now a function info/0 that returns - information about the used compiler version and options.</p> - <p>Own Id: OTP-4373</p> - </item> - <item> - <p>When compiling an ASN.1 module the compiler generates an Erlang module - that is compiled by the Erlang compiler. Earlier it was not possible to - add options to the final step, the Erlang compilation. By adding any - option that is not recognized as a specific ASN.1 option it will be - passed to the final step like: <c>erlc +debug_info Mymodule.asn</c> or - <c>asn1ct:compile('Mymodule',[debug_info])</c>.</p> - <p>Own Id: OTP-4491</p> - </item> - <item> - <p>Earlier one couldn't multi file compile modules that had different - tagdefault, which now is possible. Equal Type/Value names in different - modules are resolved by renaming (concatenate type name and module - name): If two types with the same name T exist in module A and module B - they will get the new names TA and TB.</p> - <p>(Own Id: OTP-4492)</p> - <p>Aux Id: OTP-3983</p> - </item> - <item> - <p>BER: Encode/decode of data have been significantly improved. By use of - the compiler options <c>ber_bin</c> and <c>optimize</c>, - optimized code will be generated and the optimized run-time module will - be used.</p> - <p>Own Id: OTP-4493</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.3.3.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Proper length encoding and padding implemented for a <c>BIT STRING</c> with - NamedNumberList and size constraint as value range. This functionality - didn't work in the rare occasion when the NamedNumberList is shorter - than the lower bound of the constraint.As in this example: - <c>TestS ::= BIT STRING {a (0),b (1)} (SIZE (3..8))</c></p> - <p>(Own Id: OTP-4353)</p> - </item> - <item> - <p>Bug in compiler, when an <c>OBJECT IDENTIFIER</c> value consisting of - two identifiers (Defined values or Name form identifiers) was falsely - interpreted causing a compiling error is now corrected.</p> - <p>(Own Id: OTP-4354)</p> - </item> - <item> - <p>Internal error in check phase that caused crash on - <c>ObjectClassFieldType</c> in ber_bin is corrected.</p> - <p>(Own Id: OTP-4390)</p> - </item> - <item> - <p>Tags for open types are handled according to <c>x.680 30.6c</c>, i.e. - open types shall not be tagged <c>IMPLICIT.</c></p> - <p>(Own Id: OTP-4395)</p> - <p>(Aux Id: OTP-4390)</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.3.3</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Now gives the compiler an appropriate error report when exported - undefined types are detected.</p> - <p>(Own Id: OTP-4129)</p> - </item> - <item> - <p>The type <c>ObjectDescriptor</c> is now supported, previously the - implementation of encode/decode for this rarely used type was - incomplete.</p> - <p>(Own Id: OTP-4161)</p> - <p>(Aux Id: seq7165)</p> - </item> - <item> - <p>In case of per and compact_bit_string the rightmost byte were erroneous - truncated when the rightmost bits of that byte were zeros. This is now - corrected.</p> - <p>(Own Id: OTP-4200)</p> - </item> - <item> - <p>Bad match of return-value from decode_length in skipvalue/3 has now been - fixed.</p> - <p>(Own Id: OTP-4232)</p> - </item> - <item> - <p>Now is decode of ENUMERATED handled correctly, when tagged EXPLICIT.</p> - <p>(Own Id: OTP-4234)</p> - </item> - <item> - <p>The compiler now parses and handles the ValueFromObject construct.</p> - <p>(Own Id: OTP-4242)</p> - </item> - <item> - <p>Now does the compiler handle the case when the object set in simple - table and componentrelation constraints is of a CLASS without a UNIQUE - field. In this case is the octets, which is assumed to be encoded, - encoded as an open type.</p> - <p>(Own Id: OTP-4248)</p> - <p>(Aux Id: OTP-4242)</p> - </item> - <item> - <p>Compiler handles objects in AdditionalElementSetSpec in ObjectSetSpec, - i.e. the objects that are referred to after the ellipses in an object set.</p> - <p>(Own Id: OTP-4275)</p> - </item> - <item> - <p>Now are values with a component of type CHOICE encoded with indefinite - length correctly decoded.</p> - <p>(Own Id: OTP-4358)</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>The language constructs (from the old 1988 standard) <c>ANY</c> - and <c>ANY DEFINED BY</c> are now implemented.</p> - <p>(Own Id: OTP-2741)</p> - <p>(Aux Id: seq 1188)</p> - </item> - <item> - <p>Now it is checked in run-time if a <c>OBJECT IDENTIFIER</c> value is invalid</p> - <p>(Own Id: OTP-4235)</p> - </item> - <item> - <p>The ASN.1 types EXTERNAL,EMBEDDED PDV and CHARACTER STRING now have full support in the compiler.</p> - <p>(Own Id: OTP-4247)</p> - </item> - <item> - <p>A driver in C does the final job (complete) of the PER encoding when - files are compiled with <c>per_bin</c> and <c>optimize</c> flags. - It gives significant faster encoding for PER.</p> - <p>(Own Id: OTP-4355)</p> - </item> - <item> - <p>Encode and decode of PER encoding has been made faster by moving - analysis done in run-time to compile-time. These optimizations are - available by compiling ASN.1 files with options <c>per_bin</c> and - <c>optimize</c>.</p> - <p>(Own Id: OTP-4381)</p> - <p>(Aux Id: OTP-4355)</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.3.2</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Now does the compiler check values (including referenced values), and - formats the value so it is suitable to use as input to encoding - functions.</p> - <p>(Own Id: OTP-3277)</p> - <p>(Aux Id: OTP-4103)</p> - </item> - <item> - <p>Unnecessary external function calls in generated code are now generated - as internal function calls.</p> - <p>(Own Id: OTP-4073)</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Now is Information Objects supported in BER encoding.</p> - <p>(Own Id: OTP-3980)</p> - <p>(Aux Id: OTP-3979 OTP-3978)</p> - <p></p> - </item> - <item> - <p>PER: A new option <c>per_bin</c> is now supported. When used the - generated encode/decode functions use binaries and the bit syntax to - get better performance than the old <c>per</c> variant which used - lists. All values input to encode and returned from decode are - compatible between <c>per</c> and <c>per_bin</c> except for - open types which are represented as binaries with per_bin and octet - lists with per. We recommend that you use per_bin instead of per from - now on, the use of binaries will be the default in coming versions and - all improvements and optimizations for PER will be concentrated to that - solution.</p> - <p>(Own Id: OTP-4094)</p> - <p></p> - </item> - <item> - <p>Support for DER implemented. Used by flag +der when compiling. Include - the full BER encoding plus: sorting of SET components, sorting of - encoded elements in SET OF, full check of default values in SET and - SEQUENCE. See new documentation on DER in user_guide sections 1.3.1; - 1.4.11; 1.4.12; 1.4.14; 1.4.16 and 1.10, in the reference manual for - asn1ct.</p> - <p>(Own Id: OTP-4103)</p> - <p></p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.3.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>Do not generate record in .hrl file for SET types</p> - <p>Own Id: OTP-4025</p> - </item> - <item> - <p>Fixed internal error when using BIT STRINGs with Named Number List in combination with <c>compact_bit_string</c> and <c>ber_bin</c> options.</p> - <p>Own Id: OTP-4026</p> - <p>Aux Id: OTP-3982</p> - </item> - <item> - <p>The atom 'com' can now be used in ENUMERATED as an EnumerationItem.</p> - <p>Own Id: OTP-4037</p> - <p>Aux Id: Seq 7036</p> - </item> - <item> - <p>ber: Now it is possible (again) to encode data format "{Type,Value}" in a SEQUENCE OF RequestParameter, when RequestParameter is of type ENUMERATED. The {Type,Value} - notation is not recommended for use, it is redundant and exist only for very ancient backwards compatibility reasons. The "feature" might be removed in forthcoming versions.</p> - <p>Own Id: OTP-4057</p> - <p>Aux Id: Seq 7066</p> - </item> - <item> - <p>A bug in the parser, that caused failure on COMPONENTS OF is now removed.</p> - <p>Own Id: OTP-4058</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.3</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The compiler will now check that a value referenced by name - does exist.</p> - <p>Own Id: OTP-3277</p> - </item> - <item> - <p>BER:Decode of a type T ::= SEQUENCE OF C fails if C is encoded with indefinite length. - This is know corrected.</p> - <p>Own Id: OTP-3811</p> - <p>Aux Id: seq5040</p> - </item> - </list> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The new parser handles imports when one import ends with FROM, a modulename and a reference to a objectidentifier followed by imports from other modules.</p> - <p>Own Id: OTP-3463</p> - </item> - <item> - <p>The compiler did not check that a name mentioned as EXPORTED - actually is defined within the module. - This is now corrected.</p> - <p>Own Id: OTP-3659</p> - </item> - <item> - <p>Removed bug caused by use of nested indefinite length</p> - <p>Own Id: OTP-3994</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Now supporting most common use of parameterization according to X.683</p> - <p>(Own Id: OTP-3978)</p> - </item> - <item> - <p>PER: Now supporting most common use of Information Objects according to X.681. A new parser has been implemented. The error messages due to syntax errors are slightly different than previous. TableConstraint part of X.682 now also supported.</p> - <p>Own Id: OTP-3979</p> - </item> - <item> - <p>New compiler option added: <c>ber_bin</c>. The compiler generates code with new bit syntax. Run time functions uses bit syntax when feasible. Higher encoding/decoding performance in most cases. Se also comments for Asn1 1.2.9.3.</p> - <p>Own Id: OTP-3981</p> - </item> - <item> - <p>A more compact format of BIT STRING in Erlang is now available by use of the compiler option <c>compact_bit_string</c>. It is much faster when large BIT STRINGs are used.</p> - <p>Own Id: OTP-3982</p> - </item> - <item> - <p>Now possible to merge many ASN.1 input files to one Erlang file by use of a configuration file that lists the ASN.1 files.</p> - <p>Own Id: OTP-3983</p> - </item> - <item> - <p>New documentation in <em>User's Guide</em> in section:</p> - <p>3.1: New compile-time functions and options are described.</p> - <p>4.6: New compact format of BIT STRING is described.</p> - <p>4.8: Additional comments on character strings.</p> - <p>7: New section describing ASN.1 Information Objects.</p> - <p>8: New section describing Parameterization.</p> - <p><em>Reference Manual/asn1ct</em> New compile options are described.</p> - <p>Own Id: OTP-3984</p> - <p>Aux Id: OTP-3978, OTP-3979, OTP-3981, OTP-3982, OTP-3983</p> - </item> - <item> - <p>Added the functionality to invoke ASN1Mod:encode (and decode).</p> - <p>Own Id: OTP-3985</p> - </item> - <item> - <p>Performance improvements by removing not necessary use of apply when calling asn1rt:encode. Also other general improvements.</p> - <p>Own Id: OTP-3988</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.9.6</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The compiler does not check that an exported name actually exists in the ASN.1 module.</p> - <p>Own Id: OTP-3659</p> - </item> - <item> - <p>The compiler does not check that a value referenced by name does exist.</p> - <p>Own Id: OTP-3277</p> - </item> - <item> - <p>BER: The compiler does not take the extensions into account when checking if - the tags are unique in a SEQUENCE or SET.</p> - <p>Own Id: OTP-3304</p> - </item> - </list> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>PER: Trailing zeroes in a BIT STRING declared without named bits - should not be removed in the encodings.</p> - <p>Own Id: OTP-3830</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.9.5</title> - - <section> - <title>Known problems</title> - <p>Same as for 1.2.9.3.</p> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>PER: Constraints are not propagated when types are - referring to each other. Example:</p> - <code type="none"> - - TBCD-STRING ::= OCTET STRING - - LAI ::= TBCD-STRING (SIZE(3)) </code> - <p>The size constraint is not passed on during encode,decode - resulting in wrong encoding for PER , it is - coded with a length determinant which should not be there - when the length is fixed. For BER this does not matter because the constraints does - not affect the encodings.</p> - <p>Own Id: OTP-3713</p> - </item> - <item> - <p>The generated code gets wrong if there are several ENUMERATED fields in a SEQUENCE or SET, this is now corrected.</p> - <p>Own Id: OTP-3796</p> - </item> - <item> - <p>BER:Decode of a type T ::= SEQUENCE OF C fails if C is encoded with indefinite length. - This is know corrected.</p> - <p>Own Id: OTP-3811</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.9.3</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The compiler does not check that an exported name actually exists in the ASN.1 module.</p> - <p>Own Id: OTP-3659</p> - </item> - <item> - <p>The compiler does not check that a value referenced by name does exist.</p> - <p>Own Id: OTP-3277</p> - </item> - <item> - <p>BER: The compiler does not take the extensions into account when checking if - the tags are unique in a SEQUENCE or SET.</p> - <p>Own Id: OTP-3304</p> - </item> - </list> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>This version supports soft upgrade from versions 1.2.6 1.2.7.</p> - </item> - <item> - <p>In an ENUMERATED type like this:</p> - <code type="none"> -\011\011T ::= ENUMERATED { blue, green} </code> - <p>The symbols was encoded/decoded with the wrong values, i.e in - reverse order. This is now corrected.</p> - <p>Own Id: OTP-3700</p> - </item> - <item> - <p>PER: OCTET STRING with Size constrained to a single value i.e fixed size - was treated wrong during encode and decode. This is now corrected.</p> - <p>Own Id: OTP-3701</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>There is now a new compiler option <c>ber_bin</c> available that can be used to - generate encode/decode functions for BER that uses the new "bit-syntax" to - make the functions more efficient. The <c>ber_bin</c> option is used - as an alternative to the <c>ber</c> and <c>per</c> options.</p> - <p>The encode function then produces a - possibly nested list of binaries and integer lists. The decode function does - in this case require a single binary as input instead of a list. - The modules generated with this option require that you have an R7A or later - system, otherwise they will not compile and the runtime module asn1rt_ber_bin - can not be executed.</p> - <p>The ber_bin option is not officially supported in this version (will be - in a later version) but is provided for those who want to try it. - It should be significantly faster at decode and is slightly faster at encode. - Exactly how performance differs between this binary approach and the - list approach depends highly on the type of input. - Another thing worth noting is that both approaches still have a lot of - solutions in common which can be improved a lot to gain even better - performance.</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.9.2</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>BER: Encode/decode of extension components did not work properly. This is now corrected.</p> - <p>Own Id: OTP-3395</p> - <p>Aux Id: </p> - <p>PER:The encode/decode of NULL as an open type has been corrected. An open type must always have a length of at least 1 byte even if the contained - value (e.g NULL) encodes to nothing.</p> - <p>Own Id: OTP-3496</p> - <p>Aux Id: </p> - </item> - <item> - <p>BER:In the current implementation extension components of a SEQUENCE are required - to be present when they are specified as mandatory. This is an error, all extension - components are "optional" even if they are not specified to have the OPTIONAL or - DEFAULT property. This is now corrected.</p> - <p>Own Id: OTP-3278</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>The ASN.1 language feature <c>COMPONENTS OF</c> is now implemented.</p> - <p>Own Id: OTP-2515</p> - </item> - <item> - <p>The encoding and decoding of ENUMERATED and - INTEGER with NamedNumbers is made more efficient and thus - faster in runtime.</p> - <p>Own Id: OTP-3464</p> - <p>Aux Id:</p> - </item> - <item> - <p>Added support for encode/decode of open type which is - constrained to a specific type. Previously the value of - an open type had to be a list of octets, but now the Erlang - representation of the specific type used in the constraint - is used both as input to encode and as output from decode.</p> - <p>Own Id: OTP-3569</p> - <p>Aux Id: </p> - </item> - <item> - <p>PER: GeneralString, GraphicalString etc. i.e all strings - that are not so called "known-multiplier character - string types" are now supported by the runtime - encode/decode functions.</p> - <p>Own Id: OTP-3573</p> - <p>Aux Id:</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.6</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The ASN.1 language feature <c>COMPONENTS OF</c> is not implemented.</p> - <p>Own Id: OTP-2515</p> - </item> - <item> - <p>The compiler does not check that a value referenced by name does exist.</p> - <p>Own Id: OTP-3277</p> - </item> - <item> - <p>BER:In the current implementation extension components of a SEQUENCE are required - to be present when they are specified as mandatory. This is an error, all extension - components are "optional" even if they are not specified to have the OPTIONAL or - DEFAULT property.</p> - <p>Own Id: OTP-3278</p> - </item> - <item> - <p>BER: The compiler does not take the extensions into account when checking if - the tags are unique in a SEQUENCE or SET.</p> - <p>Own Id: OTP-3304</p> - </item> - </list> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>This version supports soft upgrade from versions 1.1.1, 1.1.5 and 1.1.6. - Two new runtime modules <c>asn1rt_ber_v1</c> and - <c>asn1rt_per_v1</c> are delivered together with the old ones. This makes - it possible to continue running applications with modules generated with the - previous version of the asn1 compiler while modules generated by this version - will use the new runtime modules. Note that it is only advice-able to continue - running old generates if they are working perfectly and have no need - for the corrections made in this version of the asn1 application.</p> - </item> - <item> - <p>BER: SEQUENCEs encoded with indefinite length was not correctly decoded. - This in now corrected.</p> - <p>Own Id: OTP-3352</p> - <p>Aux Id: Seq 4100</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.2.4</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The compiler now detects multiple definitions of values and types and reports this as - an error. Previously this was detected when the generated Erlang module was compiled.</p> - <p>Own Id: OTP-3105</p> - </item> - <item> - <p>BER: An error regarding encoding of <c>ENUMERATED</c> present in asn1-1.1.1 - is corrected. The new version 1.1.2 of asn1 containing this correction is - delivered as a "patch".</p> - <p>Own Id: OTP-3169</p> - </item> - <item> - <p>BER: Decoding of <c>SEQUENCE OF</c> and <c>SET OF</c> with indefinite length is corrected. - The correction was first delivered in version 1.1.2.</p> - <p>Own Id: OTP-3170</p> - </item> - <item> - <p>BER: Encoding and decoding of <c>ENUMERATED</c> - with extensionmark - "..." did not work (crashed with a runtime error). This - has now been corrected. If an unknown enumerated value is - decoded (for an extensible enumerated type) - it is returned as <c>{asn1_enum,Value}</c> where - <c>Value</c> is an integer. Enumerated values in this format - are also accepted by the encoder. - ASN.1 modules containing - <c>ENUMERATED</c> with extensionmark should be - recompiled with the corrected - version of the compiler. The BER runtime functions are also - corrected. - Note that this correction has already been delivered as a - bugfix for R4B (OTP-2951).</p> - <p>Own Id: OTP-3202</p> - <p>Aux Id: Seq3745</p> - </item> - <item> - <p>BER: The primitive/constructed bit in the tag byte of an encoding - is not correct when it comes to user defined tags. - For example in </p> - <code type="none"> - T ::= [2] SEQUENCE { a BOOLEAN} </code> - <p>the tag 2 does not get the constructed bit set which it should. - This is now corrected.</p> - <p>Own Id: OTP-3241</p> - </item> - <item> - <p>The decoder can now detect if there are unexpected bytes - remaining when all components of a sequence are decoded. - The decoder will then return <c>{error,{asn1{unexpected,Bytes}}}</c></p> - <p>Own Id: OTP-3270</p> - </item> - <item> - <p>Values of type <c>OBJECT IDENTIFIER</c> was sometimes returned as an Erlang list - (ASN.1 constants) and sometimes as a tuple (from the decode functions). This is now - changed so that <c>OBJECT IDENTIFIER</c> values always are represented as an Erlang - tuple.</p> - <p>Own Id: OTP-3280</p> - </item> - <item> - <p>PER:The encode/decode functions could not handle integers with - a range greater than 16#7ffffff. This limit is now removed.</p> - <p>Own Id: OTP-3287</p> - </item> - <item> - <p>PER: The encoding/decoding of the length for a SET OF/SEQUENCE OF - was wrong if there was a size constraint. This is now corrected.</p> - <p>Own Id: OTP-3291</p> - </item> - <item> - <p>PER: Encoding of a constrained INTEGER (range > 16 k) was wrong for - the value 0. This is now corrected.</p> - <p>Own Id: OTP-3306</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>The ASN.1 module name and the filename where the ASN.1 - specification resides must match each other (has always been the - case). This is now checked by the compiler. The check requires that - the names match in a case or case insensitive way depending on the - characteristics for the current system.</p> - <p>Own Id: OTP-1843</p> - </item> - <item> - <p>PER: Encode/decode of an extension value (i.e not within the root set) for - <c>ENUMERATED</c> did not work properly. This is now corrected. - If an unknown enumerated value is - decoded (for an extensible enumerated type) - it is returned as <c>{asn1_enum,Value}</c> where - <c>Value</c> is an integer. Enumerated values in this format - are also accepted by the encoder (if the value is >= the number of known - extension values).</p> - <p>Own Id: OTP-2930</p> - </item> - <item> - <p>Unnecessary printouts from the compiler are removed. - The compiler version and the compiler options are now - printed to stdout.</p> - <p>Own Id: OTP-3276</p> - </item> - <item> - <p>In order to better suite the use of ASN.1 in embedded systems only - the modules needed in runtime are now listed in the <c>.app</c> file.</p> - <p>Own Id: OTP-3279</p> - </item> - <item> - <p>The compiler now supports extensionmarker in constraint specifications. - Example:</p> - <code type="none"> -INTEGER (0..10, ...) </code> - <p>In previous version this was reported as a syntax error.</p> - <p>Own Id: OTP-3281</p> - </item> - <item> - <p>A very limited part of ITU-T recommendation X.681 - Abstract Syntax Notation One (ASN.1): Information - object specification is now implemented. Specifically \011 - TYPE IDENTIFIER is recognized by the compiler.</p> - <p>Own Id: OTP-3325</p> - </item> - <item> - <p>Parameterization of ASN.1 specifications (ITU-T X.683) is now - supported to a limited extent.</p> - <p>Own Id: OTP-3326</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.1.3.1</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>BER Encoding and decoding of <c>ENUMERATED</c> - with extensionmark - "..." did not work (crashed with a runtime error). This - has now been corrected. If an unknown enumerated value is - decoded (for an extensible enumerated type) - it is returned as <c>{asn1_enum,Value}</c> where - <c>Value</c> is an integer. Enumerated values in this format - are also accepted by the encoder. - ASN.1 modules containing - <c>ENUMERATED</c> with extensionmark should be - recompiled with the corrected - version of the compiler. The BER runtime functions are also - corrected. - Note that this correction has already been delivered as a - bug-fix for R4B (OTP-2951).</p> - <p>Own Id: OTP-3202</p> - <p>Aux Id: Seq3745</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.1.1</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The syntactic construct <c>COMPONENTS OF</c> is not - implemented.</p> - <p>Own Id: OTP-2515</p> - </item> - <item> - <p><c>ANY</c> and <c>ANY DEFINED BY</c> are currently not - supported.</p> - <p>Own Id: OTP-2741</p> - <p>Aux Id: seq 1188</p> - </item> - <item> - <p>Multiple definitions of the same Type or Value is not detected - by the compiler. The error occurs when the generated Erlang - module is compiled.</p> - <p>Own Id: OTP-3105</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.1</title> - - <section> - <title>Known problems</title> - <list type="bulleted"> - <item> - <p>The primitive/constructed bit in the tag byte of an encoding - is not correct when it comes to user defined tags. - For example in</p> - <code type="none"> - T ::= [2] SEQUENCE { a BOOLEAN} </code> - <p>the tag 2 does not get the constructed bit set which it should. - This is now corrected.</p> - <p>Own Id: OTP-3241</p> - </item> - </list> - </section> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The BER decoder failed to decode certain nested data types - where <c>IMPLICIT</c> tags where involved. - This is now corrected.</p> - <p>Own Id: OTP-2719</p> - <p>Aux Id: seq 1148</p> - </item> - <item> - <p>The handling of types with extension marker "..." is corrected. - Earlier each SEQUENCE and SET with an extension marker got an - extra field named <c>asn1_EXT</c> in the generated record. - This was a mistake and that field is now removed (concerns - both BER and BER).</p> - <p>Own Id: OTP-2724</p> - <p>Aux Id: seq 1148, OTP-2719</p> - </item> - <item> - <p>The decoder (both BER and PER) could not handle unnamed - bits of a <c>BIT STRING</c> if the type had any - named bits declared. This is now corrected and the unnamed - bits are returned as <c>{bit,Pos}</c> where Pos is the bit - position. The <c>{bit,Pos}</c> can be used as input to the - encoder too.</p> - <p>Own Id: OTP-2725</p> - <p>Aux Id: seq 1148,OTP-2719,OTP-2724</p> - </item> - <item> - <p>The functions <c>asn1rt:decode</c> and <c>asn1ct:decode</c> - did not always return <c>{ok,Result}</c> or - <c>{error,Reason}</c> as documented. This is now corrected.</p> - <p>Own Id: OTP-2730</p> - <p>Aux Id: seq 1158</p> - </item> - <item> - <p>The compiler did not accept CHOICE types as components - of a SEQUENCE or SET when - the modules tag default was IMPLICIT. - Example:</p> - <code type="none"> -C ::= CHOICE { ......} -A ::= SEQUENCE { -a [1] C, -- This was not accepted -..... </code> - <p>This was an error - caused by a misinterpretation of the ASN.1 standard. This - is now corrected.</p> - <p>Own Id: OTP-2731</p> - <p>Aux Id: seq 1163</p> - </item> - <item> - <p>When decoding a SEQUENCE A which contains an OPTIONAL component - b which is a SEQUENCE with mandatory components, the decoder - does not detect as an error that a mandatory component of b - is missing. The same error could occur also in other cases - with nested types and optional components of SEQUENCE or SET. - This is now corrected.</p> - <p>Own Id: OTP-2738</p> - <p>Aux Id: seq 1183</p> - </item> - <item> - <p>BER Encoding and decoding of <c>ENUMERATED</c> - with extensionmark - "..." did not work (crashed with a runtime error). This - has now been corrected. If an unknown enumerated value is - decoded (for an extensible enumerated type) - it is returned as <c>{asn1_enum,Value}</c> where - <c>Value</c> is an integer. Enumerated values in this format - are also accepted by the encoder. - ASN.1 modules containing - <c>ENUMERATED</c> with extensionmark should be - recompiled with the corrected - version of the compiler. The BER runtime functions are also - corrected.</p> - <p>Own Id: OTP-2951</p> - <p>Aux Id: Seq 1446 OTP-2929</p> - </item> - <item> - <p>The compiler does now accept all valid value notations - for the OBJECT IDENTIFIER type. The generated code for - those values is also corrected.</p> - <p>Own Id: OTP-3059</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>The code generated for BER is significantly enhanced resulting - in less code and around 300% better performance in runtime - for the encoding of complex ASN.1 values. The performance of - decoding is unchanged.</p> - <p>Own Id: OTP-2806</p> - </item> - </list> - </section> - </section> - - <section> - <title>Asn1 1.0.3</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The <c>asn1.app</c> file is corrected.</p> - <p>Own Id: OTP-2640</p> - </item> - <item> - <p>The encoding of integers in BER did not comply with the - standard for all values. The values was not encoded - in the minimum number of octets as required. This is - now corrected in the runtime module <c>asn1rt_ber</c>.</p> - <p>Own Id: OTP-2666</p> - </item> - </list> - </section> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>The compiler now generates explicit exports directives for - all generated - functions that should be exported (instead of -compile(export_all)). - This eliminates the warnings from the Erlang compiler when - compiling the - generated file.</p> - <p>Own Id: OTP-1845</p> - </item> - </list> - </section> - </section> - - <section> - <title>R3B02 (Asn1 1.0.2)</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The decoding of a BER encoded SEQUENCE with optional component - of type SEQUENCE (also with optional components) could result - in an error or wrong result if the tags are equal.</p> - <p>Own Id: OTP-2226</p> - </item> - <item> - <p>The encoding of (PER) SEQUENCE with extensionmark was wrong. - This is now corrected.</p> - <p>Own Id: OTP-2349</p> - </item> - </list> - </section> - </section> - - <section> - <title>R3A (Asn1 0.9)</title> - - <section> - <title>Fixed errors and malfunctions</title> - <list type="bulleted"> - <item> - <p>The asn1 compiler now detects the use of an implicit tag before <c>CHOICE</c> as an error (in accordance with the standard)</p> - <p>Own Id: OTP-1844</p> - </item> - <item> - <p>An OPTIONAL CHOICE embedded in SEQUENCE when BER coding - caused an error when generating decode code. This is now - corrected.</p> - <p>Own Id: OTP-1857</p> - <p>Aux Id: OTP-1848</p> - </item> - </list> - </section> - </section> - - <section> - <title>1 ASN1 0.8.1</title> - <p>This is the first release of the ASN1 application. This version is - released for beta-testing. Some functionality will be added until the - 1.0 version is released. See the release notes for the latest version - for the exact details about new features. A list of missing features - and restrictions can be found in the chapter below.</p> - - <section> - <title>1.1 Missing features and other restrictions</title> - <p></p> - <list type="bulleted"> - <item> - <p>The encoding rules BER and PER (aligned) is supported. <em>PER (unaligned) IS NOT SUPPORTED</em>.</p> - </item> - <item> - <p>NOT SUPPORTED types <c>ANY</c> and <c>ANY DEFINED BY</c> - (is not in the standard any more).</p> - </item> - <item> - <p>NOT SUPPORTED types <c>EXTERNAL</c> and <c>EMBEDDED-PDV</c>. </p> - </item> - <item> - <p>NOT SUPPORTED type <c>REAL</c> (planned to be implemented). </p> - </item> - <item> - <p>The code generation support for value definitions in the ASN.1 notation is very limited - (planned to be enhanced).</p> - </item> - <item> - <p>The support for constraints is limited to:</p> - </item> - </list> - <list type="bulleted"> - <item> - <p>SizeConstraint SIZE(X)</p> - </item> - <item> - <p>SingleValue (1)</p> - </item> - <item> - <p>ValueRange (X..Y)</p> - </item> - <item> - <p>PermittedAlpabet FROM (but not for BMPString and UniversalString when generating PER).</p> - </item> - <item> - <p>Complex expressions in constraints is not supported (planned to be extended).</p> - </item> - <item> - <p>The current version of the compiler has very limited error checking:</p> - </item> - <item> - <p>Stops at first syntax error.</p> - </item> - <item> - <p>Does not stop when a reference to an undefined type is found , - but prints an error message. Compilation of the generated - Erlang module will then fail.</p> - </item> - <item> - <p>A whole number of other semantical controls is currently - missing. This means that the compiler will give little - or bad help to detect what's wrong with an ASN.1 - specification, but will mostly work very well when the - ASN.1 specification is correct.</p> - </item> - </list> - <list type="bulleted"> - <item> - <p>The maximum INTEGER supported in this version is a - signed 64 bit integer. This limitation is probably quite - reasonable. (Planned to be extended).</p> - </item> - <item> - <p>Only AUTOMATIC TAGS supported for PER.</p> - </item> - <item> - <p>Only EXPLICIT and IMPLICIT TAGS supported for BER.</p> - </item> - <item> - <p>The compiler supports decoding of BER-data with indefinite - length but it is not possible to produce data with indefinite - length with the encoder.</p> - </item> - </list> - </section> - </section> -</chapter> - diff --git a/lib/asn1/doc/src/part_notes.xml b/lib/asn1/doc/src/part_notes.xml deleted file mode 100644 index b0a6887aa5..0000000000 --- a/lib/asn1/doc/src/part_notes.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE part SYSTEM "part.dtd"> - -<part xmlns:xi="http://www.w3.org/2001/XInclude"> - <header> - <copyright> - <year>2004</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>Asn1 Release Notes</title> - <prepared>Ingela Anderton Andin</prepared> - <docno></docno> - <date>>2004-09-07</date> - <rev></rev> - <file>part_notes.sgml</file> - </header> - <description> - <p>The <em>Asn1</em> application - contains modules with compile-time and run-time support for ASN.1.</p> - <p>There are also release notes for - <url href="notes_history.html">older versions</url>.</p> - </description> - <xi:include href="notes.xml"/> -</part> - diff --git a/lib/asn1/doc/src/warning.gif b/lib/asn1/doc/src/warning.gif Binary files differdeleted file mode 100644 index 96af52360e..0000000000 --- a/lib/asn1/doc/src/warning.gif +++ /dev/null diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 90d25d87b2..497c4fa07b 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -150,7 +150,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) -> %% Create IFF chunk. Chunks = case member(slim, Opts) of - true -> [Essentials,AttrChunk,CompileChunk,AbstChunk]; + true -> [Essentials,AttrChunk,AbstChunk]; false -> [Essentials,LocChunk,AttrChunk,CompileChunk,AbstChunk] end, build_form(<<"BEAM">>, Chunks). diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index d8c201a194..dcc6ad4c7c 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -123,6 +123,12 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) -> throw:mixed -> failed; + %% There was a reference to a boolean expression + %% from inside a protected block (try/catch), to + %% a boolean expression outside. + throw:protected_barrier -> + failed; + %% The 'xor' operator was used. We currently don't %% find it worthwile to translate 'xor' operators %% (the code would be clumsy). @@ -167,7 +173,7 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) -> %% whether the optimized code is guaranteed to work in the same %% way as the original code. %% -%% Throws an exception if the optmization is not safe. +%% Throw an exception if the optimization is not safe. %% ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) -> %% Here are the conditions that must be true for the @@ -184,10 +190,10 @@ ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) -> %% by the code that follows. %% %% 3. Any register that is assigned a value in the optimized - %% code must be UNUSED or KILLED in the following code. - %% (Possible future improvement: Registers that are known - %% to be assigned the SAME value in the original and optimized - %% code don't need to be unused in the following code.) + %% code must be UNUSED or KILLED in the following code + %% (because the register might be assigned the wrong value, + %% and even if the value is right it might no longer be + %% assigned on *all* paths leading to its use). InitInPreceeding = initialized_regs(PreceedingCode), @@ -304,6 +310,8 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) -> dst_regs(Is, [D|Acc]); dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) -> dst_regs(Is, [D|Acc]); +dst_regs([{set,[D],_,move}|Is], Acc) -> + dst_regs(Is, [D|Acc]); dst_regs([_|Is], Acc) -> dst_regs(Is, Acc); dst_regs([], Acc) -> ordsets:from_list(Acc). @@ -414,11 +422,10 @@ bopt_good_args([A|As], Regs) -> bopt_good_args([], _) -> ok. bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp -> - case gb_trees:get(X, Regs) of - any -> ok; - _Other -> - %%io:format("not any: ~p: ~p\n", [X,_Other]), - throw(mixed) + case gb_trees:lookup(X, Regs) of + {value,any} -> ok; + {value,_} -> throw(mixed); + none -> throw(protected_barrier) end; bopt_good_arg(_, _) -> ok. diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl index 34609a49f2..a460d54239 100644 --- a/lib/compiler/test/andor_SUITE.erl +++ b/lib/compiler/test/andor_SUITE.erl @@ -20,13 +20,14 @@ -export([all/1, t_case/1,t_and_or/1,t_andalso/1,t_orelse/1,inside/1,overlap/1, - combined/1,in_case/1]). + combined/1,in_case/1,before_and_inside_if/1]). -include("test_server.hrl"). all(suite) -> test_lib:recompile(?MODULE), - [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,combined,in_case]. + [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,combined,in_case, + before_and_inside_if]. t_case(Config) when is_list(Config) -> %% We test boolean cases almost but not quite like cases @@ -380,6 +381,65 @@ in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) -> false -> loop end. +before_and_inside_if(Config) when is_list(Config) -> + ?line no = before_and_inside_if([a], [b], delete), + ?line no = before_and_inside_if([a], [b], x), + ?line no = before_and_inside_if([a], [], delete), + ?line no = before_and_inside_if([a], [], x), + ?line no = before_and_inside_if([], [], delete), + ?line yes = before_and_inside_if([], [], x), + ?line yes = before_and_inside_if([], [b], delete), + ?line yes = before_and_inside_if([], [b], x), + + ?line {ch1,ch2} = before_and_inside_if_2([a], [b], blah), + ?line {ch1,ch2} = before_and_inside_if_2([a], [b], xx), + ?line {ch1,ch2} = before_and_inside_if_2([a], [], blah), + ?line {ch1,ch2} = before_and_inside_if_2([a], [], xx), + ?line {no,no} = before_and_inside_if_2([], [b], blah), + ?line {no,no} = before_and_inside_if_2([], [b], xx), + ?line {ch1,no} = before_and_inside_if_2([], [], blah), + ?line {no,ch2} = before_and_inside_if_2([], [], xx), + ok. + +%% Thanks to Simon Cornish and Kostis Sagonas. +%% Used to crash beam_bool. +before_and_inside_if(XDo1, XDo2, Do3) -> + Do1 = (XDo1 =/= []), + Do2 = (XDo2 =/= []), + if + %% This expression occurs in a try/catch (protected) + %% block, which cannot refer to variables outside of + %% the block that are boolean expressions. + Do1 =:= true; + Do1 =:= false, Do2 =:= false, Do3 =:= delete -> + no; + true -> + yes + end. + +%% Thanks to Simon Cornish. +%% Used to generate code that would not set {y,0} on +%% all paths before its use (and therefore fail +%% validation by the beam_validator). +before_and_inside_if_2(XDo1, XDo2, Do3) -> + Do1 = (XDo1 =/= []), + Do2 = (XDo2 =/= []), + CH1 = if Do1 == true; + Do1 == false,Do2==false,Do3 == blah -> + ch1; + true -> + no + end, + CH2 = if Do1 == true; + Do1 == false,Do2==false,Do3 == xx -> + ch2; + true -> + no + end, + {CH1,CH2}. + +%% Utilities. + check(V1, V0) -> if V1 /= V0 -> io:fwrite("error: ~w.\n", [V1]), @@ -393,5 +453,3 @@ echo(X) -> X. id(I) -> I. - - diff --git a/lib/compiler/test/compilation_SUITE_data/on_load.erl b/lib/compiler/test/compilation_SUITE_data/on_load.erl index 92bcf74624..e9b5ec7f34 100644 --- a/lib/compiler/test/compilation_SUITE_data/on_load.erl +++ b/lib/compiler/test/compilation_SUITE_data/on_load.erl @@ -12,7 +12,7 @@ do_on_load() -> local_function(), - true. + ok. local_function() -> ok. diff --git a/lib/crypto/c_src/crypto_drv.c b/lib/crypto/c_src/crypto_drv.c index 241c4ec733..5b6d750dde 100644 --- a/lib/crypto/c_src/crypto_drv.c +++ b/lib/crypto/c_src/crypto_drv.c @@ -233,6 +233,11 @@ static ErlDrvEntry crypto_driver_entry = { #define DRV_BF_CFB64_ENCRYPT 59 #define DRV_BF_CFB64_DECRYPT 60 +#define DRV_BF_ECB_ENCRYPT 61 +#define DRV_BF_ECB_DECRYPT 62 +#define DRV_BF_OFB64_ENCRYPT 63 +#define DRV_BF_CBC_ENCRYPT 64 +#define DRV_BF_CBC_DECRYPT 65 /* #define DRV_CBC_IDEA_ENCRYPT 34 */ /* #define DRV_CBC_IDEA_DECRYPT 35 */ @@ -533,6 +538,79 @@ static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf, (command == DRV_CBC_DES_ENCRYPT)); return dlen; + case DRV_BF_ECB_ENCRYPT: + case DRV_BF_ECB_DECRYPT: + { + /* buf = klen[4] key data */ + int bf_direction; + const unsigned char *ukey; + const unsigned char *bf_dbuf; /* blowfish input data */ + BF_KEY bf_key; /* blowfish key 8 */ + + klen = get_int32(buf); + ukey = (unsigned char *) buf + 4; + bf_dbuf = ukey + klen; + dlen = len - 4 - klen; + if (dlen < 0) return -1; + BF_set_key(&bf_key, klen, ukey); + bin = return_binary(rbuf,rlen,dlen); + if (bin==NULL) return -1; + bf_direction = command == DRV_BF_ECB_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT; + BF_ecb_encrypt(bf_dbuf, bin, &bf_key, bf_direction); + return dlen; + } + + case DRV_BF_CBC_ENCRYPT: + case DRV_BF_CBC_DECRYPT: + { + /* buf = klen[4] key ivec[8] data */ + unsigned char *ukey; + unsigned char* ivec; + unsigned char bf_tkey[8]; /* blowfish ivec */ + int bf_direction; + const unsigned char *bf_dbuf; /* blowfish input data */ + BF_KEY bf_key; /* blowfish key 8 */ + + klen = get_int32(buf); + ukey = (unsigned char *)buf + 4; + ivec = ukey + klen; + bf_dbuf = ivec + 8; + dlen = len - 4 - klen - 8; + if (dlen < 0) return -1; + BF_set_key(&bf_key, klen, ukey); + memcpy(bf_tkey, ivec, 8); + bin = return_binary(rbuf,rlen,dlen); + if (bin==NULL) return -1; + bf_direction = command == DRV_BF_CBC_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT; + BF_cbc_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, bf_direction); + return dlen; + } + + case DRV_BF_OFB64_ENCRYPT: + { + /* buf = klen[4] key ivec[8] data */ + unsigned char *ukey; + unsigned char* ivec; + unsigned char bf_tkey[8]; /* blowfish ivec */ + int bf_n; /* blowfish ivec pos */ + const unsigned char *bf_dbuf; /* blowfish input data */ + BF_KEY bf_key; /* blowfish key 8 */ + + klen = get_int32(buf); + ukey = (unsigned char *)buf + 4; + ivec = ukey + klen; + bf_dbuf = ivec + 8; + dlen = len - 4 - klen - 8; + if (dlen < 0) return -1; + BF_set_key(&bf_key, klen, ukey); + memcpy(bf_tkey, ivec, 8); + bin = return_binary(rbuf,rlen,dlen); + if (bin==NULL) return -1; + bf_n = 0; + BF_ofb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n); + return dlen; + } + case DRV_BF_CFB64_ENCRYPT: case DRV_BF_CFB64_DECRYPT: { diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 42ba523c8c..cfc6996332 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -337,6 +337,53 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <c>Key3</c>, and <c>IVec</c> must be 64 bits (8 bytes).</p> </desc> </func> + + <func> + <name>blowfish_ecb_encrypt(Key, Text) -> Cipher</name> + <fsummary>Encrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Encrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p> + </desc> + <name>blowfish_ecb_decrypt(Key, Text) -> Cipher</name> + <fsummary>Decrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Decrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p> + </desc> + </func> + + <func> + <name>blowfish_cbc_encrypt(Key, Text) -> Cipher</name> + <fsummary>Encrypt <c>Text</c> using Blowfish in CBC mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Encrypts <c>Text</c> using Blowfish in CBC mode. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an + arbitrary initializing vector. The length of <c>IVec</c> + must be 64 bits (8 bytes). The length of <c>Text</c> must be a multiple of 64 bits (8 bytes).</p> + </desc> + <name>blowfish_cbc_decrypt(Key, Text) -> Cipher</name> + <fsummary>Decrypt <c>Text</c> using Blowfish in CBC mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Decrypts <c>Text</c> using Blowfish in CBC mode. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an + arbitrary initializing vector. The length of <c>IVec</c> + must be 64 bits (8 bytes). The length of <c>Text</c> must be a multiple 64 bits (8 bytes).</p> + </desc> + </func> + <func> <name>blowfish_cfb64_encrypt(Key, IVec, Text) -> Cipher</name> <fsummary>Encrypt <c>Text</c>using Blowfish in CFB mode with 64 @@ -367,6 +414,23 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> must be 64 bits (8 bytes).</p> </desc> </func> + + <func> + <name>blowfish_ofb64_encrypt(Key, IVec, Text) -> Cipher</name> + <fsummary>Encrypt <c>Text</c>using Blowfish in OFB mode with 64 + bit feedback</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Encrypts <c>Text</c> using Blowfish in OFB mode with 64 bit + feedback. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an + arbitrary initializing vector. The length of <c>IVec</c> + must be 64 bits (8 bytes).</p> + </desc> + </func> + <func> <name>aes_cfb_128_encrypt(Key, IVec, Text) -> Cipher</name> <name>aes_cbc_128_encrypt(Key, IVec, Text) -> Cipher</name> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 5189677dd0..fa33bad2e0 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -30,7 +30,10 @@ -export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac_96/2]). -export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]). -export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]). --export([blowfish_cfb64_encrypt/3,blowfish_cfb64_decrypt/3]). +-export([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]). +-export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]). +-export([blowfish_cfb64_encrypt/3, blowfish_cfb64_decrypt/3]). +-export([blowfish_ofb64_encrypt/3]). -export([des_ede3_cbc_encrypt/5, des_ede3_cbc_decrypt/5]). -export([aes_cfb_128_encrypt/3, aes_cfb_128_decrypt/3]). -export([exor/2]). @@ -115,6 +118,11 @@ -define(BF_CFB64_ENCRYPT, 59). -define(BF_CFB64_DECRYPT, 60). +-define(BF_ECB_ENCRYPT, 61). +-define(BF_ECB_DECRYPT, 62). +-define(BF_OFB64_ENCRYPT, 63). +-define(BF_CBC_ENCRYPT, 64). +-define(BF_CBC_DECRYPT, 65). %% -define(IDEA_CBC_ENCRYPT, 34). %% -define(IDEA_CBC_DECRYPT, 35). @@ -303,12 +311,27 @@ des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) -> %% %% Blowfish %% +blowfish_ecb_encrypt(Key, Data) when byte_size(Data) >= 8 -> + control_bin(?BF_ECB_ENCRYPT, Key, list_to_binary([Data])). + +blowfish_ecb_decrypt(Key, Data) when byte_size(Data) >= 8 -> + control_bin(?BF_ECB_DECRYPT, Key, list_to_binary([Data])). + +blowfish_cbc_encrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 -> + control_bin(?BF_CBC_ENCRYPT, Key, list_to_binary([IVec, Data])). + +blowfish_cbc_decrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 -> + control_bin(?BF_CBC_DECRYPT, Key, list_to_binary([IVec, Data])). + blowfish_cfb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> control_bin(?BF_CFB64_ENCRYPT, Key, list_to_binary([IVec, Data])). blowfish_cfb64_decrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> control_bin(?BF_CFB64_DECRYPT, Key, list_to_binary([IVec, Data])). +blowfish_ofb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 -> + control_bin(?BF_OFB64_ENCRYPT, Key, list_to_binary([IVec, Data])). + %% %% AES in cipher feedback mode (CFB) %% diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile new file mode 100644 index 0000000000..e728875027 --- /dev/null +++ b/lib/crypto/test/Makefile @@ -0,0 +1,83 @@ +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES = \ + blowfish_SUITE \ + crypto_SUITE + +ERL_FILES= $(MODULES:%=%.erl) + +TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +SOURCE = $(ERL_FILES) $(HRL_FILES) + +EMAKEFILE=Emakefile + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/crypto_test + + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_MAKE_FLAGS += +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include + +EBIN = . +MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile) + + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +# Backward compatibility, for R9B and earlier. + +ifeq ($(MAKE_EMAKE),) + +RELTEST_FILES = $(SOURCE) $(TARGET_FILES) +TEST_TARGET = tests + +tests debug opt: $(TARGET_FILES) + +else + +RELTEST_FILES = $(EMAKEFILE) $(SOURCE) +TEST_TARGET = make_emakefile + + +tests debug opt: make_emakefile + erl $(ERL_MAKE_FLAGS) -make + +make_emakefile: + $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \ + $(MODULES) > $(EMAKEFILE) + +endif +clean: + rm -f $(EMAKEFILE) + rm -f $(TARGET_FILES) $(GEN_FILES) + rm -f core + +docs: + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_tests_spec: $(TEST_TARGET) + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) crypto.spec $(RELTEST_FILES) $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) + +release_docs_spec: + diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl new file mode 100644 index 0000000000..d4cc167ea9 --- /dev/null +++ b/lib/crypto/test/blowfish_SUITE.erl @@ -0,0 +1,210 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% +-module(blowfish_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). + +-define(TIMEOUT, 120000). % 2 min + +-define(KEY, to_bin("0123456789ABCDEFF0E1D2C3B4A59687")). +-define(IVEC, to_bin("FEDCBA9876543210")). +%% "7654321 Now is the time for " (includes trailing '\0') +-define(DATA, to_bin("37363534333231204E6F77206973207468652074696D6520666F722000")). +-define(DATA_PADDED, to_bin("37363534333231204E6F77206973207468652074696D6520666F722000000000")). + +%% Test server callback functions +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initialization before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config) -> + crypto:start(), + Config. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + crypto:stop(). + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initialization before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%% Description: Initialization before each test case +%%-------------------------------------------------------------------- +init_per_testcase(_TestCase, Config0) -> + Config = lists:keydelete(watchdog, 1, Config0), + Dog = test_server:timetrap(?TIMEOUT), + [{watchdog, Dog} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(_TestCase, Config) -> + Dog = ?config(watchdog, Config), + case Dog of + undefined -> + ok; + _ -> + test_server:timetrap_cancel(Dog) + end. + +%%-------------------------------------------------------------------- +%% Function: all(Clause) -> TestCases +%% Clause - atom() - suite | doc +%% TestCases - [Case] +%% Case - atom() +%% Name of a test case. +%% Description: Returns a list of all test cases in this test suite +%%-------------------------------------------------------------------- +all(doc) -> + ["Test Blowfish functionality"]; + +all(suite) -> + [ecb, + cbc, + cfb64, + ofb64 + ]. + +%% Test cases start here. +%%-------------------------------------------------------------------- + +ecb_test(KeyBytes, ClearBytes, CipherBytes) -> + {Key, Clear, Cipher} = + {to_bin(KeyBytes), to_bin(ClearBytes), to_bin(CipherBytes)}, + crypto:blowfish_ecb_encrypt(Key, Clear) =:= Cipher. + +ecb(doc) -> + "Test that ECB mode is OK"; +ecb(suite) -> + []; +ecb(Config) when is_list(Config) -> + true = ecb_test("0000000000000000", "0000000000000000", "4EF997456198DD78"), + true = ecb_test("FFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFF", "51866FD5B85ECB8A"), + true = ecb_test("3000000000000000", "1000000000000001", "7D856F9A613063F2"), + true = ecb_test("1111111111111111", "1111111111111111", "2466DD878B963C9D"), + true = ecb_test("0123456789ABCDEF", "1111111111111111", "61F9C3802281B096"), + true = ecb_test("1111111111111111", "0123456789ABCDEF", "7D0CC630AFDA1EC7"), + true = ecb_test("0000000000000000", "0000000000000000", "4EF997456198DD78"), + true = ecb_test("FEDCBA9876543210", "0123456789ABCDEF", "0ACEAB0FC6A0A28D"), + true = ecb_test("7CA110454A1A6E57", "01A1D6D039776742", "59C68245EB05282B"), + true = ecb_test("0131D9619DC1376E", "5CD54CA83DEF57DA", "B1B8CC0B250F09A0"), + true = ecb_test("07A1133E4A0B2686", "0248D43806F67172", "1730E5778BEA1DA4"), + true = ecb_test("3849674C2602319E", "51454B582DDF440A", "A25E7856CF2651EB"), + true = ecb_test("04B915BA43FEB5B6", "42FD443059577FA2", "353882B109CE8F1A"), + true = ecb_test("0113B970FD34F2CE", "059B5E0851CF143A", "48F4D0884C379918"), + true = ecb_test("0170F175468FB5E6", "0756D8E0774761D2", "432193B78951FC98"), + true = ecb_test("43297FAD38E373FE", "762514B829BF486A", "13F04154D69D1AE5"), + true = ecb_test("07A7137045DA2A16", "3BDD119049372802", "2EEDDA93FFD39C79"), + true = ecb_test("04689104C2FD3B2F", "26955F6835AF609A", "D887E0393C2DA6E3"), + true = ecb_test("37D06BB516CB7546", "164D5E404F275232", "5F99D04F5B163969"), + true = ecb_test("1F08260D1AC2465E", "6B056E18759F5CCA", "4A057A3B24D3977B"), + true = ecb_test("584023641ABA6176", "004BD6EF09176062", "452031C1E4FADA8E"), + true = ecb_test("025816164629B007", "480D39006EE762F2", "7555AE39F59B87BD"), + true = ecb_test("49793EBC79B3258F", "437540C8698F3CFA", "53C55F9CB49FC019"), + true = ecb_test("4FB05E1515AB73A7", "072D43A077075292", "7A8E7BFA937E89A3"), + true = ecb_test("49E95D6D4CA229BF", "02FE55778117F12A", "CF9C5D7A4986ADB5"), + true = ecb_test("018310DC409B26D6", "1D9D5C5018F728C2", "D1ABB290658BC778"), + true = ecb_test("1C587F1C13924FEF", "305532286D6F295A", "55CB3774D13EF201"), + true = ecb_test("0101010101010101", "0123456789ABCDEF", "FA34EC4847B268B2"), + true = ecb_test("1F1F1F1F0E0E0E0E", "0123456789ABCDEF", "A790795108EA3CAE"), + true = ecb_test("E0FEE0FEF1FEF1FE", "0123456789ABCDEF", "C39E072D9FAC631D"), + true = ecb_test("0000000000000000", "FFFFFFFFFFFFFFFF", "014933E0CDAFF6E4"), + true = ecb_test("FFFFFFFFFFFFFFFF", "0000000000000000", "F21E9A77B71C49BC"), + true = ecb_test("0123456789ABCDEF", "0000000000000000", "245946885754369A"), + true = ecb_test("FEDCBA9876543210", "FFFFFFFFFFFFFFFF", "6B5C5A9C5D9E0A5A"), + ok. + +cbc(doc) -> + "Test that CBC mode is OK"; +cbc(suite) -> + []; +cbc(Config) when is_list(Config) -> + true = crypto:blowfish_cbc_encrypt(?KEY, ?IVEC, ?DATA_PADDED) =:= + to_bin("6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"), + ok. + +cfb64(doc) -> + "Test that CFB64 mode is OK"; +cfb64(suite) -> + []; +cfb64(Config) when is_list(Config) -> + true = crypto:blowfish_cfb64_encrypt(?KEY, ?IVEC, ?DATA) =:= + to_bin("E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"), + ok. + +ofb64(doc) -> + "Test that OFB64 mode is OK"; +ofb64(suite) -> + []; +ofb64(Config) when is_list(Config) -> + true = crypto:blowfish_ofb64_encrypt(?KEY, ?IVEC, ?DATA) =:= + to_bin("E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"), + ok. + +%% Helper functions + +%% Convert a hexadecimal string to a binary. +-spec(to_bin(L::string()) -> binary()). +to_bin(L) -> + to_bin(L, []). + +%% @spec dehex(char()) -> integer() +%% @doc Convert a hex digit to its integer value. +-spec(dehex(char()) -> integer()). +dehex(C) when C >= $0, C =< $9 -> + C - $0; +dehex(C) when C >= $a, C =< $f -> + C - $a + 10; +dehex(C) when C >= $A, C =< $F -> + C - $A + 10. + +-spec(to_bin(L::string(), list()) -> binary()). +to_bin([], Acc) -> + iolist_to_binary(lists:reverse(Acc)); +to_bin([C1, C2 | Rest], Acc) -> + to_bin(Rest, [(dehex(C1) bsl 4) bor dehex(C2) | Acc]). diff --git a/lib/crypto/test/crypto.spec b/lib/crypto/test/crypto.spec new file mode 100644 index 0000000000..7ba5696189 --- /dev/null +++ b/lib/crypto/test/crypto.spec @@ -0,0 +1,2 @@ +{topcase, {dir, "../crypto_test"}}. + diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl new file mode 100644 index 0000000000..290ef19160 --- /dev/null +++ b/lib/crypto/test/crypto_SUITE.erl @@ -0,0 +1,1110 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(crypto_SUITE). + +-include("test_server.hrl"). +-include("test_server_line.hrl"). + +-export([all/1, + init_per_testcase/2, + fin_per_testcase/2, + info/1, + link_test/1, + md5/1, + md5_update/1, + md4/1, + md4_update/1, + sha/1, + sha_update/1, + sha256/1, + sha256_update/1, + sha512/1, + sha512_update/1, + md5_mac/1, + md5_mac_io/1, + des_cbc/1, + des_cbc_iter/1, + aes_cfb/1, + aes_cbc/1, + aes_cbc_iter/1, + mod_exp_test/1, + rand_uniform_test/1, + rsa_verify_test/1, + dsa_verify_test/1, + rsa_sign_test/1, + dsa_sign_test/1, + rsa_encrypt_decrypt/1, + dh/1, + exor_test/1, + rc4_test/1, + blowfish_cfb64/1, + smp/1, + cleanup/1]). + +-export([hexstr2bin/1]). + +all(suite) -> + [link_test, + {conf,info,[md5, + md5_update, + md4, + md4_update, + md5_mac, + md5_mac_io, + sha, + sha_update, +%% sha256, +%% sha256_update, +%% sha512, +%% sha512_update, + des_cbc, + aes_cfb, + aes_cbc, + aes_cbc_iter, + des_cbc_iter, + rand_uniform_test, + rsa_verify_test, + dsa_verify_test, + rsa_sign_test, + dsa_sign_test, + rsa_encrypt_decrypt, + dh, + exor_test, + rc4_test, + mod_exp_test, + blowfish_cfb64, + smp], + cleanup}]. + +init_per_testcase(_Name,Config) -> + io:format("init_per_testcase\n"), + ?line crypto:start(), + Config. + +fin_per_testcase(_Name,Config) -> + io:format("fin_per_testcase\n"), + ?line crypto:stop(), + Config. + +%% +%% +link_test(doc) -> + ["Test that the library is statically linked to libcrypto.a."]; +link_test(suite) -> + []; +link_test(Config) when is_list(Config) -> + ?line case os:type() of + {unix,darwin} -> {skipped,"Darwin cannot link statically"}; + {unix,_} -> link_test_1(); + _ -> {skip,"Only runs on Unix"} + end. + +link_test_1() -> + ?line CryptoPriv = code:priv_dir(crypto), + ?line Wc = filename:join([CryptoPriv,"lib","crypto_drv.*"]), + ?line case filelib:wildcard(Wc) of + [] -> {skip,"Didn't find the crypto driver"}; + [Drv] -> link_test_2(Drv) + end. + +link_test_2(Drv) -> + case ldd_program() of + none -> + {skip,"No ldd-like program found"}; + Ldd -> + Cmd = Ldd ++ " " ++ Drv, + Libs = os:cmd(Cmd), + io:format("~p\n", [Libs]), + case string:str(Libs, "libcrypto") of + 0 -> ok; + _ -> + case ?t:is_commercial() of + true -> + ?t:fail({libcrypto,not_statically_linked}); + false -> + {comment,"Not statically linked (OK for open-source platform)"} + end + end + end. + +ldd_program() -> + case os:find_executable("ldd") of + false -> + case os:type() of + {unix,darwin} -> + case os:find_executable("otool") of + false -> none; + Otool -> Otool ++ " -L" + end + end; + Ldd when is_list(Ldd) -> Ldd + end. + +%% +%% +info(doc) -> + ["Call the info function."]; +info(suite) -> + []; +info(Config) when is_list(Config) -> + case {code:lib_dir(crypto),?t:is_commercial()} of + {{error,bad_name},false} -> + {skip,"Missing crypto application"}; + {_,_} -> + ?line crypto:start(), + ?line crypto:info(), + ?line InfoLib = crypto:info_lib(), + ?line [_|_] = InfoLib, + F = fun([{Name,VerN,VerS}|T],Me) -> + ?line true = is_binary(Name), + ?line true = is_integer(VerN), + ?line true = is_binary(VerS), + Me(T,Me); + ([],_) -> + ok + end, + ?line F(InfoLib,F), + ?line crypto:stop() + end. + +cleanup(doc) -> + ["Cleanup (dummy)."]; +cleanup(suite) -> + []; +cleanup(Config) when is_list(Config) -> + Config. + +%% +%% +md5(doc) -> + ["Generate MD5 message digests and check the result. Examples are " + "from RFC-1321."]; +md5(suite) -> + []; +md5(Config) when is_list(Config) -> + ?line m(crypto:md5(""), + hexstr2bin("d41d8cd98f00b204e9800998ecf8427e")), + ?line m(crypto:md5("a"), + hexstr2bin("0cc175b9c0f1b6a831c399e269772661")), + ?line m(crypto:md5("abc"), + hexstr2bin("900150983cd24fb0d6963f7d28e17f72")), + ?line m(crypto:md5("message digest"), + hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0")), + ?line m(crypto:md5("abcdefghijklmnopqrstuvwxyz"), + hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b")), + ?line m(crypto:md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789"), + hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")), + ?line m(crypto:md5("12345678901234567890123456789012345678901234567890" + "123456789012345678901234567890"), + hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")). + +%% +%% +md5_update(doc) -> + ["Generate MD5 message using md5_init, md5_update, and md5_final, and" + "check the result. Examples are from RFC-1321."]; +md5_update(suite) -> + []; +md5_update(Config) when is_list(Config) -> + ?line Ctx = crypto:md5_init(), + ?line Ctx1 = crypto:md5_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), + ?line Ctx2 = crypto:md5_update(Ctx1, "abcdefghijklmnopqrstuvwxyz" + "0123456789"), + ?line m(crypto:md5_final(Ctx2), + hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")). + +%% +%% +md4(doc) -> + ["Generate MD4 message digests and check the result. Examples are " + "from RFC-1321."]; +md4(suite) -> + []; +md4(Config) when is_list(Config) -> + ?line m(crypto:md4(""), + hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0")), + ?line m(crypto:md4("a"), + hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24")), + ?line m(crypto:md4("abc"), + hexstr2bin("a448017aaf21d8525fc10ae87aa6729d")), + ?line m(crypto:md4("message digest"), + hexstr2bin("d9130a8164549fe818874806e1c7014b")), + ?line m(crypto:md4("abcdefghijklmnopqrstuvwxyz"), + hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9")), + ?line m(crypto:md4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789"), + hexstr2bin("043f8582f241db351ce627e153e7f0e4")), + ?line m(crypto:md4("12345678901234567890123456789012345678901234567890" + "123456789012345678901234567890"), + hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")). + +%% +%% +md4_update(doc) -> + ["Generate MD5 message using md5_init, md5_update, and md5_final, and" + "check the result. Examples are from RFC-1321."]; +md4_update(suite) -> + []; +md4_update(Config) when is_list(Config) -> + ?line Ctx = crypto:md4_init(), + ?line Ctx1 = crypto:md4_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), + ?line Ctx2 = crypto:md4_update(Ctx1, "abcdefghijklmnopqrstuvwxyz" + "0123456789"), + ?line m(crypto:md4_final(Ctx2), + hexstr2bin("043f8582f241db351ce627e153e7f0e4")). + +%% +%% +sha(doc) -> + ["Generate SHA message digests and check the result. Examples are " + "from FIPS-180-1."]; +sha(suite) -> + []; +sha(Config) when is_list(Config) -> + ?line m(crypto:sha("abc"), + hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D")), + ?line m(crypto:sha("abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + "nlmnomnopnopq"), + hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")). + + +%% +%% +sha_update(doc) -> + ["Generate SHA message digests by using sha_init, sha_update, and" + "sha_final, and check the result. Examples are from FIPS-180-1."]; +sha_update(suite) -> + []; +sha_update(Config) when is_list(Config) -> + ?line Ctx = crypto:sha_init(), + ?line Ctx1 = crypto:sha_update(Ctx, "abcdbcdecdefdefgefghfghighi"), + ?line Ctx2 = crypto:sha_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"), + ?line m(crypto:sha_final(Ctx2), + hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")). + +%% +%% +sha256(doc) -> + ["Generate SHA-256 message digests and check the result. Examples are " + "from rfc-4634."]; +sha256(suite) -> + []; +sha256(Config) when is_list(Config) -> + ?line m(crypto:sha256("abc"), + hexstr2bin("BA7816BF8F01CFEA4141" + "40DE5DAE2223B00361A396177A9CB410FF61F20015AD")), + ?line m(crypto:sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklm" + "nlmnomnopnopq"), + hexstr2bin("248D6A61D20638B8" + "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")). + +%% +%% +sha256_update(doc) -> + ["Generate SHA256 message digests by using sha256_init, sha256_update, and" + "sha256_final, and check the result. Examples are from rfc-4634."]; +sha256_update(suite) -> + []; +sha256_update(Config) when is_list(Config) -> + ?line Ctx = crypto:sha256_init(), + ?line Ctx1 = crypto:sha256_update(Ctx, "abcdbcdecdefdefgefghfghighi"), + ?line Ctx2 = crypto:sha256_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"), + ?line m(crypto:sha256_final(Ctx2), + hexstr2bin("248D6A61D20638B8" + "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")). + + +%% +%% +sha512(doc) -> + ["Generate SHA-512 message digests and check the result. Examples are " + "from rfc-4634."]; +sha512(suite) -> + []; +sha512(Config) when is_list(Config) -> + ?line m(crypto:sha512("abc"), + hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" + "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" + "454D4423643CE80E2A9AC94FA54CA49F")), + ?line m(crypto:sha512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"), + hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" + "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" + "C7D329EEB6DD26545E96E55B874BE909")). + +%% +%% +sha512_update(doc) -> + ["Generate SHA512 message digests by using sha512_init, sha512_update, and" + "sha512_final, and check the result. Examples are from rfc=4634."]; +sha512_update(suite) -> + []; +sha512_update(Config) when is_list(Config) -> + ?line Ctx = crypto:sha512_init(), + ?line Ctx1 = crypto:sha512_update(Ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"), + ?line Ctx2 = crypto:sha512_update(Ctx1, "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"), + ?line m(crypto:sha512_final(Ctx2), + hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" + "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" + "C7D329EEB6DD26545E96E55B874BE909")). + +%% +%% +md5_mac(doc) -> + ["Generate some HMACs, using MD5, and check the result. Examples are " + "from RFC-2104."]; +md5_mac(suite) -> + []; +md5_mac(Config) when is_list(Config) -> + ?line m(crypto:md5_mac(hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + "Hi There"), + hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")), + ?line m(crypto:md5_mac(list_to_binary("Jefe"), + "what do ya want for nothing?"), + hexstr2bin("750c783e6ab0b503eaa86e310a5db738")), + ?line m(crypto:md5_mac(hexstr2bin("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), + hexstr2bin("DDDDDDDDDDDDDDDDDDDD" + "DDDDDDDDDDDDDDDDDDDD" + "DDDDDDDDDDDDDDDDDDDD" + "DDDDDDDDDDDDDDDDDDDD" + "DDDDDDDDDDDDDDDDDDDD")), + hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6")). + +%% +%% +md5_mac_io(doc) -> + ["Generate some HMACs, using MD5, with Key an IO-list, and check the " + "result. Examples are from RFC-2104."]; +md5_mac_io(suite) -> + []; +md5_mac_io(Config) when is_list(Config) -> + ?line Key1 = hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"), + ?line {B11, B12} = split_binary(Key1, 4), + ?line Key11 = [B11,binary_to_list(B12)], + ?line m(crypto:md5_mac(Key11, "Hi There"), + hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")). + +%% +%% +des_cbc(doc) -> + "Encrypt and decrypt according to CBC DES. and check the result. " + "Example are from FIPS-81."; +des_cbc(suite) -> + []; +des_cbc(Config) when is_list(Config) -> + ?line Key = hexstr2bin("0123456789abcdef"), + ?line IVec = hexstr2bin("1234567890abcdef"), + ?line Plain = "Now is the time for all ", + ?line Cipher = crypto:des_cbc_encrypt(Key, IVec, Plain), + ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c" + "0f683788499a7c05f6")), + ?line m(list_to_binary(Plain), + crypto:des_cbc_decrypt(Key, IVec, Cipher)), + ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0], + ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec, Plain2), + ?line m(Cipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9" + "9484521388fa59ae67d58d2e77e86062733")), + ?line m(list_to_binary(Plain2), + crypto:des_cbc_decrypt(Key, IVec, Cipher2)). + +%% +%% +des_cbc_iter(doc) -> + "Encrypt and decrypt according to CBC DES in two steps, and " + "check the result. Example are from FIPS-81."; +des_cbc_iter(suite) -> + []; +des_cbc_iter(Config) when is_list(Config) -> + ?line Key = hexstr2bin("0123456789abcdef"), + ?line IVec = hexstr2bin("1234567890abcdef"), + ?line Plain1 = "Now is the time ", + ?line Plain2 = "for all ", + ?line Cipher1 = crypto:des_cbc_encrypt(Key, IVec, Plain1), + ?line IVec2 = crypto:des_cbc_ivec(Cipher1), + ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec2, Plain2), + ?line Cipher = concat_binary([Cipher1, Cipher2]), + ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c" + "0f683788499a7c05f6")). + +%% +%% +aes_cfb(doc) -> + "Encrypt and decrypt according to AES CFB 128 bit and check " + "the result. Example are from NIST SP 800-38A."; + +aes_cfb(suite) -> + []; +aes_cfb(Config) when is_list(Config) -> + +%% Sample data from NIST Spec.Publ. 800-38A +%% F.3.13 CFB128-AES128.Encrypt +%% Key 2b7e151628aed2a6abf7158809cf4f3c +%% IV 000102030405060708090a0b0c0d0e0f +%% Segment #1 +%% Input Block 000102030405060708090a0b0c0d0e0f +%% Output Block 50fe67cc996d32b6da0937e99bafec60 +%% Plaintext 6bc1bee22e409f96e93d7e117393172a +%% Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a +%% Segment #2 +%% Input Block 3b3fd92eb72dad20333449f8e83cfb4a +%% Output Block 668bcf60beb005a35354a201dab36bda +%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +%% Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b +%% Segment #3 +%% Input Block c8a64537a0b3a93fcde3cdad9f1ce58b +%% Output Block 16bd032100975551547b4de89daea630 +%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +%% Ciphertext 26751f67a3cbb140b1808cf187a4f4df +%% Segment #4 +%% Input Block 26751f67a3cbb140b1808cf187a4f4df +%% Output Block 36d42170a312871947ef8714799bc5f6 +%% Plaintext f69f2445df4f9b17ad2b417be66c3710 +%% Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6 + + ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), + ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"), + ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"), + ?line Cipher = crypto:aes_cfb_128_encrypt(Key, IVec, Plain), + ?line m(Cipher, hexstr2bin("3b3fd92eb72dad20333449f8e83cfb4a")), + ?line m(Plain, + crypto:aes_cfb_128_decrypt(Key, IVec, Cipher)). + +%% +%% +aes_cbc(doc) -> + "Encrypt and decrypt according to AES CBC 128 bit. and check the result. " + "Example are from NIST SP 800-38A."; + +aes_cbc(suite) -> + []; +aes_cbc(Config) when is_list(Config) -> + +%% Sample data from NIST Spec.Publ. 800-38A +%% F.2.1 CBC-AES128.Encrypt +%% Key 2b7e151628aed2a6abf7158809cf4f3c +%% IV 000102030405060708090a0b0c0d0e0f +%% Block #1 +%% Plaintext 6bc1bee22e409f96e93d7e117393172a +%% Input Block 6bc0bce12a459991e134741a7f9e1925 +%% Output Block 7649abac8119b246cee98e9b12e9197d +%% Ciphertext 7649abac8119b246cee98e9b12e9197d +%% Block #2 +%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +%% Input Block d86421fb9f1a1eda505ee1375746972c +%% Output Block 5086cb9b507219ee95db113a917678b2 +%% Ciphertext 5086cb9b507219ee95db113a917678b2 +%% Block #3 +%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +%% Input Block 604ed7ddf32efdff7020d0238b7c2a5d +%% Output Block 73bed6b8e3c1743b7116e69e22229516 +%% Ciphertext 73bed6b8e3c1743b7116e69e22229516 +%% Block #4 +%% Plaintext f69f2445df4f9b17ad2b417be66c3710 +%% Input Block 8521f2fd3c8eef2cdc3da7e5c44ea206 +%% Output Block 3ff1caa1681fac09120eca307586e1a7 +%% Ciphertext 3ff1caa1681fac09120eca307586e1a7 +%% +%% F.2.2 CBC-AES128.Decrypt +%% Key 2b7e151628aed2a6abf7158809cf4f3c +%% IV 000102030405060708090a0b0c0d0e0f + %% Block #1 +%% Ciphertext 7649abac8119b246cee98e9b12e9197d +%% Input Block 7649abac8119b246cee98e9b12e9197d +%% Output Block 6bc0bce12a459991e134741a7f9e1925 +%% Plaintext 6bc1bee22e409f96e93d7e117393172a +%% Block #2 +%% Ciphertext 5086cb9b507219ee95db113a917678b2 +%% Input Block 5086cb9b507219ee95db113a917678b2 +%% Output Block d86421fb9f1a1eda505ee1375746972c +%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51 +%% Block #3 +%% Ciphertext 73bed6b8e3c1743b7116e69e22229516 +%% Input Block 73bed6b8e3c1743b7116e69e22229516 +%% Output Block 604ed7ddf32efdff7020d0238b7c2a5d +%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef +%% Block #4 +%% Ciphertext 3ff1caa1681fac09120eca307586e1a7 +%% Input Block 3ff1caa1681fac09120eca307586e1a7 +%% Output Block 8521f2fd3c8eef2cdc3da7e5c44ea206 +%% Plaintext f69f2445df4f9b17ad2b417be66c3710 + + ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), + ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"), + ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"), + ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain), + ?line m(Cipher, hexstr2bin("7649abac8119b246cee98e9b12e9197d")), + ?line m(Plain, + crypto:aes_cbc_128_decrypt(Key, IVec, Cipher)). + +aes_cbc_iter(doc) -> + "Encrypt and decrypt according to CBC AES in steps"; +aes_cbc_iter(suite) -> []; +aes_cbc_iter(Config) when is_list(Config) -> + Key = list_to_binary(lists:seq(255,256-16*17,-17)), + IVec = list_to_binary(lists:seq(1,16*7,7)), + Plain = <<"One, two, three o'clock, four o'clock, rock" + "Five, six, seven o'clock, eight o'clock, rock" + "Nine, ten, eleven o'clock, twelve o'clock, rock" + "We're gonna rock around the clock tonight">>, + ?line 0 = size(Plain) rem 16, + + ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain), + ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Cipher), + + ?line Cipher = aes_cbc_encrypt_iter(Key,IVec,Plain,<<>>), + ?line Plain = aes_cbc_decrypt_iter(Key,IVec,Cipher,<<>>), + ok. + +aes_cbc_encrypt_iter(_,_,<<>>, Acc) -> + Acc; +aes_cbc_encrypt_iter(Key,IVec,Data, Acc) -> + Bytes = 16 * (1 + size(Data) div (16*3)), + <<Chunk:Bytes/binary, Rest/binary>> = Data, + %%io:format("encrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]), + ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Chunk), + ?line IVec2 = crypto:aes_cbc_ivec(Cipher), + aes_cbc_encrypt_iter(Key,IVec2,Rest, <<Acc/binary, Cipher/binary>>). + +aes_cbc_decrypt_iter(_,_,<<>>, Acc) -> + Acc; +aes_cbc_decrypt_iter(Key,IVec,Data, Acc) -> + Bytes = 16 * (1 + size(Data) div (16*5)), + <<Chunk:Bytes/binary, Rest/binary>> = Data, + %%io:format("decrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]), + ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Chunk), + ?line IVec2 = crypto:aes_cbc_ivec(Chunk), + aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>). + + +%% +%% +mod_exp_test(doc) -> + "mod_exp testing (A ^ M % P with bignums)"; +mod_exp_test(suite) -> + []; +mod_exp_test(Config) when is_list(Config) -> + mod_exp_aux_test(2, 5, 10, 8). + +mod_exp_aux_test(_, _, _, 0) -> + ok; +mod_exp_aux_test(B, E, M, N) -> + ?line R1 = crypto:mod_exp(B, E, M), + ?line R2 = ipow(B, E, M), + ?line m(R1, R2), + ?line mod_exp_aux_test(B, E*E+1, M*M+1, N-1). + +%% +%% +rand_uniform_test(doc) -> + "rand_uniform and random_bytes testing"; +rand_uniform_test(suite) -> + []; +rand_uniform_test(Config) when is_list(Config) -> + rand_uniform_aux_test(10), + ?line 10 = size(crypto:rand_bytes(10)). + +rand_uniform_aux_test(0) -> + ok; +rand_uniform_aux_test(N) -> + ?line L = N*1000, + ?line H = N*100000+1, + ?line R1 = crypto:rand_uniform(L, H), + ?line t(R1 >= L), + ?line t(R1 < H), + ?line rand_uniform_aux_test(N-1). + +%% +%% +%% +%% +rsa_verify_test(doc) -> + "rsa_verify testing (A ^ M % P with bignums)"; +rsa_verify_test(suite) -> + []; +rsa_verify_test(Config) when is_list(Config) -> + ?line H = <<178,28,54,104,36,80,144,66,140,201,135,17,36,97,114,124, + 194,164,172,147>>, + ?line SigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70, + 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241, + 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23, + 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76, + 115,34,107,227,151,47,80,185,143,85,202,55,245,163,226,26, + 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180, + 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14, + 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>, + ?line BadSigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70, + 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241, + 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23, + 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76, + 115,107,34,227,151,47,80,185,143,85,202,55,245,163,226,26, + 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180, + 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14, + 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>, + ?line E = <<35>>, + ?line N = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10, + 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193, + 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6, + 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1, + 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123, + 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50, + 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73, + 76,89,40,33,147,208,189,76,98,24,61,8,10,110,165,119,165>>, + ?line Nbad = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10, + 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193, + 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6, + 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1, + 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123, + 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50, + 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73, + 76,89,40,33,147,189,208,76,98,24,61,8,10,110,165,119,165>>, + ?line Ebad = <<77>>, + ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob), + [sized_binary(E), sized_binary(N)]), true), + ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob), + [sized_binary(Ebad), sized_binary(N)]), false), + ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob), + [sized_binary(E), sized_binary(Nbad)]), false), + ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(BadSigBlob), + [sized_binary(E), sized_binary(N)]), false). + +%% +%% +dsa_verify_test(doc) -> + "dsa_verify testing (A ^ M % P with bignums)"; +dsa_verify_test(suite) -> + []; +dsa_verify_test(Config) when is_list(Config) -> + ?line Msg = <<48,130,2,245,160,3,2,1,2,2,1,1,48,9,6,7,42,134,72,206,56,4,3,48, + 58,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,85,4,10,19,17, + 84,101,115,116,32,67,101,114,116,105,102,105,99,97,116,101,115,49, + 15,48,13,6,3,85,4,3,19,6,68,83,65,32,67,65,48,30,23,13,48,49,48, + 52,49,57,49,52,53,55,50,48,90,23,13,49,49,48,52,49,57,49,52,53,55, + 50,48,90,48,93,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3, + 85,4,10,19,17,84,101,115,116,32,67,101,114,116,105,102,105,99,97, + 116,101,115,49,50,48,48,6,3,85,4,3,19,41,86,97,108,105,100,32,68, + 83,65,32,83,105,103,110,97,116,117,114,101,115,32,69,69,32,67,101, + 114,116,105,102,105,99,97,116,101,32,84,101,115,116,52,48,130,1, + 182,48,130,1,43,6,7,42,134,72,206,56,4,1,48,130,1,30,2,129,129,0, + 228,139,175,64,140,21,215,61,124,238,3,150,18,104,193,32,5,232,23, + 202,158,116,101,75,154,84,151,42,120,51,218,165,197,114,234,52, + 179,148,104,66,213,27,253,119,240,168,66,158,100,147,144,182,194, + 2,49,70,19,122,3,105,204,152,45,86,157,94,35,95,40,191,173,127,15, + 208,105,149,98,92,26,7,42,94,140,115,73,126,253,18,34,142,85,229, + 86,233,174,114,41,150,135,8,39,215,119,67,240,134,184,9,10,27,20, + 165,230,3,230,69,121,77,233,250,83,95,193,9,189,126,197,195,2,21, + 0,128,63,228,252,243,76,229,62,203,15,23,10,42,84,108,208,103,108, + 13,59,2,129,128,102,212,22,138,32,173,254,209,50,159,165,127,167, + 179,208,234,119,63,235,108,162,228,41,216,216,188,33,221,154,247, + 204,229,180,119,77,223,236,218,162,140,156,117,18,90,31,254,102, + 211,17,194,239,132,67,236,169,136,110,76,186,76,63,53,150,199,103, + 252,153,189,15,153,41,19,145,78,216,2,174,254,107,175,80,86,170, + 47,30,181,42,200,238,34,71,37,120,107,33,221,20,63,206,240,16,129, + 247,150,29,156,65,187,94,68,146,93,46,198,30,184,205,105,200,143, + 63,59,62,208,79,162,206,217,3,129,132,0,2,129,128,15,83,40,172,56, + 47,61,243,17,97,65,195,61,167,214,122,247,246,1,50,211,33,113,16, + 20,213,195,62,77,235,25,162,140,175,158,8,61,65,10,255,204,162,71, + 130,122,86,161,163,253,236,178,139,183,57,181,202,160,25,133,130, + 155,150,104,168,187,107,186,144,164,225,173,101,182,68,49,210,30, + 34,47,83,65,79,250,156,248,47,232,44,67,36,22,126,43,216,100,247, + 100,250,240,121,72,29,185,2,109,144,54,204,235,54,15,242,57,171, + 125,39,236,247,71,111,221,51,196,126,77,238,36,87,163,107,48,105, + 48,29,6,3,85,29,14,4,22,4,20,179,51,215,81,162,4,13,68,251,157,64, + 241,18,98,113,176,83,246,105,13,48,31,6,3,85,29,35,4,24,48,22,128, + 20,116,21,213,36,28,189,94,101,136,31,225,139,9,126,127,234,25,72, + 78,97,48,23,6,3,85,29,32,4,16,48,14,48,12,6,10,96,134,72,1,101,3, + 2,1,48,1,48,14,6,3,85,29,15,1,1,255,4,4,3,2,6,192>>, + + ?line SigBlob = <<48,45,2,21,0,140,167,200,210,153,212,64,155,249,33,146,104,243, + 39,38,9,115,162,89,24,2,20,76,254,31,128,187,48,128,215,216, + 112,198,78,118,160,217,157,180,246,64,234>>, + ?line P_p = 157224271412839155721795253728878055347359513988016145491388196653004661857517720927482198111104095793441029858267073789634147217022008635826863307553453131345099940951090826856271796188522037524757740796268675508118348391218066949174594918958269259937813776150149068811425194955973128428675945283593831134219, + ?line Q_p = 1181895316321540581845959276009400765315408342791, + ?line G_p = 143872196713149000950547166575757355261637863805587906227228163275557375159769599033632918292482002186641475268486598023281100659643528846513898847919251032731261718358900479488287933293278745715922865499005559197328388506945134386346185262919258658109015074718441639029135304654725637911172671711310801418648, + + ?line Key = 12603618348903387232593303690286336220738319446775939686476278478034365380027994899970214309288018488811754534229198764622077544117034174589418477472887827980332636062691833965078594576024299807057520016043084384987871640003684704483975314128362610573625803532737054022545217931847268776098203204571431581966, + + ValidKey = [crypto:mpint(P_p), + crypto:mpint(Q_p), + crypto:mpint(G_p), + crypto:mpint(Key) + ], + + ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + ValidKey), true), + + BadMsg = one_bit_wrong(Msg), + ?line m(crypto:dss_verify(sized_binary(BadMsg), sized_binary(SigBlob), + ValidKey), false), + BadSig = one_bit_wrong(SigBlob), + ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(BadSig), + ValidKey), false), + SizeErr = size(SigBlob) - 13, + + BadArg = (catch crypto:dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>, + ValidKey)), + ?line m(element(1,element(2,BadArg)), badarg), + + InValidKey = [crypto:mpint(P_p), + crypto:mpint(Q_p), + crypto:mpint(G_p), + crypto:mpint(Key+17) + ], + + ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob), + InValidKey), false). + +one_bit_wrong(Bin) -> + Half = size(Bin) div 2, + <<First:Half/binary, Byte:8, Last/binary>> = Bin, + <<First/binary, (Byte+1):8, Last/binary>>. + + +%% +%% Sign tests + +rsa_sign_test(doc) -> + "rsa_sign testing"; +rsa_sign_test(suite) -> + []; +rsa_sign_test(Config) when is_list(Config) -> + PubEx = 65537, + PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945, + Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123, + Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger" + "09812312908312378623487263487623412039812 huagasd">>, + + PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)], + PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)], + ?line Sig1 = crypto:rsa_sign(sized_binary(Msg), PrivKey), + ?line m(crypto:rsa_verify(sized_binary(Msg), sized_binary(Sig1),PubKey), true), + + ?line Sig2 = crypto:rsa_sign(md5, sized_binary(Msg), PrivKey), + ?line m(crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig2),PubKey), true), + + ?line m(Sig1 =:= Sig2, false), + ?line m(crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig1),PubKey), false), + ?line m(crypto:rsa_verify(sha, sized_binary(Msg), sized_binary(Sig1),PubKey), true), + + ok. + +dsa_sign_test(doc) -> + "dsa_sign testing"; +dsa_sign_test(suite) -> + []; +dsa_sign_test(Config) when is_list(Config) -> + Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger" + "09812312908312378623487263487623412039812 huagasd">>, + + PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978, + PrivKey = _X = 441502407453038284293378221372000880210588566361, + ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797, + ParamQ = 1349199015905534965792122312016505075413456283393, + ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669, + + Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)], + ?line Sig1 = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PrivKey)]), + + ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(Sig1), + [Params, crypto:mpint(PubKey)]), true), + + ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1), + [Params, crypto:mpint(PubKey)]), false), + + ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)), + [Params, crypto:mpint(PubKey)]), false), + + %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]), + + ok. + + +rsa_encrypt_decrypt(doc) -> + ["Test rsa_public_encrypt and rsa_private_decrypt functions."]; +rsa_encrypt_decrypt(suite) -> []; +rsa_encrypt_decrypt(Config) when is_list(Config) -> + PubEx = 65537, + PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945, + Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123, + + PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)], + PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)], + + Msg = <<"7896345786348 Asldi">>, + + ?line PKCS1 = crypto:rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_padding), + ?line PKCS1Dec = crypto:rsa_private_decrypt(PKCS1, PrivKey, rsa_pkcs1_padding), + io:format("PKCS1Dec ~p~n",[PKCS1Dec]), + ?line Msg = PKCS1Dec, + + ?line OAEP = crypto:rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_oaep_padding), + ?line Msg = crypto:rsa_private_decrypt(OAEP, PrivKey, rsa_pkcs1_oaep_padding), + + <<Msg2Len:32,_/binary>> = crypto:mpint(Mod), + Msg2 = list_to_binary(lists:duplicate(Msg2Len-1, $X)), + ?line NoPad = crypto:rsa_public_encrypt(Msg2, PubKey, rsa_no_padding), + ?line NoPadDec = crypto:rsa_private_decrypt(NoPad, PrivKey, rsa_no_padding), + ?line NoPadDec = Msg2, + + ShouldBeError = (catch crypto:rsa_public_encrypt(Msg, PubKey, rsa_no_padding)), + ?line {'EXIT', {encrypt_failed,_}} = ShouldBeError, + +%% ?line SSL = crypto:rsa_public_encrypt(Msg, PubKey, rsa_sslv23_padding), +%% ?line Msg = crypto:rsa_private_decrypt(SSL, PrivKey, rsa_sslv23_padding), + + ?line PKCS1_2 = crypto:rsa_private_encrypt(Msg, PrivKey, rsa_pkcs1_padding), + ?line PKCS1_2Dec = crypto:rsa_public_decrypt(PKCS1_2, PubKey, rsa_pkcs1_padding), + io:format("PKCS2Dec ~p~n",[PKCS1_2Dec]), + ?line Msg = PKCS1_2Dec, + + ?line PKCS1_3 = crypto:rsa_private_encrypt(Msg2, PrivKey, rsa_no_padding), + ?line PKCS1_3Dec = crypto:rsa_public_decrypt(PKCS1_3, PubKey, rsa_no_padding), + io:format("PKCS2Dec ~p~n",[PKCS1_3Dec]), + ?line Msg2 = PKCS1_3Dec, + + ?line {'EXIT', {encrypt_failed,_}} = + (catch crypto:rsa_private_encrypt(Msg, PrivKey, rsa_no_padding)), + + ok. + + +dh(doc) -> + ["Test dh (Diffie-Hellman) functions."]; +dh(suite) -> []; +dh(Config) when is_list(Config) -> + Self = self(), + GenP = fun() -> + %% Gen Param may take arbitrary long time to finish + %% That's not a bug in erlang crypto application. + ?line DHPs = crypto:dh_generate_parameters(512,2), + ?line ok = crypto:dh_check(DHPs), + Self ! {param, DHPs} + end, + Pid = spawn(GenP), + receive + {param, DHPs} -> + timer:sleep(100), + io:format("DHP ~p~n", [DHPs]), + ?line {Pub1,Priv1} = crypto:dh_generate_key(DHPs), + io:format("Key1:~n~p~n~p~n~n", [Pub1,Priv1]), + ?line {Pub2,Priv2} = crypto:dh_generate_key(DHPs), + io:format("Key2:~n~p~n~p~n~n", [Pub2,Priv2]), + ?line A = crypto:dh_compute_key(Pub1, Priv2, DHPs), + timer:sleep(100), %% Get another thread see if that triggers problem + ?line B = crypto:dh_compute_key(Pub2, Priv1, DHPs), + io:format("A ~p~n",[A]), + io:format("B ~p~n",[B]), + ?line A = B + after 50000 -> + io:format("Killing Param generation which took to long ~p~n",[Pid]), + exit(Pid, kill) + end. + +%% +%% +exor_test(doc) -> + ["Test the exor function."]; +exor_test(suite) -> + []; +exor_test(Config) when is_list(Config) -> + B = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>, + Z1 = zero_bin(B), + Z1 = crypto:exor(B, B), + B1 = crypto:rand_bytes(100), + B2 = crypto:rand_bytes(100), + Z2 = zero_bin(B1), + Z2 = crypto:exor(B1, B1), + Z2 = crypto:exor(B2, B2), + R = xor_bytes(B1, B2), + R = crypto:exor(B1, B2), + ok. + +%% +%% +rc4_test(doc) -> + ["Test rc4 encryption ."]; +rc4_test(suite) -> + []; +rc4_test(Config) when is_list(Config) -> + CT1 = <<"hej p� dig">>, + R1 = <<71,112,14,44,140,33,212,144,155,47>>, + K = "apaapa", + R1 = crypto:rc4_encrypt(K, CT1), + CT1 = crypto:rc4_encrypt(K, R1), + CT2 = lists:seq(0, 255), + R2 = crypto:rc4_encrypt(K, CT2), + CT2 = binary_to_list(crypto:rc4_encrypt(K, R2)), + ok. + +blowfish_cfb64(doc) -> ["Test Blowfish encrypt/decrypt."]; +blowfish_cfb64(suite) -> []; +blowfish_cfb64(Config) when is_list(Config) -> + Key = <<1,35,69,103,137,171,205,239,240,225,210,195,180,165,150,135>>, + + IVec = <<254,220,186,152,118,84,50,16>>, + Plain = <<"7654321 Now is the time for ">>, + Enc = <<231,50,20,162,130,33,57,202,242,110,207,109,46,185,231,110,61,163,222,4,209,81,114,0,81,157,87,166>>, + + Enc = crypto:blowfish_cfb64_encrypt(Key, IVec, Plain), + Plain = crypto:blowfish_cfb64_decrypt(Key, IVec, Enc), + + Key2 = <<"A2B4C">>, + IVec2 = <<"12345678">>, + Plain2 = <<"badger at my table....!">>, + Enc2 = <<173,76,128,155,70,81,79,228,4,162,188,92,119,53,144,89,93,236,28,164,176,16,138>>, + + Enc2 = crypto:blowfish_cfb64_encrypt(Key2, IVec2, Plain2), + Plain2 = crypto:blowfish_cfb64_decrypt(Key2, IVec2, Enc2). + + +smp(doc) -> "Check concurrent access to crypto driver"; +smp(suite) -> []; +smp(Config) -> + case erlang:system_info(smp_support) of + true -> + NumOfProcs = erlang:system_info(schedulers), + io:format("smp starting ~p workers\n",[NumOfProcs]), + Seeds = [random:uniform(9999) || _ <- lists:seq(1,NumOfProcs)], + Parent = self(), + Pids = [spawn_link(fun()-> worker(Seed,Config,Parent) end) + || Seed <- Seeds], + wait_pids(Pids); + + false -> + {skipped,"No smp support"} + end. + +worker(Seed, Config, Parent) -> + io:format("smp worker ~p, seed=~p~n",[self(),Seed]), + random:seed(Seed,Seed,Seed), + worker_loop(100, Config), + %%io:format("worker ~p done\n",[self()]), + Parent ! self(). + +worker_loop(0, _) -> + ok; +worker_loop(N, Config) -> + Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc, + aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test, + rsa_verify_test, exor_test, rc4_test, mod_exp_test }, + + F = element(random:uniform(size(Funcs)),Funcs), + %%io:format("worker ~p calling ~p\n",[self(),F]), + ?MODULE:F(Config), + worker_loop(N-1,Config). + +wait_pids([]) -> + ok; +wait_pids(Pids) -> + receive + Pid -> + ?line true = lists:member(Pid,Pids), + Others = lists:delete(Pid,Pids), + io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]), + wait_pids(Others) + end. + +%% +%% Help functions +%% + +% match +m(X, X) -> + ?line true. +t(true) -> + true. + +% hexstr2bin +hexstr2bin(S) -> + list_to_binary(hexstr2list(S)). + +hexstr2list([X,Y|T]) -> + [mkint(X)*16 + mkint(Y) | hexstr2list(T)]; +hexstr2list([]) -> + []. + +mkint(C) when $0 =< C, C =< $9 -> + C - $0; +mkint(C) when $A =< C, C =< $F -> + C - $A + 10; +mkint(C) when $a =< C, C =< $f -> + C - $a + 10. + +%% mod_exp in erlang (copied from jungerl's ssh_math.erl) +ipow(A, B, M) when M > 0, B >= 0 -> + if A == 1 -> + 1; + true -> + ipow(A, B, M, 1) + end. + +ipow(A, 1, M, Prod) -> + (A*Prod) rem M; +ipow(_A, 0, _M, Prod) -> + Prod; +ipow(A, B, M, Prod) -> + B1 = B bsr 1, + A1 = (A*A) rem M, + if B - B1 == B1 -> + ipow(A1, B1, M, Prod); + true -> + ipow(A1, B1, M, (A*Prod) rem M) + end. + +%% +%% Invert an element X mod P +%% Calculated as {1, {A,B}} = egcd(X,P), +%% 1 == P*A + X*B == X*B (mod P) i.e B is the inverse element +%% +%% X > 0, P > 0, X < P (P should be prime) +%% +%% invert(X,P) when X > 0, P > 0, X < P -> +%% I = inv(X,P,1,0), +%% if +%% I < 0 -> P + I; +%% true -> I +%% end. + +%% inv(0,_,_,Q) -> Q; +%% inv(X,P,R1,Q1) -> +%% D = P div X, +%% inv(P rem X, X, Q1 - D*R1, R1). + +sized_binary(Binary) when is_binary(Binary) -> + <<(size(Binary)):32/integer, Binary/binary>>; +sized_binary(List) -> + sized_binary(list_to_binary(List)). + +xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) -> + L1 = binary_to_list(Bin1), + L2 = binary_to_list(Bin2), + list_to_binary(xor_bytes(L1, L2)); +xor_bytes(L1, L2) -> + xor_bytes(L1, L2, []). + +xor_bytes([], [], Acc) -> + lists:reverse(Acc); +xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) -> + xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]). + +zero_bin(N) when is_integer(N) -> + N8 = N * 8, + <<0:N8/integer>>; +zero_bin(B) when is_binary(B) -> + zero_bin(size(B)). diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile index e6a1de2701..1c0bbaf9d2 100644 --- a/lib/debugger/doc/src/Makefile +++ b/lib/debugger/doc/src/Makefile @@ -39,7 +39,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) XML_APPLICATION_FILES = ref_man.xml XML_REF3_FILES = debugger.xml i.xml int.xml -XML_PART_FILES = part.xml part_notes.xml +XML_PART_FILES = part.xml XML_CHAPTER_FILES = debugger_chapter.xml notes.xml BOOK_FILES = book.xml diff --git a/lib/debugger/doc/src/part_notes.xml b/lib/debugger/doc/src/part_notes.xml deleted file mode 100644 index 60299bbb11..0000000000 --- a/lib/debugger/doc/src/part_notes.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE part SYSTEM "part.dtd"> - -<part xmlns:xi="http://www.w3.org/2001/XInclude"> - <header> - <copyright> - <year>2004</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>Debugger Release Notes</title> - <prepared></prepared> - <docno></docno> - <date>2004-09-07</date> - <rev>1.0</rev> - <file>part_notes.sgml</file> - </header> - <description> - <p><em>Debugger</em> is a graphical tool which can be used for - debugging and testing of Erlang programs. For example, breakpoints - can be set, code can be single stepped and variable values can be - displayed and changed.</p> - </description> - <xi:include href="notes.xml"> -</part> - - diff --git a/lib/debugger/doc/src/warning.gif b/lib/debugger/doc/src/warning.gif Binary files differdeleted file mode 100644 index 96af52360e..0000000000 --- a/lib/debugger/doc/src/warning.gif +++ /dev/null diff --git a/lib/erl_docgen/priv/xsl/db_eix.xsl b/lib/erl_docgen/priv/xsl/db_eix.xsl new file mode 100644 index 0000000000..929272256a --- /dev/null +++ b/lib/erl_docgen/priv/xsl/db_eix.xsl @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + # + # %CopyrightBegin% + # + # Copyright Ericsson AB 2009. All Rights Reserved. + # + # The contents of this file are subject to the Erlang Public License, + # Version 1.1, (the "License"); you may not use this file except in + # compliance with the License. You should have received a copy of the + # Erlang Public License along with this software. If not, it can be + # retrieved online at http://www.erlang.org/. + # + # Software distributed under the License is distributed on an "AS IS" + # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + # the License for the specific language governing rights and limitations + # under the License. + # + # %CopyrightEnd% + + --> + +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> + + <xsl:output method="text" encoding="UTF-8" indent="no"/> + + <!-- Book --> + <xsl:template match="/book"> + <xsl:text>%% %% Search data file for </xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/> + <xsl:text> %% generated </xsl:text><xsl:value-of select="$gendate"/><xsl:text> %% </xsl:text> + <xsl:apply-templates select="applications"/> + <xsl:text>{notused, application, ["</xsl:text><xsl:value-of select="$appname"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + <!-- Applications --> + <xsl:template match="applications"> + <xsl:apply-templates name="application"/> + </xsl:template> + + <!-- Reference Manual --> + + <!-- Application --> + <xsl:template match="application"> + <xsl:apply-templates select="erlref|cref|comref|fileref|appref"/> + </xsl:template> + + <!-- Erlref --> + <xsl:template match="erlref"> + <xsl:text>{"</xsl:text><xsl:value-of select="module"/><xsl:text>.html", {function, {"</xsl:text><xsl:value-of select="$appname"/> + <xsl:text>", "</xsl:text><xsl:value-of select="module"/><xsl:text>"}}, [ </xsl:text> + <xsl:apply-templates select="funcs"> + <xsl:with-param name="mod" select="module"/> + </xsl:apply-templates> + <xsl:text>]}. </xsl:text> + <xsl:text>{"</xsl:text><xsl:value-of select="module"/><xsl:text>.html", {module, "</xsl:text> + <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="module"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + <!-- Cref --> + <xsl:template match="cref"> + <xsl:text>{"</xsl:text><xsl:value-of select="lib"/><xsl:text>.html", {function, {"</xsl:text><xsl:value-of select="$appname"/> + <xsl:text>", "</xsl:text><xsl:value-of select="lib"/><xsl:text>"}}, [ </xsl:text> + <xsl:apply-templates select="funcs"> + <xsl:with-param name="mod" select="lib"/> + </xsl:apply-templates> + <xsl:text>]}. </xsl:text> + <xsl:text>{"</xsl:text><xsl:value-of select="lib"/><xsl:text>.html", {clib, "</xsl:text> + <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="lib"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + <!-- Comref --> + <xsl:template match="comref"> + <xsl:text>{"</xsl:text><xsl:value-of select="com"/><xsl:text>.html", {command, "</xsl:text> + <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="com"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + <!-- Fileref --> + <xsl:template match="fileref"> + <xsl:text>{"</xsl:text><xsl:value-of select="file"/><xsl:text>.html", {file, "</xsl:text> + <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="file"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + <!-- Appref --> + <xsl:template match="appref"> + <xsl:text>{"</xsl:text><xsl:value-of select="app"/><xsl:text>_app.html", {app, "</xsl:text> + <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="app"/><xsl:text>"]}. </xsl:text> + </xsl:template> + + + <!-- Funcs --> + <xsl:template match="funcs"> + <xsl:param name="mod"/> + <xsl:variable name="lastfuncsblock"> + <xsl:value-of select="position() = last()"/> + </xsl:variable> + <xsl:apply-templates select="func/name"> + <xsl:with-param name="mod" select="$mod"/> + <xsl:with-param name="lastfuncsblock" select="$lastfuncsblock"/> + </xsl:apply-templates> + </xsl:template> + + + + + <xsl:template match="name"> + <xsl:param name="mod"/> + <xsl:param name="lastfuncsblock"/> + + <xsl:variable name="tmpstring"> + <xsl:value-of select="substring-before(substring-after(., '('), '->')"/> + </xsl:variable> + <xsl:variable name="ustring"> + <xsl:choose> + <xsl:when test="string-length($tmpstring) > 0"> + <xsl:call-template name="remove-paren"> + <xsl:with-param name="string" select="$tmpstring"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="remove-paren"> + <xsl:with-param name="string" select="substring-after(., '(')"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="arity"> + <xsl:call-template name="calc-arity"> + <xsl:with-param name="string" select="substring-before($ustring, ')')"/> + <xsl:with-param name="no-of-pars" select="0"/> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="fname"> + <xsl:choose> + <xsl:when test="ancestor::cref"> + <xsl:value-of select="substring-before(nametext, '(')"/> + </xsl:when> + <xsl:when test="ancestor::erlref"> + <xsl:value-of select="substring-before(., '(')"/> + </xsl:when> + </xsl:choose> + </xsl:variable> + <xsl:text> {"</xsl:text><xsl:value-of select="$fname"/> + <xsl:text>", "</xsl:text><xsl:value-of select="$fname"/> + <xsl:text>(</xsl:text><xsl:value-of select="normalize-space($tmpstring)"/> + <xsl:text>", "</xsl:text><xsl:value-of select="$fname"/> + <xsl:text>-</xsl:text><xsl:value-of select="$arity"/><xsl:text>"}</xsl:text> + + <xsl:choose> + <xsl:when test="($lastfuncsblock = 'true') and (position() = last())"> + <xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>, </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Special templates to calculate the arity of functions --> + <xsl:template name="calc-arity"> + <xsl:param name="string"/> + <xsl:param name="no-of-pars"/> + <xsl:variable name="length"> + <xsl:value-of select="string-length($string)"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="$length > 0"> + <xsl:call-template name="calc-arity"> + <xsl:with-param name="string" select="substring-after($string, ',')"/> + <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$no-of-pars"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="remove-paren"> + <xsl:param name="string"/> + <xsl:variable name="bstring"> + <xsl:value-of select="substring-before($string, '(')"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="string-length($bstring) > 0"> + <xsl:variable name="astring"> + <xsl:value-of select="substring-after($string, ')')"/> + </xsl:variable> + <xsl:variable name="retstring"> + <xsl:call-template name="remove-paren"> + <xsl:with-param name="string" select="$astring"/> + </xsl:call-template> + </xsl:variable> + <xsl:value-of select="concat($bstring, $retstring)"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$string"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- default content handling --> + <xsl:template match="text()"/> + +</xsl:stylesheet> diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index 3e6f762870..984655fc26 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -61,7 +61,7 @@ <xsl:value-of select="$copyright"/> <xsl:value-of select="/book/header/copyright/year[1]"/> <xsl:text>-</xsl:text> - <xsl:value-of select="substring-after(substring-after($gendate, ' '), ' ')"/> + <xsl:value-of select="substring-after(normalize-space(substring-after($gendate, ' ')), ' ')"/> <xsl:text> </xsl:text> <xsl:value-of select="/book/header/copyright/holder"/> </p> diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 80b229c1c3..2f5b5673bb 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -100,11 +100,11 @@ if test "x$LD" = "x"; then fi AC_SUBST(LD) -AC_CHECK_SIZEOF(short, $erl_xcomp_short) -AC_CHECK_SIZEOF(int, $erl_xcomp_int) -AC_CHECK_SIZEOF(long, $erl_xcomp_long) -AC_CHECK_SIZEOF(void *, $erl_xcomp_void_p) -AC_CHECK_SIZEOF(long long, $erl_xcomp_long_long) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long long) if test $ac_cv_sizeof_void_p = 8; then CFLAGS="$CFLAGS -DEI_64BIT" diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml index 08e7b122c6..abf705f9e2 100644 --- a/lib/erl_interface/doc/src/ei_connect.xml +++ b/lib/erl_interface/doc/src/ei_connect.xml @@ -619,6 +619,16 @@ typedef struct { <p>These are convenience functions for some common name lookup functions.</p> </desc> </func> + <func> + <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name> + <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name> + <fsummary>Get and set functions for tracing.</fsummary> + <desc> + <p>These functions are used to set tracing on the distribution. The levels are different verbosity levels. A higher level means more information. + See also Debug Information and <c><![CDATA[EI_TRACELEVEL]]></c> below. </p> + <p> <c><![CDATA[ei_set_tracelevel]]></c> and <c><![CDATA[ei_get_tracelevel]]></c> are not thread safe. </p> + </desc> + </func> </funcs> <section> @@ -634,6 +644,17 @@ typedef struct { <item>the environment variable <c><![CDATA[ERL_EPMD_PORT]]></c> is set correctly.</item> </list> + <p>The connection attempt can be traced by setting a tracelevel by either using + <c><![CDATA[ei_set_tracelevel]]></c> or by setting the environment variable <c><![CDATA[EI_TRACELEVEL]]></c>. + The different tracelevels has the following messages:</p> + <list> + <item>1: Verbose error messages</item> + <item>2: Above messages and verbose warning messages </item> + <item>3: Above messages and progress reports for connection handling</item> + <item>4: Above messages and progress reports for communication</item> + <item>5: Above messages and progress reports for data conversion</item> + </list> </section> + </cref> diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml index ce14549672..f403618c59 100644 --- a/lib/erl_interface/doc/src/erl_eterm.xml +++ b/lib/erl_interface/doc/src/erl_eterm.xml @@ -248,7 +248,7 @@ iohead ::= Binary <v>ETERM *list;</v> </type> <desc> - <p>This function converts an IO list to a '\\0' terminated C + <p>This function converts an IO list to a '\0' terminated C string. </p> <p><c><![CDATA[list]]></c> is an Erlang term containing an IO list. The IO list must not contain the integer 0, since C strings may not diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index f2519fda0b..21f12f616a 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -336,7 +336,7 @@ from 0 to 255 as a string. If the original list contains the integer 0, this is considered terminator of the string. This is incorrect. The function has now been - modified to not look for '\\0' in a string, but always + modified to not look for '\0' in a string, but always print all characters.</p> <p>Own Id: OTP-6339 Aux Id: seq10492 </p> </item> diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h index 01272244e1..d1a697615a 100644 --- a/lib/erl_interface/include/ei.h +++ b/lib/erl_interface/include/ei.h @@ -339,7 +339,13 @@ const char *ei_thisalivename(const ei_cnode* ec); erlang_pid *ei_self(ei_cnode* ec); +/* + * settings + */ + void ei_set_compat_rel(unsigned rel); +void ei_set_tracelevel(int); +int ei_get_tracelevel(void); /* * We have erl_gethost*() so we include ei versions as well. diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c index 9ac5a93c5a..d2d0a7e7c1 100644 --- a/lib/erl_interface/src/connect/ei_connect.c +++ b/lib/erl_interface/src/connect/ei_connect.c @@ -249,8 +249,22 @@ ei_cnode *ei_fd_to_cnode(int fd) return &sockinfo->cnode; } + +/*************************************************************************** + * Get/Set tracelevel + ***************************************************************************/ + +void ei_set_tracelevel(int level) { + ei_tracelevel = level; +} + +int ei_get_tracelevel(void) { + return ei_tracelevel; +} + + /*************************************************************************** - * XXXX + * Distversion ***************************************************************************/ int ei_distversion(int fd) @@ -1282,8 +1296,6 @@ error: return -1; } -/* FIXME fix the signed/unsigned mess..... */ - static int send_name_or_challenge(int fd, char *nodename, int f_chall, unsigned challenge, diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml index 2303617542..f9f5443f68 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -1368,7 +1368,7 @@ f.txt: {person, "kalle", 25}. </type> <desc> <p>Reads a line of bytes/characters from the file referenced by - <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\\n</c>) character, but any carriage return (CR, <c>\\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p> + <c>IoDevice</c>. Lines are defined to be delimited by the linefeed (LF, <c>\n</c>) character, but any carriage return (CR, <c>\r</c>) followed by a newline is also treated as a single LF character (the carriage return is silently ignored). The line is returned <em>including</em> the LF, but excluding any CR immediately followed by a LF. This behaviour is consistent with the behaviour of <seealso marker="stdlib:io#get_line/2">io:get_line/2</seealso>. If end of file is reached without any LF ending the last line, a line with no trailing LF is returned.</p> <p>The function can be used on files opened in <c>raw</c> mode. It is however inefficient to use it on <c>raw</c> files if the file is not opened with the option <c>{read_ahead, Size}</c> specified, why combining <c>raw</c> and <c>{read_ahead, Size}</c> is highly recommended when opening a text file for raw line oriented reading.</p> <p>If <c>encoding</c> is set to something else than <c>latin1</c>, the <c>read_line/1</c> call will fail if the data contains characters larger than 255, why the <seealso marker="stdlib:io">io(3)</seealso> module is to be preferred when reading such a file.</p> <p>The function returns:</p> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index cae5fef2f8..f502b30c8d 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -49,8 +49,8 @@ might be specified in this way. An example of starting an Erlang node with all sockets using delayed send could look like this:</p> <pre> -$ <input>erl -sname test -kernel \\</input> -<input>inet_default_connect_options '[{delay_send,true}]' \\</input> +$ <input>erl -sname test -kernel \</input> +<input>inet_default_connect_options '[{delay_send,true}]' \</input> <input>inet_default_listen_options '[{delay_send,true}]'</input></pre> <p>Note that the default option <c>{active, true}</c> currently cannot be changed, for internal reasons.</p> diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl index 018f7f41d2..d4e3f0bcf8 100644 --- a/lib/kernel/src/code_server.erl +++ b/lib/kernel/src/code_server.erl @@ -1479,13 +1479,12 @@ finish_on_load(Ref, OnLoadRes, #state{on_load=OnLoad0,moddb=Db}=State) -> end. finish_on_load_1(Mod, File, OnLoadRes, WaitingPids, Db) -> - Keep = if - is_boolean(OnLoadRes) -> OnLoadRes; - true -> false - end, + Keep = OnLoadRes =:= ok, erlang:finish_after_on_load(Mod, Keep), Res = case Keep of - false -> {error,on_load_failure}; + false -> + finish_on_load_report(Mod, OnLoadRes), + {error,on_load_failure}; true -> ets:insert(Db, {Mod,File}), {module,Mod} @@ -1493,6 +1492,24 @@ finish_on_load_1(Mod, File, OnLoadRes, WaitingPids, Db) -> [reply(Pid, Res) || Pid <- WaitingPids], ok. +finish_on_load_report(_Mod, Atom) when is_atom(Atom) -> + %% No error reports for atoms. + ok; +finish_on_load_report(Mod, Term) -> + %% Play it very safe here. The error_logger module and + %% modules it depend on may not be loaded yet and there + %% would be a dead-lock if we called it directly + %% from the code_server process. + spawn(fun() -> + F = "The on_load function for module " + "~s returned ~P\n", + + %% Express the call as an apply to simplify + %% the ext_mod_dep/1 test case. + E = error_logger, + E:warning_msg(F, [Mod,Term,10]) + end). + %% ------------------------------------------------------- %% Internal functions. %% ------------------------------------------------------- diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 9fda66711d..38aadac202 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -31,12 +31,17 @@ where_is_file_cached/1, where_is_file_no_cache/1, purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1, code_archive/1, code_archive2/1, on_load/1, - on_load_embedded/1]). + on_load_embedded/1, on_load_errors/1]). -export([init_per_testcase/2, fin_per_testcase/2, init_per_suite/1, end_per_suite/1, sticky_compiler/1]). +%% error_logger +-export([init/1, + handle_event/2, handle_call/2, handle_info/2, + terminate/2]). + all(suite) -> [set_path, get_path, add_path, add_paths, del_path, replace_path, load_file, load_abs, ensure_loaded, @@ -47,7 +52,8 @@ all(suite) -> load_cached, start_node_with_cache, add_and_rehash, where_is_file_no_cache, where_is_file_cached, purge_stacktrace, mult_lib_roots, bad_erl_libs, - code_archive, code_archive2, on_load, on_load_embedded]. + code_archive, code_archive2, on_load, on_load_embedded, + on_load_errors]. init_per_suite(Config) -> %% The compiler will no longer create a Beam file if @@ -671,6 +677,8 @@ check_funs({'$M_EXPR','$F_EXPR',2}, check_funs({'$M_EXPR','$F_EXPR',1}, [{lists,foreach,2}, {hipe_unified_loader,patch_consts,3} | _]) -> 0; +check_funs({'$M_EXPR',warning_msg,2}, + [{code_server,finish_on_load_report,2} | _]) -> 0; %% This is cheating! /raimo %% %% check_funs(This = {M,_,_}, Path) -> @@ -1229,6 +1237,81 @@ is_source_dir() -> filename:basename(code:lib_dir(kernel)) =:= "kernel" andalso filename:basename(code:lib_dir(stdlib)) =:= "stdlib". +on_load_errors(Config) when is_list(Config) -> + Master = on_load_error_test_case_process, + ?line register(Master, self()), + + ?line Data = filename:join([?config(data_dir, Config),"on_load_errors"]), + ?line ok = file:set_cwd(Data), + ?line up_to_date = make:all([{d,'MASTER',Master}]), + + ?line do_on_load_error(an_atom), + + ?line error_logger:add_report_handler(?MODULE, self()), + + ?line do_on_load_error({something,terrible,is,wrong}), + receive + Any1 -> + ?line {_, "The on_load function"++_, + [on_load_error, + {something,terrible,is,wrong},_]} = Any1 + end, + + ?line do_on_load_error(fail), %Cause exception. + receive + Any2 -> + ?line {_, "The on_load function"++_, + [on_load_error,{failed,[_|_]},_]} = Any2 + end, + + %% There should be no more messages. + receive + Unexpected -> + ?line ?t:fail({unexpected,Unexpected}) + after 10 -> + ok + end, + + ok. + +do_on_load_error(ReturnValue) -> + ?line {_,Ref} = spawn_monitor(fun() -> + exit(on_load_error:main()) + end), + receive {on_load_error,ErrorPid} -> ok end, + ?line ErrorPid ! ReturnValue, + receive + {'DOWN',Ref,process,_,Exit} -> + ?line {undef,[{on_load_error,main,[]}|_]} = Exit + end. + +%%----------------------------------------------------------------- +%% error_logger handler. +%% (Copied from stdlib/test/proc_lib_SUITE.erl.) +%%----------------------------------------------------------------- +init(Tester) -> + {ok, Tester}. + +handle_event({error, _GL, {emulator, _, _}}, Tester) -> + {ok, Tester}; +handle_event({error, _GL, Msg}, Tester) -> + Tester ! Msg, + {ok, Tester}; +handle_event(_Event, State) -> + {ok, State}. + +handle_info(_, State) -> + {ok, State}. + +handle_call(_Query, State) -> {ok, {error, bad_query}, State}. + +terminate(_Reason, State) -> + State. + +%%% +%%% Common utility functions. +%%% + start_node(Name, Param) -> ?t:start_node(Name, slave, [{args, Param}]). diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl index 660000df46..f6bcb6570b 100644 --- a/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl +++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl @@ -13,7 +13,7 @@ on_load() -> LibDir = code:lib_dir(kernel), ?MASTER ! {?MODULE,LibDir}, - true. + ok. data() -> [a|on_load_b:data()]. diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl index 5c4d676e2d..947cbd5bcd 100644 --- a/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl +++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl @@ -6,7 +6,7 @@ on_load() -> ?MASTER ! {?MODULE,start}, on_load_c:data(), ?MASTER ! {?MODULE,done}, - true. + ok. data() -> [b|on_load_c:data()]. diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl index 4b2edbfb5a..6ab7f6402f 100644 --- a/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl +++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl @@ -7,7 +7,7 @@ on_load() -> receive go -> ?MASTER ! {?MODULE,done}, - true + ok end. data() -> diff --git a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl index bfc26864d5..a39332f81d 100644 --- a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl +++ b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl @@ -9,7 +9,7 @@ run_me() -> ok end end), - true. + ok. status() -> case whereis(everything_is_fine) of diff --git a/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl b/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl new file mode 100644 index 0000000000..0772050aeb --- /dev/null +++ b/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl @@ -0,0 +1,13 @@ +-module(on_load_error). +-on_load(on_load/0). +-export([main/0]). + +on_load() -> + ?MASTER ! {?MODULE,self()}, + receive + fail -> erlang:error(failed); + Ret -> Ret + end. + +main() -> + ok. diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl index b323d86ea4..978541e470 100644 --- a/lib/observer/src/crashdump_viewer.erl +++ b/lib/observer/src/crashdump_viewer.erl @@ -1272,6 +1272,9 @@ get_general_info(Fd,GenInfo) -> get_general_info(Fd,GenInfo#general_info{system_vsn=val(Fd)}); "Compiled" -> get_general_info(Fd,GenInfo#general_info{compile_time=val(Fd)}); + "Taints" -> + Val = case val(Fd) of "-1" -> "(none)"; Line -> Line end, + get_general_info(Fd,GenInfo#general_info{taints=Val}); "Atoms" -> get_general_info(Fd,GenInfo#general_info{num_atoms=val(Fd)}); "=" ++ _next_tag -> diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl index 386d3bb423..6ce727cd3e 100644 --- a/lib/observer/src/crashdump_viewer.hrl +++ b/lib/observer/src/crashdump_viewer.hrl @@ -26,6 +26,7 @@ slogan, system_vsn, compile_time, + taints, node_name, num_atoms, num_procs, diff --git a/lib/observer/src/crashdump_viewer_html.erl b/lib/observer/src/crashdump_viewer_html.erl index 5fa829ed37..5e7bbf62a0 100644 --- a/lib/observer/src/crashdump_viewer_html.erl +++ b/lib/observer/src/crashdump_viewer_html.erl @@ -215,6 +215,8 @@ general_info_body(Heading,GenInfo) -> td(GenInfo#general_info.system_vsn)]), tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Compiled"), td(GenInfo#general_info.compile_time)]), + tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Taints"), + td(GenInfo#general_info.taints)]), case GenInfo#general_info.mem_tot of "" -> ""; MemTot -> diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml index c113b586df..12abfd244f 100644 --- a/lib/parsetools/doc/src/leex.xml +++ b/lib/parsetools/doc/src/leex.xml @@ -281,7 +281,7 @@ NAME = VALUE</code> <Regexp> : <Erlang code>.</code> <p>The <Regexp> must occur at the start of a line and not - include any blanks; use <c>\\t</c> and <c>\\s</c> to include TAB + include any blanks; use <c>\t</c> and <c>\s</c> to include TAB and SPACE characters in the regular expression. If <Regexp> matches then the corresponding <Erlang code> is evaluated to generate a token. With the Erlang code the following predefined @@ -344,7 +344,7 @@ D = [0-9] {D}+ : {token,{integer,TokenLine,list_to_integer(TokenChars)}}. -{D}+\\.{D}+((E|e)(\\+|\\-)?{D}+)? : +{D}+\.{D}+((E|e)(\+|\-)?{D}+)? : {token,{float,TokenLine,list_to_float(TokenChars)}}.</code> <p>The Erlang code in the "Erlang code." section is written into @@ -367,7 +367,7 @@ D = [0-9] <tag><c>c</c></tag> <item><p>Matches the non-metacharacter c.</p> </item> - <tag><c>\\c</c></tag> + <tag><c>\c</c></tag> <item><p>Matches the escape sequence or literal character c.</p> </item> <tag><c>.</c></tag> @@ -410,33 +410,33 @@ D = [0-9] <p>The escape sequences allowed are the same as for Erlang strings:</p> <taglist> - <tag><c>\\b</c></tag> + <tag><c>\b</c></tag> <item><p>Backspace.</p></item> - <tag><c>\\f</c></tag> + <tag><c>\f</c></tag> <item><p>Form feed.</p></item> - <tag><c>\\n</c></tag> + <tag><c>\n</c></tag> <item><p>Newline (line feed).</p></item> - <tag><c>\\r</c></tag> + <tag><c>\r</c></tag> <item><p>Carriage return.</p></item> - <tag><c>\\t</c></tag> + <tag><c>\t</c></tag> <item><p>Tab.</p></item> - <tag><c>\\e</c></tag> + <tag><c>\e</c></tag> <item><p>Escape.</p></item> - <tag><c>\\v</c></tag> + <tag><c>\v</c></tag> <item><p>Vertical tab.</p></item> - <tag><c>\\s</c></tag> + <tag><c>\s</c></tag> <item><p>Space.</p></item> - <tag><c>\\d</c></tag> + <tag><c>\d</c></tag> <item><p>Delete.</p></item> - <tag><c>\\ddd</c></tag> + <tag><c>\ddd</c></tag> <item><p>The octal value <c>ddd</c>.</p></item> - <tag><c>\\xhh</c></tag> + <tag><c>\xhh</c></tag> <item><p>The hexadecimal value <c>hh</c>.</p></item> - <tag><c>\\x{h...}</c></tag> + <tag><c>\x{h...}</c></tag> <item><p>The hexadecimal value <c>h...</c>.</p></item> - <tag><c>\\c</c></tag> - <item><p>Any other character literally, for example <c>\\\\</c> for - backslash, <c>\\"</c> for <c>"</c>.</p> + <tag><c>\c</c></tag> + <item><p>Any other character literally, for example <c>\\</c> for + backslash, <c>\"</c> for <c>"</c>.</p> </item> </taglist> @@ -446,7 +446,7 @@ Atoms [a-z][0-9a-zA-Z_]* Variables [A-Z_][0-9a-zA-Z_]* -Floats (\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?</code> +Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</code> <note><p>Anchoring a regular expression with <c>^</c> and <c>$</c> is not implemented in the current version of Leex and just diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl index 4becfef19b..7972fde597 100644 --- a/lib/percept/src/egd.erl +++ b/lib/percept/src/egd.erl @@ -128,13 +128,13 @@ line(Image, P1, P2, Color) -> %% @spec color( Value | Name ) -> color() %% where -%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} -%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua +%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} +%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua %% @doc Creates a color reference. -spec(color/1 :: ( - Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) -> - color()). + Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) -> + color()). color(Color) -> egd_primitives:color(Color). diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl index 2b2a89a0a9..5f0d56dd90 100644 --- a/lib/percept/src/egd_font.erl +++ b/lib/percept/src/egd_font.erl @@ -131,18 +131,18 @@ parse_glyph({Code,W,H,X0,Y0,Xm,Offset}, Bitmasks) -> render_glyph(W, H, X0, Y0, Xm, Bitmask) -> render_glyph(W,{0,H},X0,Y0,Xm,Bitmask, []). render_glyph(_W, {H,H}, _X0, _Y0, _Xm, _Bitmask, Out) -> Out; -render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask, LSs) -> +render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask , LSs) -> N = ((W+7) div 8), O = N*Hi, <<_:O/binary, Submask/binary>> = Bitmask, - LS = render_glyph_horizontal( + LS = render_glyph_horizontal( Submask, % line glyph bitmask {down, W - 1}, % loop state W - 1, % Width []), % Linespans render_glyph(W,{Hi+1,H},X0,Y0,Xm, Bitmask, [LS|LSs]). -render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) -> +render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) -> Cr = bit_spin(Value, 0), case {Pr,Cr} of {up , up } -> % closure of interval since its last @@ -173,4 +173,3 @@ bit_spin(Value, Cx) -> 1 -> up; 0 -> down end. - diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl index 3a0aaeef31..3a0aaeef31 100755..100644 --- a/lib/percept/src/egd_png.erl +++ b/lib/percept/src/egd_png.erl diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl index 245e0d48e2..77c600279f 100644 --- a/lib/percept/src/egd_primitives.erl +++ b/lib/percept/src/egd_primitives.erl @@ -28,6 +28,7 @@ pixel/3, polygon/3, line/4, + line/5, arc/4, arc/5, rectangle/4, @@ -50,7 +51,6 @@ -include("egd.hrl"). - %% API info info(I) -> W = I#image.width, H = I#image.height, @@ -75,13 +75,22 @@ object_info(O) -> %% interface functions line(I, Sp, Ep, Color) -> - I#image{objects = [ + I#image{ objects = [ #image_object{ type = line, points = [Sp, Ep], span = span([Sp, Ep]), color = Color} | I#image.objects]}. +line(I, Sp, Ep, Stroke, Color) -> + I#image{ objects = [ + #image_object{ + type = line, + points = [Sp, Ep], + span = span([Sp, Ep]), + internals = Stroke, + color = Color } | I#image.objects]}. + arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) -> X = Ex - Sx, Y = Ey - Sy, @@ -162,8 +171,6 @@ create(W, H) -> #image{ width = W, height = H}. -%color({crayon, Color}) -> rgba_byte2float(name_to_color({crayon, Color, 255})); -%color({crayon, Color, A}) -> rgba_byte2float(name_to_color({crayon, Color, A})); color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, 255})); color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, A})); color({R,G,B}) -> rgba_byte2float({R,G,B, 255}); @@ -314,129 +321,6 @@ name_to_color({ slategray, A}) -> { 112, 128, 144, A}; name_to_color({ dimgray, A}) -> { 105, 105, 105, A}; name_to_color({ darkslategray, A}) -> { 47, 79, 79, A}. -%% Crayons -%name_to_color({crayon, mahogany, A}) -> { 205, 74, 74, A}; -%name_to_color({crayon, 'fuzzy wuzzy brown', A}) -> { 204, 102, 102, A}; -%name_to_color({crayon, chestnut, A}) -> { 188, 93, 88, A}; -%name_to_color({crayon, 'red orange', A}) -> { 255, 83, 73, A}; -%name_to_color({crayon, 'sunset orange', A}) -> { 253, 94, 83, A}; -%name_to_color({crayon, bittersweet, A}) -> { 253, 124, 110, A}; -%name_to_color({crayon, melon, A}) -> { 253, 188, 180, A}; -%name_to_color({crayon, 'outrageous orange', A}) -> { 255, 110, 74, A}; -%name_to_color({crayon, 'vivid tangerine', A}) -> { 255, 160, 137, A}; -%name_to_color({crayon, 'burnt sienna', A}) -> { 234, 126, 93, A}; -%name_to_color({crayon, brown, A}) -> { 180, 103, 77, A}; -%name_to_color({crayon, sepia, A}) -> { 165, 105, 79, A}; -%name_to_color({crayon, orange, A}) -> { 255, 117, 56, A}; -%name_to_color({crayon, 'burnt orange', A}) -> { 255, 127, 73, A}; -%name_to_color({crayon, copper, A}) -> { 221, 148, 117, A}; -%name_to_color({crayon, 'mango tango', A}) -> { 255, 130, 67, A}; -%name_to_color({crayon, 'atomic tangerine', A}) -> { 255, 164, 116, A}; -%name_to_color({crayon, beaver, A}) -> { 159, 129, 112, A}; -%name_to_color({crayon, 'antique brass', A}) -> { 205, 149, 117, A}; -%name_to_color({crayon, 'desert sand', A}) -> { 239, 205, 184, A}; -%name_to_color({crayon, 'raw sienna', A}) -> { 214, 138, 89, A}; -%name_to_color({crayon, tumbleweed, A}) -> { 222, 170, 136, A}; -%name_to_color({crayon, tan, A}) -> { 250, 167, 108, A}; -%name_to_color({crayon, peach, A}) -> { 255, 207, 171, A}; -%name_to_color({crayon, 'macaroni and cheese', A}) -> { 255, 189, 136, A}; -%name_to_color({crayon, apricot, A}) -> { 253, 217, 181, A}; -%name_to_color({crayon, 'neon carrot', A}) -> { 255, 163, 67, A}; -%name_to_color({crayon, almond, A}) -> { 239, 219, 197, A}; -%name_to_color({crayon, 'yellow orange', A}) -> { 255, 182, 83, A}; -%name_to_color({crayon, gold, A}) -> { 231, 198, 151, A}; -%name_to_color({crayon, shadow, A}) -> { 138, 121, 93, A}; -%name_to_color({crayon, 'banana mania', A}) -> { 250, 231, 181, A}; -%name_to_color({crayon, sunglow, A}) -> { 255, 207, 72, A}; -%name_to_color({crayon, goldenrod, A}) -> { 252, 217, 117, A}; -%name_to_color({crayon, dandelion, A}) -> { 253, 219, 109, A}; -%name_to_color({crayon, yellow, A}) -> { 252, 232, 131, A}; -%name_to_color({crayon, 'green yellow', A}) -> { 240, 232, 145, A}; -%name_to_color({crayon, 'spring green', A}) -> { 236, 234, 190, A}; -%name_to_color({crayon, 'olive green', A}) -> { 186, 184, 108, A}; -%name_to_color({crayon, 'laser lemon', A}) -> { 253, 252, 116, A}; -%name_to_color({crayon, 'unmellow yellow', A}) -> { 253, 252, 116, A}; -%name_to_color({crayon, canary, A}) -> { 255, 255, 153, A}; -%name_to_color({crayon, 'yellow green', A}) -> { 197, 227, 132, A}; -%name_to_color({crayon, 'inch worm', A}) -> { 178, 236, 93, A}; -%name_to_color({crayon, asparagus, A}) -> { 135, 169, 107, A}; -%name_to_color({crayon, 'granny smith apple', A}) -> { 168, 228, 160, A}; -%name_to_color({crayon, 'electric lime', A}) -> { 29, 249, 20, A}; -%name_to_color({crayon, 'screamin green', A}) -> { 118, 255, 122, A}; -%name_to_color({crayon, fern, A}) -> { 113, 188, 120, A}; -%name_to_color({crayon, 'forest green', A}) -> { 109, 174, 129, A}; -%name_to_color({crayon, 'sea green', A}) -> { 159, 226, 191, A}; -%name_to_color({crayon, green, A}) -> { 28, 172, 120, A}; -%name_to_color({crayon, 'mountain meadow', A}) -> { 48, 186, 143, A}; -%name_to_color({crayon, shamrock, A}) -> { 69, 206, 162, A}; -%name_to_color({crayon, 'jungle green', A}) -> { 59, 176, 143, A}; -%name_to_color({crayon, 'caribbean green', A}) -> { 28, 211, 162, A}; -%name_to_color({crayon, 'tropical rain forest', A}) -> { 23, 128, 109, A}; -%name_to_color({crayon, 'pine green', A}) -> { 21, 128, 120, A}; -%name_to_color({crayon, 'robin egg blue', A}) -> { 31, 206, 203, A}; -%name_to_color({crayon, aquamarine, A}) -> { 120, 219, 226, A}; -%name_to_color({crayon, 'turquoise blue', A}) -> { 119, 221, 231, A}; -%name_to_color({crayon, 'sky blue', A}) -> { 128, 218, 235, A}; -%name_to_color({crayon, 'outer space', A}) -> { 65, 74, 76, A}; -%name_to_color({crayon, 'blue green', A}) -> { 25, 158, 189, A}; -%name_to_color({crayon, 'pacific blue', A}) -> { 28, 169, 201, A}; -%name_to_color({crayon, cerulean, A}) -> { 29, 172, 214, A}; -%name_to_color({crayon, cornflower, A}) -> { 154, 206, 235, A}; -%name_to_color({crayon, 'midnight blue', A}) -> { 26, 72, 118, A}; -%name_to_color({crayon, 'navy blue', A}) -> { 25, 116, 210, A}; -%name_to_color({crayon, denim, A}) -> { 43, 108, 196, A}; -%name_to_color({crayon, blue, A}) -> { 31, 117, 254, A}; -%name_to_color({crayon, periwinkle, A}) -> { 197, 208, 230, A}; -%name_to_color({crayon, 'cadet blue', A}) -> { 176, 183, 198, A}; -%name_to_color({crayon, indigo, A}) -> { 93, 118, 203, A}; -%name_to_color({crayon, 'wild blue yonder', A}) -> { 162, 173, 208, A}; -%name_to_color({crayon, manatee, A}) -> { 151, 154, 170, A}; -%name_to_color({crayon, 'blue bell', A}) -> { 173, 173, 214, A}; -%name_to_color({crayon, 'blue violet', A}) -> { 115, 102, 189, A}; -%name_to_color({crayon, 'purple heart', A}) -> { 116, 66, 200, A}; -%name_to_color({crayon, 'royal purple', A}) -> { 120, 81, 169, A}; -%name_to_color({crayon, 'purple mountains majesty', A}) -> { 157, 129, 186, A}; -%name_to_color({crayon, violet, A}) -> { 146, 110, 174, A}; -%name_to_color({crayon, wisteria, A}) -> { 205, 164, 222, A}; -%name_to_color({crayon, 'vivid violet', A}) -> { 143, 80, 157, A}; -%name_to_color({crayon, fuchsia, A}) -> { 195, 100, 197, A}; -%name_to_color({crayon, 'shocking pink', A}) -> { 251, 126, 253, A}; -%name_to_color({crayon, 'pink flamingo', A}) -> { 252, 116, 253, A}; -%name_to_color({crayon, plum, A}) -> { 142, 69, 133, A}; -%name_to_color({crayon, 'hot magenta', A}) -> { 255, 29, 206, A}; -%name_to_color({crayon, 'purple pizzazz', A}) -> { 255, 29, 206, A}; -%name_to_color({crayon, 'razzle dazzle rose', A}) -> { 255, 72, 208, A}; -%name_to_color({crayon, orchid, A}) -> { 230, 168, 215, A}; -%name_to_color({crayon, 'red violet', A}) -> { 192, 68, 143, A}; -%name_to_color({crayon, eggplant, A}) -> { 110, 81, 96, A}; -%name_to_color({crayon, cerise, A}) -> { 221, 68, 146, A}; -%name_to_color({crayon, 'wild strawberry', A}) -> { 255, 67, 164, A}; -%name_to_color({crayon, magenta, A}) -> { 246, 100, 175, A}; -%name_to_color({crayon, lavender, A}) -> { 252, 180, 213, A}; -%name_to_color({crayon, 'cotton candy', A}) -> { 255, 188, 217, A}; -%name_to_color({crayon, 'violet red', A}) -> { 247, 83, 148, A}; -%name_to_color({crayon, 'carnation pink', A}) -> { 255, 170, 204, A}; -%name_to_color({crayon, razzmatazz, A}) -> { 227, 37, 107, A}; -%name_to_color({crayon, 'piggy pink', A}) -> { 253, 215, 228, A}; -%name_to_color({crayon, 'jazzberry jam', A}) -> { 202, 55, 103, A}; -%name_to_color({crayon, blush, A}) -> { 222, 93, 131, A}; -%name_to_color({crayon, 'tickle me pink', A}) -> { 252, 137, 172, A}; -%name_to_color({crayon, 'pink sherbet', A}) -> { 247, 128, 161, A}; -%name_to_color({crayon, maroon, A}) -> { 200, 56, 90, A}; -%name_to_color({crayon, red, A}) -> { 238, 32, 77, A}; -%name_to_color({crayon, 'radical red', A}) -> { 255, 73, 108, A}; -%name_to_color({crayon, mauvelous, A}) -> { 239, 152, 170, A}; -%name_to_color({crayon, 'wild watermelon', A}) -> { 252, 108, 133, A}; -%name_to_color({crayon, scarlet, A}) -> { 252, 40, 71, A}; -%name_to_color({crayon, salmon, A}) -> { 255, 155, 170, A}; -%name_to_color({crayon, 'brick red', A}) -> { 203, 65, 84, A}; -%name_to_color({crayon, white, A}) -> { 237, 237, 237, A}; -%name_to_color({crayon, timberwolf, A}) -> { 219, 215, 210, A}; -%name_to_color({crayon, silver, A}) -> { 205, 197, 194, A}; -%name_to_color({crayon, gray, A}) -> { 149, 145, 140, A}; -%name_to_color({crayon, black, A}) -> { 35, 35, 35, A}. - - text(I, {Xs,Ys} = Sp, Font, Text, Color) -> {FW,FH} = egd_font:size(Font), Length = length(Text), diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl index f5e32c2a0f..cea9d2d926 100644 --- a/lib/percept/src/egd_render.erl +++ b/lib/percept/src/egd_render.erl @@ -35,7 +35,7 @@ binary(Image, Type) -> parallel_binary(precompile(Image),Type). parallel_binary(Image = #image{ height = Height },Type) -> - case lists:min([erlang:system_info(schedulers), Height]) of + case erlang:min(erlang:system_info(schedulers), Height) of 1 -> % if the height or the number of schedulers is 1 % do the scanlines in this process. @@ -120,27 +120,15 @@ receive_binaries(H, Bins) when H > 0 -> scanline(Y, Os, {_,_,Width,_}=LSB, Type) -> - OLSs = parse_objects_on_line(Y-1, Width, Os), - URLSs = resulting_line_spans([LSB|OLSs],Type), - - % FIXME: Can we keep the list sorted instead of sorting it? - % sort descending - RLSs = lists:reverse(URLSs), - - resulting_scanline(RLSs,Width). - -resulting_scanline(RLSs, Width) -> resulting_scanline(RLSs, Width, []). -resulting_scanline([], _, Scanlines) -> Scanlines; -resulting_scanline([{_,Xl, Xr, C} | RLSs], Width, Scanlines) -> - {R,G,B,_} = rgb_float2byte(C), - Scanline = lists:duplicate(trunc(Xr - Xl + 1), <<R:8,G:8,B:8>>), - resulting_scanline(RLSs, Width, [Scanline|Scanlines]). + OLSs = parse_objects_on_line(Y-1, Width, Os), + RLSs = resulting_line_spans([LSB|OLSs],Type), + [ lists:duplicate(Xr - Xl + 1, <<(trunc(R*255)):8,(trunc(G*255)):8,(trunc(B*255)):8>>) || {_,Xl, Xr, {R,G,B,_}} <- RLSs ]. resulting_line_spans(LSs,Type) -> %% Build a list of "transitions" from left to right. Trans = line_spans_to_trans(LSs), %% Convert list of "transitions" to linespans. - trans_to_line_spans(Trans,Type). + trans_to_line_spans(Trans,Type). line_spans_to_trans(LSs) -> line_spans_to_trans(LSs,[],0). @@ -194,19 +182,14 @@ color([{_,C}|_],opaque) -> C; color(Layers,alpha) -> color1({0,0,0,0},Layers). color1(Color,[]) -> Color; -color1(Color,[{_,C}|Layers]) -> color1(blend(Color,C),Layers). - -blend(C1,C2) -> alpha_blend(C1,C2). +color1(Color,[{_,C}|Layers]) -> color1(alpha_blend(Color,C),Layers). modify_layers(Layers,[]) -> Layers; -modify_layers(Layers,[{{_,Z,Op},C}|Trans]) -> - modify_layers(case Op of - start -> - add_layer(Layers,Z,C); - stop -> - remove_layer(Layers,Z,C) - end, - Trans). +modify_layers(Layers,[{{_,Z,start},C}|Trans]) -> + modify_layers(add_layer(Layers, Z, C), Trans); +modify_layers(Layers,[{{_,Z,stop },C}|Trans]) -> + modify_layers(remove_layer(Layers, Z, C), Trans). + add_layer([{Z1,_}=H|Layers],Z,C) when Z1 > Z -> [H|add_layer(Layers,Z,C)]; @@ -216,7 +199,7 @@ add_layer(Layers,Z,C) -> remove_layer(Layers,Z,C) -> Layers -- [{Z,C}]. -alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) -> +alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) when is_float(A1), is_float(A2)-> Beta = A2*(1.0 - A1), A = A1 + Beta, R = R1*A1 + R2*Beta, @@ -232,7 +215,7 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) -> false -> parse_objects_on_line(Y, Z + 1, Width, Os, Out); true -> - OLs = object_line_data(Y, Z, O), + OLs = object_line_data(Y, Z, O), TOLs = trim_object_line_data(OLs, Width), parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out]) end. @@ -240,15 +223,13 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) -> trim_object_line_data(OLs, Width) -> trim_object_line_data(OLs, Width, []). trim_object_line_data([], _, Out) -> Out; + +trim_object_line_data([{_, Xl, _, _}|OLs], Width, Out) when Xl > Width -> + trim_object_line_data(OLs, Width, Out); +trim_object_line_data([{_, _, Xr, _}|OLs], Width, Out) when Xr < 0 -> + trim_object_line_data(OLs, Width, Out); trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) -> - if - Xl > Width -> - trim_object_line_data(OLs, Width, Out); - Xr < 0 -> - trim_object_line_data(OLs, Width, Out); - true -> - trim_object_line_data(OLs, Width, [{Z, lists:max([0,Xl]), lists:min([Xr,Width]), C}|Out]) - end. + trim_object_line_data(OLs, Width, [{Z, erlang:max(0,Xl), erlang:min(Xr,Width), C}|Out]). % object_line_data % In: @@ -264,7 +245,8 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) -> % Calculate the length (start and finish index) of an objects horizontal % line given the height index. -object_line_data(Y, Z, Object) -> object_line_data(Y, Z, Object, Object#image_object.type). +object_line_data(Y, Z, Object) -> + object_line_data(Y, Z, Object, Object#image_object.type). object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, rectangle) -> if Y0 =:= Y ; Y1 =:= Y -> @@ -277,70 +259,43 @@ object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, recta object_line_data(_Y, Z, #image_object{ span = {X0, _, X1, _}, color = C}, filled_rectangle) -> [{Z, X0, X1, C}]; -object_line_data(Y, Z, #image_object{ span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) -> +object_line_data(Y, Z, #image_object{ internals={Xr,Yr,Yr2}, span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) -> if - X1 - X0 == 0 -> % if the width is exactly one pixel - [{Z, X1, X0, C}]; - X1 - X0 < 0 -> throw(bad_ellipse_width); - Y1 - Y0 == 0 -> % Height exactly one pixel, get width + X1 - X0 == 0; Y1 - Y0 == 0 -> [{Z, X0, X1, C}]; true -> - Xr = (X1 - X0)/2, - Yr = (Y1 - Y0)/2, - Yo = trunc(Y - Y0 - Yr), + Yo = trunc(Y - Y0 - Yr), Yo2 = Yo*Yo, - Yr2 = Yr*Yr, - Xo = math:sqrt((1 - Yo2/Yr2))*Xr, + Xo = math:sqrt((1 - Yo2/Yr2))*Xr, [{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}] end; object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, filled_triangle) -> - case lists:keysearch(Y, 1, Is) of - {value, {Y, Xl, Xr}} -> [{Z, Xl, Xr, C}]; + case lists:keyfind(Y, 1, Is) of + {Y, Xl, Xr} -> [{Z, Xl, Xr, C}]; false -> [] end; object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, line) -> case dict:find(Y, Is) of - %{ok, {Xl, Xr}} -> [{Z, Xl, Xr, C}]; {ok, Ls} -> [{Z, Xl, Xr, C}||{Xl,Xr} <- Ls]; _ -> [] end; -object_line_data(Y, Z, O, polygon) -> - Is = lists:filter( - fun({Yp,_,_}) -> - if Yp == Y -> true; true -> false end - end, O#image_object.intervals), - [ {Z, Xl, Xr, O#image_object.color} || {_, Xl, Xr} <- Is]; - -object_line_data(Y, Z, #image_object{ color = C, intervals = Is }, text_horizontal) -> - % FIXME: optimize! - lists:foldl( - fun ({Yg,Xl,Xr}, Out) -> - if - Yg == Y -> - [{Z, Xl, Xr, C}|Out]; - true -> - Out - end - end, [], Is); +object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, polygon) -> + [{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y]; + +object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, text_horizontal) -> + [{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y]; + object_line_data(_, Z, #image_object{ span = {X0,_,X1,_}, color = C}, _) -> - % faked [{Z, X0, X1, C}]. -is_object_on_line(Y, Object) -> - is_object_bounds_on_line(Y, Object#image_object.span). +is_object_on_line(Y, #image_object{ span = Span }) -> + is_object_bounds_on_line(Y, Span). -is_object_bounds_on_line(Y, {_,Y0,_,Y1}) -> - if - Y < Y0 -> false; - Y > Y1 -> false; - true -> true - end. - -rgb_float2byte({R,G,B,A}) -> - {trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}. +is_object_bounds_on_line(Y, {_,Y0,_,Y1}) when Y < Y0 ; Y > Y1 -> false; +is_object_bounds_on_line(_, _) -> true. %%% primitives to line_spans @@ -360,6 +315,12 @@ precompile_objects([O = #image_object{ type = filled_triangle, points = [P0,P1,P precompile_objects([O = #image_object{ type = polygon, points = Pts } | Os], Out) -> precompile_objects(Os, [O#image_object{ intervals = polygon_ls(Pts) } | Out]); + +precompile_objects([O = #image_object{ type = filled_ellipse, span = {X0,Y0,X1,Y1} } | Os], Out) -> + Xr = (X1 - X0)/2, + Yr = (Y1 - Y0)/2, + Yr2 = Yr*Yr, + precompile_objects(Os, [ O#image_object{ internals={Xr,Yr,Yr2} } | Out]); precompile_objects([O = #image_object{ type = arc, points = [P0,P1], internals = D }| Os], Out) -> Es = egd_primitives:arc_to_edges(P0, P1, D), @@ -579,13 +540,7 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) -> true -> 1; false -> -1 end, - case Steep of - false -> - line_ls_step_not_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, []); - true -> - line_ls_step_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, []) - end. - + line_ls_step(X0, X1,Y0, DX, DY, Ystep, Error, X0, Steep, []). %% line_ls_step_(not)_steep %% In: @@ -594,27 +549,17 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) -> %% Purpose: %% Produce an line_interval for each Yi (Y index) -% Iterating the X-axis - -line_ls_step_not_steep({X,X1},Y,Dx,Dy,Ys,E, X0, LSs) when X < X1 -> - case E >= 0 of - true -> - line_ls_step_not_steep({X+1,X1},Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1,[{Y,X0,X}|LSs]); - false -> - line_ls_step_not_steep({X+1,X1},Y,Dx,Dy,Ys, E + Dy, X0, LSs) - end; -line_ls_step_not_steep({X,_},Y,_Dx,_Dy,_Ystep,_E,X0,LSs) -> - [{Y,X0,X}|LSs]. - -% Iterating the Y-axis -line_ls_step_steep({X,X1},Y,Dx,Dy,Ystep,E, X0, LSs) when X =< X1 -> - case E >= 0 of - true -> - line_ls_step_steep({X + 1,X1},Y+Ystep,Dx,Dy,Ystep,E - Dx + Dy,X,[{X,Y,Y}|LSs]); - false -> - line_ls_step_steep({X + 1,X1},Y,Dx,Dy,Ystep,E + Dy,X0, [{X,Y,Y}|LSs]) - end; -line_ls_step_steep({_X,_},_Y,_Dx,_Dy,_Ystep,_E,_X0,LSs) -> +line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1, E >= 0 -> + line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1, Steep, [{Y,X0,X}|LSs]); +line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1 -> + line_ls_step(X+1,X1,Y,Dx,Dy,Ys, E + Dy, X0, Steep, LSs); +line_ls_step(X, _X1, Y, _Dx, _Dy, _Ys, _E, X0, false, LSs) -> + [{Y,X0,X}|LSs]; +line_ls_step(X, X1, Y, Dx, Dy, Ys, E, _X0, true = Steep, LSs) when X =< X1, E >= 0 -> + line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X, Steep, [{X,Y,Y}|LSs]); +line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, true = Steep, LSs) when X =< X1 -> + line_ls_step(X+1,X1,Y,Dx,Dy,Ys,E + Dy, X0, Steep, [{X,Y,Y}|LSs]); +line_ls_step(_X,_,_Y,_Dx,_Dy,_Ys,_E,_X0,_,LSs) -> LSs. % Text @@ -707,3 +652,4 @@ eps_header(W,H) -> eps_footer() -> "%%EOF\n". + diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl index 603ad628d3..a2595400dd 100644 --- a/lib/percept/test/egd_SUITE.erl +++ b/lib/percept/test/egd_SUITE.erl @@ -29,6 +29,7 @@ -export([ image_create_and_destroy/1, image_shape/1, + image_primitives/1, image_colors/1, image_font/1, image_png_compliant/1 @@ -38,8 +39,7 @@ -define(default_timeout, ?t:minutes(1)). init_per_suite(Config) when is_list(Config) -> - {A1,A2,A3} = now(), - random:seed(A1, A2, A3), + random:seed(now()), Config. end_per_suite(Config) when is_list(Config) -> @@ -59,6 +59,7 @@ all(suite) -> [ image_create_and_destroy, image_shape, + image_primitives, image_colors, image_font, image_png_compliant @@ -145,7 +146,43 @@ image_shape(Config) when is_list(Config) -> ?line ok = egd:destroy(Im), erase(image_size), ok. - + +image_primitives(suite) -> + []; +image_primitives(doc) -> + ["Image shape api test."]; +image_primitives(Config) when is_list(Config) -> + {W,H} = get_size(?config(max_size, Config)), + put(image_size, {W,H}), + + ?line Im0 = egd_primitives:create(W, H), + ?line Fgc = egd:color({25,25,255}), + ?line Bgc = egd:color({0,250,25}), + + ?line Im1 = lists:foldl(fun + ({Function, Arguments}, Im) -> + ?line erlang:apply(egd_primitives, Function, [Im|Arguments]) + end, Im0, + [{Fs, [get_point(), get_point(), Bgc]} || Fs <- [line, rectangle, filledEllipse, arc]] ++ + [{pixel, [get_point(), Bgc]}, + {filledTriangle, [get_point(), get_point(), get_point(), Bgc]}]), + + Pt1 = get_point(), + Pt2 = get_point(), + + ?line Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc), + + ?line Bitmap = egd_render:binary(Im2, opaque), + + ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc), + ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc), + + erase(image_size), + ok. + + + + image_font(suite) -> []; image_font(doc) -> diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml index 8fb4ea5fd0..8cfe57f670 100644 --- a/lib/public_key/doc/src/cert_records.xml +++ b/lib/public_key/doc/src/cert_records.xml @@ -41,10 +41,18 @@ </p> <p>Use the following include directive to get access to the - records and constant macros described in the following sections.</p> + records and constant macros (OIDs) described in the following sections.</p> <code> -include_lib("public_key/include/public_key.hrl"). </code> + <p>The used specification is available in <c>OTP-PKIX.asn1</c>, + which is an amelioration of + the <c>PKIX1Explicit88.asn1</c>, <c>PKIX1Implicit88.asn1</c> + and <c>PKIX1Algorithms88.asn1</c> modules. + You find all these modules in the <c>asn1</c> subdirectory + of the application <c>public_key</c>. + </p> + <section> <title>Common Data Types</title> @@ -148,8 +156,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p> }. </code> -<p><c>id_attributes() = ?oid_name_as_erlang_atom</c> -for available oid names see table below. Ex: ?'id-at-name'</p> +<p><c>id_attributes() </c></p> <table> <row> <cell align="left" valign="middle">OID name</cell> @@ -231,8 +238,7 @@ for available oid names see table below. Ex: ?'id-at-name'</p> }. </code> -<p><c> id_public_key_algorithm() = ?oid_name_as_erlang_atom</c> for available -oid names see table below. Ex: ?'id-dsa'</p> +<p><c> id_public_key_algorithm() </c></p> <table> <row> <cell align="left" valign="middle">OID name</cell> @@ -264,14 +270,11 @@ oid names see table below. Ex: ?'id-dsa'</p> }. </code> -<p><c>id_extensions() = ?oid_name_as_erlang_atom</c> for -available oid names see tables. Ex: ?'id-ce-authorityKeyIdentifier'<seealso -marker="#StdCertExt">Standard Certificate Extensions</seealso>, - <seealso - marker="#PrivIntExt">Private Internet Extensions</seealso>, <seealso - marker="#CRLCertExt">CRL Extensions</seealso> and - <seealso - marker="#CRLEntryExt">CRL Entry Extensions</seealso>. +<p><c>id_extensions()</c> + <seealso marker="#StdCertExt">Standard Certificate Extensions</seealso>, + <seealso marker="#PrivIntExt">Private Internet Extensions</seealso>, + <seealso marker="#CRLCertExt">CRL Extensions</seealso> and + <seealso marker="#CRLEntryExt">CRL Entry Extensions</seealso>. </p> </section> @@ -368,9 +371,8 @@ marker="#StdCertExt">Standard Certificate Extensions</seealso>, decipherOnly </c></p> - <p><c> id_key_purpose() = ?oid_name_as_erlang_atom</c> for available -oid names see table below. Ex: ?'id-kp-serverAuth'</p> - + <p><c> id_key_purpose()</c></p> + <table> <row> <cell align="left" valign="middle">OID name</cell> diff --git a/lib/ssl/doc/src/create_certs.xml b/lib/ssl/doc/src/create_certs.xml index 15958ee457..79cc8a0537 100644 --- a/lib/ssl/doc/src/create_certs.xml +++ b/lib/ssl/doc/src/create_certs.xml @@ -98,12 +98,12 @@ <title>Creating the Erlang root CA</title> <p>The Erlang root CA is created with the command</p> <code type="none"> -\011openssl req -new -x509 -config /some/path/req.cnf \\ -\011 -keyout /some/path/key.pem -out /some/path/cert.pem </code> + openssl req -new -x509 -config /some/path/req.cnf \\ + -keyout /some/path/key.pem -out /some/path/cert.pem </code> <p>where the option <c>-new</c> indicates that we want to create a new certificate request and the option <c>-x509</c> implies that a self-signed certificate is created. - </p> + </p> </section> <section> @@ -111,12 +111,12 @@ <p>The OTP CA is created by first creating a certificate request with the command</p> <code type="none"> -\011openssl req -new -config /some/path/req.cnf \\ -\011 -keyout /some/path/key.pem -out /some/path/req.pem </code> + openssl req -new -config /some/path/req.cnf \\ + -keyout /some/path/key.pem -out /some/path/req.pem </code> <p>and the ask the Erlang CA to sign it:</p> <code type="none"> -\011openssl ca -batch -notext -config /some/path/req.cnf \\ -\011 -extensions ca_cert -in /some/path/req.pem -out /some/path/cert.pem </code> + openssl ca -batch -notext -config /some/path/req.cnf \\ + -extensions ca_cert -in /some/path/req.pem -out /some/path/cert.pem </code> <p>where the option <c>-extensions</c> refers to a section in the configuration file saying that it should create a CA certificate, and not a plain user certificate. diff --git a/lib/ssl/doc/src/new_ssl.xml b/lib/ssl/doc/src/new_ssl.xml index f50f714fe6..a11919eb51 100644 --- a/lib/ssl/doc/src/new_ssl.xml +++ b/lib/ssl/doc/src/new_ssl.xml @@ -437,30 +437,17 @@ end </func> <func> - <name>peercert(Socket) -> </name> - <name>peercert(Socket, Opts) -> {ok, Cert} | {error, Reason}</name> + <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> <fsummary>Return the peer certificate.</fsummary> <type> <v>Socket = sslsocket()</v> - <v>Opts = [] | [otp] | [plain] </v> - <v>Cert = term()</v> + <v>Cert = binary()</v> <v>Subject = term()</v> </type> <desc> - <p><c>peercert(Cert)</c> is equivalent to <c>peercert(Cert, [])</c>. - </p> - <p>The form of the returned certificate depends on the - options. - </p> - <p>If the options list is empty the certificate is returned as - a DER encoded binary. - </p> - <p>The option <c>otp</c> or <c>plain</c> implies that the - certificate will be returned as a parsed ASN.1 structure in the - form of an Erlang term. For detail see the public_key application. - Currently only plain is officially supported see the public_key users - guide. - </p> + <p>The peer certificate is returned as a DER encoded binary. + The certificate can be decoded with <c>public_key:pkix_decode_cert/2</c>. + </p> </desc> </func> <func> diff --git a/lib/ssl/doc/src/pkix_certs.xml b/lib/ssl/doc/src/pkix_certs.xml index 47818c1b7d..1de807cadc 100644 --- a/lib/ssl/doc/src/pkix_certs.xml +++ b/lib/ssl/doc/src/pkix_certs.xml @@ -34,219 +34,24 @@ <p>Certificates were originally defined by ITU (CCITT) and the latest definitions are described in <cite id="X.509"></cite>, but those definitions are (as always) not working. - </p> + </p> <p>Working certificate definitions for the Internet Community are found - in the the PKIX RFCs <cite id="rfc3279"></cite>and <cite id="rfc3280"></cite>. + in the the PKIX RFCs <cite id="rfc3279"></cite> and <cite id="rfc3280"></cite>. The parsing of certificates in the Erlang/OTP SSL application is based on those RFCS. - </p> + </p> <p>Certificates are defined in terms of ASN.1 (<cite id="X.680"></cite>). For an introduction to ASN.1 see <url href="http://asn1.elibel.tm.fr/">ASN.1 Information Site</url>. - </p> + </p> </section> <section> <title>PKIX Certificates</title> - <p>Here we base the PKIX certificate definitions in RFCs <cite id="rfc3279"></cite>and <cite id="rfc3280"></cite>. We however present the - definitions according to <c>SSL-PKIX.asn1</c> module, - which is an amelioration of the <c>PKIX1Explicit88.asn1</c>, - <c>PKIX1Implicit88.asn1</c>, and <c>PKIX1Algorithms88.asn1</c> - modules. You find all these modules in the <c>pkix</c> subdirectory - of SSL. - </p> - <p>The Erlang terms that are returned by the functions - <c>ssl:peercert/1/2</c>, <c>ssl_pkix:decode_cert/1/2</c>, and - <c>ssl_pkix:decode_cert_file/1/2</c> when the option <c>ssl</c> - is used in those functions, correspond the ASN.1 structures - described in the sequel. - </p> - - <section> - <title>Certificate and TBSCertificate</title> - <code type="none"> -Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm SignatureAlgorithm, - signature BIT STRING } - -TBSCertificate ::= SEQUENCE { - version [0] Version DEFAULT v1, - serialNumber CertificateSerialNumber, - signature SignatureAlgorithm, - issuer Name, - validity Validity, - subject Name, - subjectPublicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - extensions [3] Extensions OPTIONAL - -- If present, version MUST be v3 -- } - -Version ::= INTEGER { v1(0), v2(1), v3(2) } - -CertificateSerialNumber ::= INTEGER - -Validity ::= SEQUENCE { - notBefore Time, - notAfter Time } - -Time ::= CHOICE { - utcTime UTCTime, - generalTime GeneralizedTime } - </code> - <p>The meaning of the fields <c>version</c>, <c>serialNumber</c>, - and <c>validity</c> are quite obvious given the type definitions - above, so we do not go further into their details. - </p> - <p>The <c>signatureAlgorithm</c> field of <c>Certificate</c> and - the <c>signature</c> field of <c>TBSCertificate</c> contain - the name and parameters of the algorithm used for signing the - certificate. The values of these two fields must be equal. - </p> - <p>The <c>signature</c> field of <c>Certificate</c> contains the - value of the signature that the issuer computed by using the - prescribed algorithm. - </p> - <p>The <c><![CDATA[issuer<c> and <c>subject]]></c> fields can contain many - different types av data, and is therefore considered in a - separate section. The same holds for the <c>extensions</c> - field. - The <c>issuerUniqueID</c> and the <c>subjectUniqueID</c> fields - are not considered further.</p> - </section> - - <section> - <title>TBSCertificate issuer and subject</title> - <p></p> - <code type="none"><![CDATA[ -Name ::= CHOICE { -- only one possibility for now -- - rdnSequence RDNSequence } - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -DistinguishedName ::= RDNSequence - -RelativeDistinguishedName ::= - SET SIZE (1 .. MAX) OF AttributeTypeAndValue - -AttributeTypeAndValue ::= SEQUENCE { - type ATTRIBUTE-TYPE-AND-VALUE-CLASS.&id -\011\011({SupportedAttributeTypeAndValues}), - value ATTRIBUTE-TYPE-AND-VALUE-CLASS.&Type -\011\011({SupportedAttributeTypeAndValues}{@type}) } - -SupportedAttributeTypeAndValues ATTRIBUTE-TYPE-AND-VALUE-CLASS ::= -\011{ name | surname | givenName | initials | generationQualifier | -\011 commonName | localityName | stateOrProvinceName | organizationName | -\011 organizationalUnitName | title | dnQualifier | countryName | -\011 serialNumber | pseudonym | domainComponent | emailAddress } ]]></code> - </section> - - <section> - <title>TBSCertificate extensions</title> - <p>The <c>extensions</c> field of a <c>TBScertificate</c> is a - sequence of type <c>Extension</c>, defined as follows,</p> - <code type="none"> -Extension ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue ANY } </code> - <p>Each extension has a unique object identifier. An extension - with a <c>critical</c> value set to <c>TRUE</c><em>must</em> - be recognised by the reader of a certificate, or else the - certificate must be rejected. - </p> - <p>Extensions are divided into two groups: standard extensions - and internet certificate extensions. All extensions listed in - the table that follows are standard extensions, except for - <c>authorityInfoAccess</c> and <c>subjectInfoAccess</c>, which - are internet extensions. - </p> - <p>Depending on the object identifier the <c>extnValue</c> is - parsed into an appropriate welldefined structure. - </p> - <p>The following table shows the purpose of each extension, but - does not specify the structure. To see the structure consult - the <c>PKIX1Implicit88.asn1</c> module. - </p> - <table> - <row> - <cell align="left" valign="middle">authorityKeyIdentifier</cell> - <cell align="left" valign="middle">Used by to identify a certificate signed that has multiple signing keys. </cell> - </row> - <row> - <cell align="left" valign="middle">subjectKeyIdentifier</cell> - <cell align="left" valign="middle">Used to identify certificates that contain a public key. Must appear i CA certificates.</cell> - </row> - <row> - <cell align="left" valign="middle">keyUsage </cell> - <cell align="left" valign="middle">Defines the purpose of the certificate. Can be one or several of<c>digitalSignature</c>, <c>nonRepudiation</c>,<c>keyEncipherment</c>, <c>dataEncipherment</c>,<c>keyAgreement</c>, <c>keyCertSign</c>, <c>cRLSign</c>,<c>encipherOnly</c>, <c>decipherOnly</c>.</cell> - </row> - <row> - <cell align="left" valign="middle">privateKeyUsagePeriod </cell> - <cell align="left" valign="middle">Allows certificate issuer to provide a private key usage period to be short than the certificate usage period.</cell> - </row> - <row> - <cell align="left" valign="middle">certificatePolicies</cell> - <cell align="left" valign="middle">Contains one or more policy information terms indicating the policies under which the certificate has been issued.</cell> - </row> - <row> - <cell align="left" valign="middle">policyMappings</cell> - <cell align="left" valign="middle">Used i CA certificates. </cell> - </row> - <row> - <cell align="left" valign="middle">subjectAltName</cell> - <cell align="left" valign="middle">Allows additional identities to be bound the the subject. </cell> - </row> - <row> - <cell align="left" valign="middle">issuerAltName</cell> - <cell align="left" valign="middle">Allows additional identities to be bound the the issuer.</cell> - </row> - <row> - <cell align="left" valign="middle">subjectDirectoryAttributes</cell> - <cell align="left" valign="middle">Conveys identity attributes of the subject.</cell> - </row> - <row> - <cell align="left" valign="middle">basicConstraints</cell> - <cell align="left" valign="middle">Tells if the certificate holder is a CA or not.</cell> - </row> - <row> - <cell align="left" valign="middle">nameConstraints</cell> - <cell align="left" valign="middle">Used in CA certificates.</cell> - </row> - <row> - <cell align="left" valign="middle">policyConstraints</cell> - <cell align="left" valign="middle">Used in CA certificates.</cell> - </row> - <row> - <cell align="left" valign="middle">extKeyUsage</cell> - <cell align="left" valign="middle">Indicates for which purposed the public key may be used. </cell> - </row> - <row> - <cell align="left" valign="middle">cRLDistributionPoints</cell> - <cell align="left" valign="middle">Indicates how CRL (Certificate Revokation List) information is obtained.</cell> - </row> - <row> - <cell align="left" valign="middle">inhibitAnyPolicy</cell> - <cell align="left" valign="middle">Used i CA certificates.</cell> - </row> - <row> - <cell align="left" valign="middle">freshestCRL</cell> - <cell align="left" valign="middle">For CRLs.</cell> - </row> - <row> - <cell align="left" valign="middle">authorityInfoAccess</cell> - <cell align="left" valign="middle">How to access CA information of the issuer of the certificate.</cell> - </row> - <row> - <cell align="left" valign="middle">subjectInfoAccess</cell> - <cell align="left" valign="middle">How to access CA information of the subject of the certificate.</cell> - </row> - <tcaption>PKIX Extensions</tcaption> - </table> - </section> + <p>Certificate handling is now handled by the <c>public_key</c> application.</p> + <p> + DER encoded certificates returned by <c>ssl:peercert/1</c> can for example + be decoded by the <c>public_key:pkix_decode_cert/2</c> function. + </p> </section> </chapter> diff --git a/lib/ssl/doc/src/remember.xml b/lib/ssl/doc/src/remember.xml deleted file mode 100644 index 799627a33c..0000000000 --- a/lib/ssl/doc/src/remember.xml +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>2003</year><year>2009</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - </legalnotice> - - <title>PKIX Certificates</title> - <prepared>UAB/F/P Peter Högfeldt</prepared> - <docno></docno> - <date>2003-06-09</date> - <rev>A</rev> - <file>pkix_certs.sgml</file> - </header> - - <section> - <title>Introduction to Certificates</title> - <p><em>Outline:</em></p> - <list type="bulleted"> - <item>SSL/TLS protocol - server must have certificate - -what - the the server sends to the client - client may verify the - server - server may ask client for certificate - what the - client sends to the server - server may then verify the client - - verification - certificate chains - root certificates - - public keys - key agreement - purpose of certificate - main - contents of certificate - contents have increased as time went - by - common file formats for certificates. - </item> - <item>private keys - password protection - key generation - file - formats. - </item> - <item>ssl_pkix and alternate decodings. - </item> - <item>Attribute Certificates (not used by SSL). - </item> - <item>Certificate requests - certificate authorities - signing of - certificates - certificate revocation lists. - </item> - <item>standards: ASN.1, X.509, X.520, PKIX, PKCS, PEM. - </item> - <item>incompatibilities between standards (X.509-1997 vs old) - the - ASN.1 problem of ANY, BIT STRING and OCTET STRING - the module - ssl_pkix. - </item> - <item>test suites: NIST - </item> - <item>Warnings: *creation* of trusted certificate (OpenSSL). - </item> - <item>Erlang SSL and certificates - </item> - <item>The need for seeding the random generator. See also John - S. Denker: High-Entropy Symbol Generator - (http://www.monmouth.com/~jsd). - </item> - <item>links to standards and documents. Books (Rescorla). - </item> - <item>ASN.1 crash course. - </item> - <item>Nagel algorithm. - </item> - </list> - <p>For an introduction to ASN.1 see <url href="http://asn1.elibel.tm.fr/">ASN.1 Information Site</url>. - </p> - </section> -</chapter> - - diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 9b780b14ce..217eb791d0 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -347,39 +347,17 @@ </desc> </func> <func> - <name>peercert(Socket) -> </name> - <name>peercert(Socket, Opts) -> {ok, Cert} | {ok, Subject} | {error, Reason}</name> + <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name> <fsummary>Return the peer certificate.</fsummary> <type> <v>Socket = sslsocket()</v> - <v>Opts = [pkix | ssl | subject]()</v> - <v>Cert = term()()</v> + <v>Cert = binary()()</v> <v>Subject = term()()</v> </type> <desc> - <p><c>peercert(Cert)</c> is equivalent to <c>peercert(Cert, [])</c>. - </p> - <p>The form of the returned certificate depends on the - options. - </p> - <p>If the options list is empty the certificate is returned as - a DER encoded binary. - </p> - <p>The options <c>pkix</c> and <c>ssl</c> implies that the - certificate is returned as a parsed ASN.1 structure in the - form of an Erlang term. - </p> - <p>The <c>ssl</c> option gives a more elaborate return - structure, with more explicit information. In particular - object identifiers are replaced by atoms. - </p> - <p>The options <c>pkix</c>, and <c>ssl</c> are mutually - exclusive. - </p> - <p>The option <c>subject</c> implies that only the subject's - distinguished name part of the peer certificate is returned. - It can only be used together with the option <c>pkix</c> or - the option <c>ssl</c>.</p> + <p>Returns the DER encoded peer certificate, the certificate can be decoded with + <c>public_key:pkix_decode_cert/2</c>. + </p> </desc> </func> <func> @@ -719,8 +697,7 @@ <section> <title>SEE ALSO</title> - <p>gen_tcp(3), inet(3) - </p> + <p>gen_tcp(3), inet(3) public_key(3) </p> </section> </erlref> diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index 3a6c5e0b60..0cf82fa48b 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -37,7 +37,7 @@ is meant all strings that can be used to denote a file. They can be short relative names like <c>foo.erl</c>, very long absolute name which include a drive designator and directory names like - <c>D:\\usr/local\\bin\\erl/lib\\tools\\foo.erl</c>, or any variations + <c>D:\usr/local\bin\erl/lib\tools\foo.erl</c>, or any variations in between.</p> <p>In Windows, all functions return file names with forward slashes only, even if the arguments contain back slashes. Use @@ -173,7 +173,7 @@ name() = string() | atom() | DeepList 14> <input>filename:dirname("kalle.erl").</input> "." -5> <input>filename:dirname("\\\\usr\\\\src/kalle.erl").</input> % Windows +5> <input>filename:dirname("\\usr\\src/kalle.erl").</input> % Windows "/usr/src"</pre> </desc> </func> @@ -228,7 +228,7 @@ name() = string() | atom() | DeepList 18> <input>filename:join(["a/b///c/"]).</input> "a/b/c" -6> <input>filename:join(["B:a\\\\b///c/"]).</input> % Windows +6> <input>filename:join(["B:a\\b///c/"]).</input> % Windows "b:a/b/c"</pre> </desc> </func> @@ -259,7 +259,7 @@ name() = string() | atom() | DeepList "/usr/local/bin" 7> <input>filename:nativename("/usr/local/bin/").</input> % Windows -"\\\\usr\\\\local\\\\bin"</pre> +"\\usr\\local\\bin"</pre> </desc> </func> <func> @@ -329,7 +329,7 @@ name() = string() | atom() | DeepList ["/","usr","local","bin"] 25> <input>filename:split("foo/bar").</input> ["foo","bar"] -26> <input>filename:split("a:\\\\msdev\\\\include").</input> +26> <input>filename:split("a:\\msdev\\include").</input> ["a:/","msdev","include"]</pre> </desc> </func> diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml index f5d8b9bb48..739cd0bffd 100644 --- a/lib/stdlib/doc/src/gen_fsm.xml +++ b/lib/stdlib/doc/src/gen_fsm.xml @@ -729,6 +729,36 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4 updated internal data.</p> </desc> </func> + <func> + <name>Module:format_status(normal, [PDict, StateData]) -> Status</name> + <fsummary>Optional function for providing a term describing the + current gen_fsm status.</fsummary> + <type> + <v>PDict = [{Key, Value}]</v> + <v>StateData = term()</v> + <v>Status = [term()]</v> + </type> + <desc> + <p><em>This callback is optional, so callback modules need not + export it. The gen_fsm module provides a default + implementation of this function that returns the callback + module state data.</em></p> + <p>This function is called by a gen_fsm process when one + of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> + is invoked to get the gen_fsm status. A callback module + wishing to customise the <c>sys:get_status/1,2</c> return + value exports an instance of <c>format_status/2</c> that + returns a term describing the current status of the + gen_fsm.</p> + <p><c>PDict</c> is the current value of the gen_fsm's + process dictionary.</p> + <p><c>StateData</c> is the internal state data of the + gen_fsm.</p> + <p>The function should return <c>Status</c>, a list of one or + more terms that customise the details of the current state + and status of the gen_fsm.</p> + </desc> + </func> </funcs> <section> diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml index 8496802259..30c04d1d52 100644 --- a/lib/stdlib/doc/src/gen_server.xml +++ b/lib/stdlib/doc/src/gen_server.xml @@ -598,6 +598,35 @@ gen_server:abcast -----> Module:handle_cast/2 <p>The function should return the updated internal state.</p> </desc> </func> + <func> + <name>Module:format_status(normal, [PDict, State]) -> Status</name> + <fsummary>Optional function for providing a term describing the + current gen_server status.</fsummary> + <type> + <v>PDict = [{Key, Value}]</v> + <v>State = term()</v> + <v>Status = [term()]</v> + </type> + <desc> + <p><em>This callback is optional, so callback modules need not + export it. The gen_server module provides a default + implementation of this function that returns the callback + module state.</em></p> + <p>This function is called by a gen_server process when one + of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> + is invoked to get the gen_server status. A callback module + wishing to customise the <c>sys:get_status/1,2</c> return + value exports an instance of <c>format_status/2</c> that + returns a term describing the current status of the + gen_server.</p> + <p><c>PDict</c> is the current value of the gen_server's + process dictionary.</p> + <p><c>State</c> is the internal state of the gen_server.</p> + <p>The function should return <c>Status</c>, a list of one or + more terms that customise the details of the current state + and status of the gen_server.</p> + </desc> + </func> </funcs> <section> diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml index 1b75114031..201787f7b5 100644 --- a/lib/stdlib/doc/src/io_protocol.xml +++ b/lib/stdlib/doc/src/io_protocol.xml @@ -546,7 +546,7 @@ request({get_chars, Encoding, _Prompt, N}, State) -> get_until(Encoding, ?MODULE, until_enough, [N], State); request({get_line, Encoding, _Prompt}, State) -> %% To simplify the code, get_line is implemented using get_until - get_until(Encoding, ?MODULE, until_newline, [$\\n], State); + get_until(Encoding, ?MODULE, until_newline, [$\n], State); </code> <p>Here we have cheated a little by more or less only implementing diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index 41dce7f2a7..e9a32a59d4 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -56,10 +56,10 @@ <note> <p>The Erlang literal syntax for strings give special - meaning to the "\\" (backslash) character. To literally write + meaning to the "\" (backslash) character. To literally write a regular expression or a replacement string containing a backslash in your code or in the shell, two backslashes have to be written: - "\\\\".</p> + "\\".</p> </note> @@ -163,9 +163,9 @@ This option makes it possible to include comments inside complicated patterns. N </taglist> </item> <tag><c>bsr_anycrlf</c></tag> - <item>Specifies specifically that \\R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.</item> + <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.</item> <tag><c>bsr_unicode</c></tag> - <item>Specifies specifically that \\R is to match all the Unicode newline characters (including crlf etc, the default).</item> + <item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).</item> </taglist> </desc> </func> @@ -384,9 +384,9 @@ This option makes it possible to include comments inside complicated patterns. N </taglist> </item> <tag><c>bsr_anycrlf</c></tag> - <item>Specifies specifically that \\R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item> + <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item> <tag><c>bsr_unicode</c></tag> - <item>Specifies specifically that \\R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item> + <item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item> <tag><c>{capture, ValueSpec}</c>/<c>{capture, ValueSpec, Type}</c></tag> <item> @@ -471,9 +471,9 @@ This option makes it possible to include comments inside complicated patterns. N <tag><c>index</c></tag> <item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly imagined) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem contra-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item> <tag><c>list</c></tag> - <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \\C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the\\C sequence when capturing lists.</item> + <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item> <tag><c>binary</c></tag> - <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \\C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item> + <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item> </taglist> </item> </taglist> @@ -544,20 +544,20 @@ This option makes it possible to include comments inside complicated patterns. N <p>The replacement string can contain the special character <c>&</c>, which inserts the whole matching expression in the - result, and the special sequence <c>\\</c>N (where N is an + result, and the special sequence <c>\</c>N (where N is an integer > 0), resulting in the subexpression number N will be inserted in the result. If no subexpression with that number is generated by the regular expression, nothing is inserted.</p> - <p>To insert an <c>&</c> or <c>\\</c> in the result, precede it - with a <c>\\</c>. Note that Erlang already gives a special - meaning to <c>\\</c> in literal strings, why a single <c>\\</c> - has to be written as <c>"\\\\"</c> and therefore a double <c>\\</c> - as <c>"\\\\\\\\"</c>. Example:</p> + <p>To insert an <c>&</c> or <c>\</c> in the result, precede it + with a <c>\</c>. Note that Erlang already gives a special + meaning to <c>\</c> in literal strings, why a single <c>\</c> + has to be written as <c>"\\"</c> and therefore a double <c>\</c> + as <c>"\\\\"</c>. Example:</p> <code> re:replace("abcd","c","[&]",[{return,list}]).</code> <p>gives</p> <code> "ab[c]d"</code> <p>while</p> - <code> re:replace("abcd","c","[\\\&]",[{return,list}]).</code> + <code> re:replace("abcd","c","[\\&]",[{return,list}]).</code> <p>gives</p> <code> "ab[&]d"</code> <p>As with <c>re:run/3</c>, compilation errors raise the <c>badarg</c> @@ -852,19 +852,19 @@ example, the pattern:</p> <p> (*CR)a.b</p> </quote> -<p>changes the convention to CR. That pattern matches "a\\nb" because LF is no +<p>changes the convention to CR. That pattern matches "a\nb" because LF is no longer a newline. Note that these special settings, which are not Perl-compatible, are recognized only at the very start of a pattern, and that they must be in upper case. If more than one of them is present, the last one is used.</p> -<p>The newline convention does not affect what the \\R escape sequence matches. By +<p>The newline convention does not affect what the \R escape sequence matches. By default, this is any Unicode newline sequence, for Perl compatibility. However, -this can be changed; see the description of \\R in the section entitled +this can be changed; see the description of \R in the section entitled "Newline sequences" -below. A change of \\R setting can be combined with a change of newline +below. A change of \R setting can be combined with a change of newline convention.</p> </section> @@ -897,7 +897,7 @@ recognized within square brackets. Outside square brackets, the metacharacters are as follows:</p> <taglist> - <tag>\\</tag> <item>general escape character with several uses</item> + <tag>\</tag> <item>general escape character with several uses</item> <tag>^</tag> <item>assert start of string (or line, in multiline mode)</item> <tag>$</tag> <item>assert end of string (or line, in multiline mode)</item> <tag>.</tag> <item>match any character except newline (by default)</item> @@ -918,7 +918,7 @@ are as follows:</p> a character class the only metacharacters are:</p> <taglist> - <tag>\\</tag> <item>general escape character</item> + <tag>\</tag> <item>general escape character</item> <tag>^</tag> <item>negate the class, but only if the first character</item> <tag>-</tag> <item>indicates character range</item> <tag>[</tag> <item>POSIX character class (only if followed by POSIX @@ -939,11 +939,11 @@ non-alphanumeric character, it takes away any special meaning that character may have. This use of backslash as an escape character applies both inside and outside character classes.</p> -<p>For example, if you want to match a * character, you write \\* in the pattern. +<p>For example, if you want to match a * character, you write \* in the pattern. This escaping action applies whether or not the following character would otherwise be interpreted as a metacharacter, so it is always safe to precede a non-alphanumeric with backslash to specify that it stands for itself. In -particular, if you want to match a backslash, you write \\\\.</p> +particular, if you want to match a backslash, you write \\.</p> <p>If a pattern is compiled with the <c>extended</c> option, whitespace in the pattern (other than in a character class) and characters between a # outside @@ -951,18 +951,18 @@ a character class and the next newline are ignored. An escaping backslash can be used to include a whitespace or # character as part of the pattern.</p> <p>If you want to remove the special meaning from a sequence of characters, you -can do so by putting them between \\Q and \\E. This is different from Perl in -that $ and @ are handled as literals in \\Q...\\E sequences in PCRE, whereas in +can do so by putting them between \Q and \E. This is different from Perl in +that $ and @ are handled as literals in \Q...\E sequences in PCRE, whereas in Perl, $ and @ cause variable interpolation. Note the following examples:</p> <code type="none"> Pattern PCRE matches Perl matches - \\Qabc$xyz\\E abc$xyz abc followed by the contents of $xyz - \\Qabc\\$xyz\\E abc\\$xyz abc\\$xyz - \\Qabc\\E\\$\\Qxyz\\E abc$xyz abc$xyz</code> + \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz + \Qabc\$xyz\E abc\$xyz abc\$xyz + \Qabc\E\$\Qxyz\E abc$xyz abc$xyz</code> -<p>The \\Q...\\E sequence is recognized both inside and outside character classes.</p> +<p>The \Q...\E sequence is recognized both inside and outside character classes.</p> <p><em>Non-printing characters</em></p> @@ -975,41 +975,41 @@ use one of the following escape sequences than the binary character it represents:</p> <taglist> - <tag>\\a</tag> <item>alarm, that is, the BEL character (hex 07)</item> - <tag>\\cx</tag> <item>"control-x", where x is any character</item> - <tag>\\e </tag> <item>escape (hex 1B)</item> - <tag>\\f</tag> <item>formfeed (hex 0C)</item> - <tag>\\n</tag> <item>linefeed (hex 0A)</item> - <tag>\\r</tag> <item>carriage return (hex 0D)</item> - <tag>\\t </tag> <item>tab (hex 09)</item> - <tag>\\ddd</tag> <item>character with octal code ddd, or backreference</item> - <tag>\\xhh </tag> <item>character with hex code hh</item> - <tag>\\x{hhh..}</tag> <item>character with hex code hhh..</item> + <tag>\a</tag> <item>alarm, that is, the BEL character (hex 07)</item> + <tag>\cx</tag> <item>"control-x", where x is any character</item> + <tag>\e </tag> <item>escape (hex 1B)</item> + <tag>\f</tag> <item>formfeed (hex 0C)</item> + <tag>\n</tag> <item>linefeed (hex 0A)</item> + <tag>\r</tag> <item>carriage return (hex 0D)</item> + <tag>\t </tag> <item>tab (hex 09)</item> + <tag>\ddd</tag> <item>character with octal code ddd, or backreference</item> + <tag>\xhh </tag> <item>character with hex code hh</item> + <tag>\x{hhh..}</tag> <item>character with hex code hhh..</item> </taglist> -<p>The precise effect of \\cx is as follows: if x is a lower case letter, it +<p>The precise effect of \cx is as follows: if x is a lower case letter, it is converted to upper case. Then bit 6 of the character (hex 40) is inverted. -Thus \\cz becomes hex 1A, but \\c{ becomes hex 3B, while \\c; becomes hex +Thus \cz becomes hex 1A, but \c{ becomes hex 3B, while \c; becomes hex 7B.</p> -<p>After \\x, from zero to two hexadecimal digits are read (letters can be in -upper or lower case). Any number of hexadecimal digits may appear between \\x{ +<p>After \x, from zero to two hexadecimal digits are read (letters can be in +upper or lower case). Any number of hexadecimal digits may appear between \x{ and }, but the value of the character code must be less than 256 in non-UTF-8 mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code point, which is 10FFFF.</p> -<p>If characters other than hexadecimal digits appear between \\x{ and }, or if +<p>If characters other than hexadecimal digits appear between \x{ and }, or if there is no terminating }, this form of escape is not recognized. Instead, the -initial \\x will be interpreted as a basic hexadecimal escape, with no +initial \x will be interpreted as a basic hexadecimal escape, with no following digits, giving a character whose value is zero.</p> <p>Characters whose value is less than 256 can be defined by either of the two -syntaxes for \\x. There is no difference in the way they are handled. For -example, \\xdc is exactly the same as \\x{dc}.</p> +syntaxes for \x. There is no difference in the way they are handled. For +example, \xdc is exactly the same as \x{dc}.</p> -<p>After \\0 up to two further octal digits are read. If there are fewer than two -digits, just those that are present are used. Thus the sequence \\0\\x\\07 +<p>After \0 up to two further octal digits are read. If there are fewer than two +digits, just those that are present are used. Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL character (code value 7). Make sure you supply two digits after the initial zero if the pattern character that follows is itself an octal digit.</p> @@ -1027,32 +1027,32 @@ have not been that many capturing subpatterns, PCRE re-reads up to three octal digits following the backslash, and uses them to generate a data character. Any subsequent digits stand for themselves. The value of a -character specified in octal must be less than \\400. +character specified in octal must be less than \400. In non-UTF-8 mode, the value of a -character specified in octal must be less than \\400. In UTF-8 mode, values up -to \\777 are permitted. +character specified in octal must be less than \400. In UTF-8 mode, values up +to \777 are permitted. For example:</p> <taglist> - <tag>\\040</tag> <item>is another way of writing a space</item> + <tag>\040</tag> <item>is another way of writing a space</item> - <tag>\\40</tag> <item>is the same, provided there are fewer than 40 + <tag>\40</tag> <item>is the same, provided there are fewer than 40 previous capturing subpatterns</item> - <tag>\\7</tag> <item>is always a back reference</item> + <tag>\7</tag> <item>is always a back reference</item> - <tag>\\11</tag> <item> might be a back reference, or another way of + <tag>\11</tag> <item> might be a back reference, or another way of writing a tab</item> - <tag>\\011</tag> <item>is always a tab</item> - <tag>\\0113</tag> <item>is a tab followed by the character "3"</item> + <tag>\011</tag> <item>is always a tab</item> + <tag>\0113</tag> <item>is a tab followed by the character "3"</item> - <tag>\\113</tag> <item>might be a back reference, otherwise the + <tag>\113</tag> <item>might be a back reference, otherwise the character with octal code 113</item> - <tag>\\377</tag> <item>might be a back reference, otherwise + <tag>\377</tag> <item>might be a back reference, otherwise the byte consisting entirely of 1 bits</item> - <tag>\\81</tag> <item>is either a back reference, or a binary zero + <tag>\81</tag> <item>is either a back reference, or a binary zero followed by the two characters "8" and "1"</item> </taglist> @@ -1062,16 +1062,16 @@ read.</p> <p>All the sequences that define a single character value can be used both inside and outside character classes. In addition, inside a -character class, the sequence \\b is interpreted as the backspace -character (hex 08), and the sequences \\R and \\X are interpreted as +character class, the sequence \b is interpreted as the backspace +character (hex 08), and the sequences \R and \X are interpreted as the characters "R" and "X", respectively. Outside a character class, these sequences have different meanings (see below).</p> <p><em>Absolute and relative back references</em></p> -<p>The sequence \\g followed by an unsigned or a negative number, +<p>The sequence \g followed by an unsigned or a negative number, optionally enclosed in braces, is an absolute or relative back -reference. A named back reference can be coded as \\g{name}. Back +reference. A named back reference can be coded as \g{name}. Back references are discussed later, following the discussion of parenthesized subpatterns.</p> @@ -1081,16 +1081,16 @@ parenthesized subpatterns.</p> following are always recognized:</p> <taglist> - <tag>\\d</tag> <item>any decimal digit</item> - <tag>\\D</tag> <item>any character that is not a decimal digit</item> - <tag>\\h</tag> <item>any horizontal whitespace character</item> - <tag>\\H</tag> <item>any character that is not a horizontal whitespace character</item> - <tag>\\s</tag> <item>any whitespace character</item> - <tag>\\S</tag> <item>any character that is not a whitespace character</item> - <tag>\\v</tag> <item>any vertical whitespace character</item> - <tag>\\V</tag> <item>any character that is not a vertical whitespace character</item> - <tag>\\w</tag> <item>any "word" character</item> - <tag>\\W</tag> <item>any "non-word" character</item> + <tag>\d</tag> <item>any decimal digit</item> + <tag>\D</tag> <item>any character that is not a decimal digit</item> + <tag>\h</tag> <item>any horizontal whitespace character</item> + <tag>\H</tag> <item>any character that is not a horizontal whitespace character</item> + <tag>\s</tag> <item>any whitespace character</item> + <tag>\S</tag> <item>any character that is not a whitespace character</item> + <tag>\v</tag> <item>any vertical whitespace character</item> + <tag>\V</tag> <item>any character that is not a vertical whitespace character</item> + <tag>\w</tag> <item>any "word" character</item> + <tag>\W</tag> <item>any "non-word" character</item> </taglist> <p>Each pair of escape sequences partitions the complete set of characters into @@ -1101,19 +1101,19 @@ classes. They each match one character of the appropriate type. If the current matching point is at the end of the subject string, all of them fail, since there is no character to match.</p> -<p>For compatibility with Perl, \\s does not match the VT character (code 11). -This makes it different from the POSIX "space" class. The \\s characters +<p>For compatibility with Perl, \s does not match the VT character (code 11). +This makes it different from the POSIX "space" class. The \s characters are HT (9), LF (10), FF (12), CR (13), and space (32). If "use locale;" is -included in a Perl script, \\s may match the VT character. In PCRE, it never +included in a Perl script, \s may match the VT character. In PCRE, it never does.</p> -<p>In UTF-8 mode, characters with values greater than 128 never match \\d, \\s, or -\\w, and always match \\D, \\S, and \\W. This is true even when Unicode +<p>In UTF-8 mode, characters with values greater than 128 never match \d, \s, or +\w, and always match \D, \S, and \W. This is true even when Unicode character property support is available. These sequences retain their original meanings from before UTF-8 support was available, mainly for efficiency reasons.</p> -<p>The sequences \\h, \\H, \\v, and \\V are Perl 5.10 features. In contrast to the +<p>The sequences \h, \H, \v, and \V are Perl 5.10 features. In contrast to the other sequences, these do match certain high-valued codepoints in UTF-8 mode. The horizontal space characters are:</p> @@ -1157,11 +1157,11 @@ low-valued character tables, which are always ISO-8859-1.</p> <p><em>Newline sequences</em></p> -<p>Outside a character class, by default, the escape sequence \\R matches any -Unicode newline sequence. This is a Perl 5.10 feature. In non-UTF-8 mode \\R is +<p>Outside a character class, by default, the escape sequence \R matches any +Unicode newline sequence. This is a Perl 5.10 feature. In non-UTF-8 mode \R is equivalent to the following:</p> -<quote><p> (?>\\r\\n|\\n|\\x0b|\\f|\\r|\\x85)</p></quote> +<quote><p> (?>\r\n|\n|\x0b|\f|\r|\x85)</p></quote> <p>This is an example of an "atomic group", details of which are given below.</p> @@ -1177,7 +1177,7 @@ Unicode character property support is not needed for these characters to be recognized.</p> -<p>It is possible to restrict \\R to match only CR, LF, or CRLF (instead of the +<p>It is possible to restrict \R to match only CR, LF, or CRLF (instead of the complete set of Unicode line endings) by setting the option <c>bsr_anycrlf</c> either at compile time or when the pattern is matched. (BSR is an abbreviation for "backslash R".) This can be made the default when PCRE is built; if this is @@ -1197,7 +1197,7 @@ newline convention, for example, a pattern can start with:</p> <p> (*ANY)(*BSR_ANYCRLF)</p> -<p>Inside a character class, \\R matches the letter "R".</p> +<p>Inside a character class, \R matches the letter "R".</p> <p><em>Unicode character properties</em></p> @@ -1208,22 +1208,22 @@ When not in UTF-8 mode, these sequences are of course limited to testing characters whose codepoints are less than 256, but they do work in this mode. The extra escape sequences are:</p> -<p> \\p{<em>xx</em>} a character with the <em>xx</em> property - \\P{<em>xx</em>} a character without the <em>xx</em> property - \\X an extended Unicode sequence</p> +<p> \p{<em>xx</em>} a character with the <em>xx</em> property + \P{<em>xx</em>} a character without the <em>xx</em> property + \X an extended Unicode sequence</p> <p>The property names represented by <em>xx</em> above are limited to the Unicode script names, the general category properties, and "Any", which matches any character (including newline). Other properties such as "InMusicalSymbols" are -not currently supported by PCRE. Note that \\P{Any} does not match any +not currently supported by PCRE. Note that \P{Any} does not match any characters, so always causes a match failure.</p> <p>Sets of Unicode characters are defined as belonging to certain scripts. A character from one of these sets can be matched using a script name. For example:</p> -<p> \\p{Greek} - \\P{Han}</p> +<p> \p{Greek} + \P{Han}</p> <p>Those that are not part of an identified script are lumped together as "Common". The current list of scripts is:</p> @@ -1300,15 +1300,15 @@ example:</p> <p>Each character has exactly one general category property, specified by a two-letter abbreviation. For compatibility with Perl, negation can be specified by including a circumflex between the opening brace and the property name. For -example, \\p{^Lu} is the same as \\P{Lu}.</p> +example, \p{^Lu} is the same as \P{Lu}.</p> -<p>If only one letter is specified with \\p or \\P, it includes all the general +<p>If only one letter is specified with \p or \P, it includes all the general category properties that start with that letter. In this case, in the absence of negation, the curly brackets in the escape sequence are optional; these two examples have the same effect:</p> -<list><item>\\p{L}</item> - <item>\\pL</item></list> +<list><item>\p{L}</item> + <item>\pL</item></list> <p>The following general category property codes are supported:</p> @@ -1382,7 +1382,7 @@ cannot be tested by PCRE, unless UTF-8 validity checking has been turned off <em>pcreapi</em> page).</p> -<p>The long synonyms for these properties that Perl supports (such as \\p{Letter}) +<p>The long synonyms for these properties that Perl supports (such as \p{Letter}) are not supported by PCRE, nor is it permitted to prefix any of these properties with "Is".</p> @@ -1391,12 +1391,12 @@ Instead, this property is assumed for any code point that is not in the Unicode table.</p> <p>Specifying caseless matching does not affect these escape sequences. For -example, \\p{Lu} always matches only upper case letters.</p> +example, \p{Lu} always matches only upper case letters.</p> -<p>The \\X escape matches any number of Unicode characters that form an extended -Unicode sequence. \\X is equivalent to</p> +<p>The \X escape matches any number of Unicode characters that form an extended +Unicode sequence. \X is equivalent to</p> -<quote><p> (?>\\PM\\pM*)</p></quote> +<quote><p> (?>\PM\pM*)</p></quote> <p>That is, it matches a character without the "mark" property, followed by zero or more characters with the "mark" property, and treats the sequence as an @@ -1404,20 +1404,20 @@ atomic group (see below). Characters with the "mark" property are typically accents that affect the preceding character. None of them have codepoints less than 256, so in -non-UTF-8 mode \\X matches any one character.</p> +non-UTF-8 mode \X matches any one character.</p> <p>Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is -why the traditional escape sequences such as \\d and \\w do not use Unicode +why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE.</p> <p><em>Resetting the match start</em></p> -<p>The escape sequence \\K, which is a Perl 5.10 feature, causes any previously +<p>The escape sequence \K, which is a Perl 5.10 feature, causes any previously matched characters not to be included in the final matched sequence. For example, the pattern:</p> -<quote><p> foo\\Kbar</p></quote> +<quote><p> foo\Kbar</p></quote> <p>matches "foobar", but reports that it has matched "bar". This feature is similar to a lookbehind assertion @@ -1426,12 +1426,12 @@ similar to a lookbehind assertion (described below). However, in this case, the part of the subject before the real match does not -have to be of fixed length, as lookbehind assertions do. The use of \\K does +have to be of fixed length, as lookbehind assertions do. The use of \K does not interfere with the setting of captured substrings. For example, when the pattern</p> -<quote><p> (foo)\\Kbar</p></quote> +<quote><p> (foo)\Kbar</p></quote> <p>matches "foobar", the first substring is still set to "foo".</p> @@ -1444,50 +1444,50 @@ string. The use of subpatterns for more complicated assertions is described below. The backslashed assertions are:</p> <taglist> - <tag>\\b</tag> <item>matches at a word boundary</item> - <tag>\\B</tag> <item>matches when not at a word boundary</item> - <tag>\\A</tag> <item>matches at the start of the subject</item> - <tag>\\Z</tag> <item>matches at the end of the subject + <tag>\b</tag> <item>matches at a word boundary</item> + <tag>\B</tag> <item>matches when not at a word boundary</item> + <tag>\A</tag> <item>matches at the start of the subject</item> + <tag>\Z</tag> <item>matches at the end of the subject also matches before a newline at the end of the subject</item> - <tag>\\z</tag> <item>matches only at the end of the subject</item> - <tag>\\G</tag> <item>matches at the first matching position in the + <tag>\z</tag> <item>matches only at the end of the subject</item> + <tag>\G</tag> <item>matches at the first matching position in the subject</item> </taglist> -<p>These assertions may not appear in character classes (but note that \\b has a +<p>These assertions may not appear in character classes (but note that \b has a different meaning, namely the backspace character, inside a character class).</p> <p>A word boundary is a position in the subject string where the current character -and the previous character do not both match \\w or \\W (i.e. one matches -\\w and the other matches \\W), or the start or end of the string if the -first or last character matches \\w, respectively.</p> +and the previous character do not both match \w or \W (i.e. one matches +\w and the other matches \W), or the start or end of the string if the +first or last character matches \w, respectively.</p> -<p>The \\A, \\Z, and \\z assertions differ from the traditional circumflex and +<p>The \A, \Z, and \z assertions differ from the traditional circumflex and dollar (described in the next section) in that they only ever match at the very start and end of the subject string, whatever options are set. Thus, they are independent of multiline mode. These three assertions are not affected by the <c>notbol</c> or <c>noteol</c> options, which affect only the behaviour of the circumflex and dollar metacharacters. However, if the <em>startoffset</em> argument of <c>re:run/3</c> is non-zero, indicating that matching is to start -at a point other than the beginning of the subject, \\A can never match. The -difference between \\Z and \\z is that \\Z matches before a newline at the end -of the string as well as at the very end, whereas \\z matches only at the end.</p> +at a point other than the beginning of the subject, \A can never match. The +difference between \Z and \z is that \Z matches before a newline at the end +of the string as well as at the very end, whereas \z matches only at the end.</p> -<p>The \\G assertion is true only when the current matching position is at the +<p>The \G assertion is true only when the current matching position is at the start point of the match, as specified by the <em>startoffset</em> argument of -<c>re:run/3</c>. It differs from \\A when the value of <em>startoffset</em> is +<c>re:run/3</c>. It differs from \A when the value of <em>startoffset</em> is non-zero. By calling <c>re:run/3</c> multiple times with appropriate arguments, you can mimic Perl's /g option, and it is in this kind of -implementation where \\G can be useful.</p> +implementation where \G can be useful.</p> -<p>Note, however, that PCRE's interpretation of \\G, as the start of the current +<p>Note, however, that PCRE's interpretation of \G, as the start of the current match, is subtly different from Perl's, which defines it as the end of the previous match. In Perl, these can be different when the previously matched string was empty. Because PCRE does just one match at a time, it cannot reproduce this behaviour.</p> -<p>If all the alternatives of a pattern begin with \\G, the expression is anchored +<p>If all the alternatives of a pattern begin with \G, the expression is anchored to the starting match position, and the "anchored" flag is set in the compiled regular expression.</p> @@ -1519,7 +1519,7 @@ character class.</p> <p>The meaning of dollar can be changed so that it matches only at the very end of the string, by setting the <c>dollar_endonly</c> option at -compile time. This does not affect the \\Z assertion.</p> +compile time. This does not affect the \Z assertion.</p> <p>The meanings of the circumflex and dollar characters are changed if the <c>multiline</c> option is set. When this is the case, a circumflex matches @@ -1530,16 +1530,16 @@ matches before any newlines in the string, as well as at the very end, when sequence CRLF, isolated CR and LF characters do not indicate newlines.</p> <p>For example, the pattern /^abc$/ matches the subject string -"def\\nabc" (where \\n represents a newline) in multiline mode, but +"def\nabc" (where \n represents a newline) in multiline mode, but not otherwise. Consequently, patterns that are anchored in single line mode because all branches start with ^ are not anchored in multiline mode, and a match for circumflex is possible when the <em>startoffset</em> argument of <c>re:run/3</c> is non-zero. The <c>dollar_endonly</c> option is ignored if <c>multiline</c> is set.</p> -<p>Note that the sequences \\A, \\Z, and \\z can be used to match the start and +<p>Note that the sequences \A, \Z, and \z can be used to match the start and end of the subject in both modes, and if all branches of a pattern start with -\\A it is always anchored, whether or not <c>multiline</c> is set.</p> +\A it is always anchored, whether or not <c>multiline</c> is set.</p> </section> @@ -1574,14 +1574,14 @@ involve newlines. Dot has no special meaning in a character class.</p> <section><marker id="sect6"></marker><title>Matching a single byte</title> -<p>Outside a character class, the escape sequence \\C matches any one byte, both +<p>Outside a character class, the escape sequence \C matches any one byte, both in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending characters. The feature is provided in Perl in order to match individual bytes in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes, what remains in the string may be a malformed UTF-8 string. For this reason, -the \\C escape sequence is best avoided.</p> +the \C escape sequence is best avoided.</p> -<p>PCRE does not allow \\C to appear in lookbehind assertions (described below), +<p>PCRE does not allow \C to appear in lookbehind assertions (described below), because in UTF-8 mode this would make it impossible to calculate the length of the lookbehind.</p> @@ -1615,7 +1615,7 @@ string, and therefore it fails if the current pointer is at the end of the string.</p> <p>In UTF-8 mode, characters with values greater than 255 can be included in a -class as a literal string of bytes, or by using the \\x{ escaping mechanism.</p> +class as a literal string of bytes, or by using the \x{ escaping mechanism.</p> <p>When caseless matching is set, any letters in a class represent both their upper case and lower case versions, so for example, a caseless [aeiou] matches @@ -1648,32 +1648,32 @@ character of a range. A pattern such as [W-]46] is interpreted as a class of two characters ("W" and "-") followed by a literal string "46]", so it would match "W46]" or "-46]". However, if the "]" is escaped with a backslash it is interpreted as the end of range, so -[W-\\]46] is interpreted as a class containing a range followed by two +[W-\]46] is interpreted as a class containing a range followed by two other characters. The octal or hexadecimal representation of "]" can also be used to end a range.</p> <p>Ranges operate in the collating sequence of character values. They can also be -used for characters specified numerically, for example [\\000-\\037]. +used for characters specified numerically, for example [\000-\037]. In UTF-8 mode, ranges can include characters whose values are greater than 255, for -example [\\x{100}-\\x{2ff}]. +example [\x{100}-\x{2ff}]. </p> <p>If a range that includes letters is used when caseless matching is set, it matches the letters in either case. For example, [W-c] is equivalent to -[][\\\\^_`wxyzabc], matched caselessly +[][\\^_`wxyzabc], matched caselessly , and in non-UTF-8 mode, if character -tables for a French locale are in use, [\\xc8-\\xcb] matches accented E +tables for a French locale are in use, [\xc8-\xcb] matches accented E characters in both cases. In UTF-8 mode, PCRE supports the concept of case for characters with values greater than 128 only when it is compiled with Unicode property support.</p> -<p>The character types \\d, \\D, \\p, \\P, \\s, \\S, \\w, and \\W may +<p>The character types \d, \D, \p, \P, \s, \S, \w, and \W may also appear in a character class, and add the characters that they -match to the class. For example, [\\dABCDEF] matches any hexadecimal +match to the class. For example, [\dABCDEF] matches any hexadecimal digit. A circumflex can conveniently be used with the upper case character types to specify a more restricted set of characters than -the matching lower case type. For example, the class [^\\W_] matches +the matching lower case type. For example, the class [^\W_] matches any letter or digit, but not underscore.</p> <p>The only metacharacters that are recognized in character classes @@ -1702,20 +1702,20 @@ are</p> <tag>ascii</tag> <item>character codes 0 - 127</item> <tag>blank</tag> <item>space or tab only</item> <tag>cntrl</tag> <item>control characters</item> - <tag>digit</tag> <item>decimal digits (same as \\d)</item> + <tag>digit</tag> <item>decimal digits (same as \d)</item> <tag>graph</tag> <item>printing characters, excluding space</item> <tag>lower</tag> <item>lower case letters</item> <tag>print</tag> <item>printing characters, including space</item> <tag>punct</tag> <item>printing characters, excluding letters and digits</item> - <tag>space</tag> <item>whitespace (not quite the same as \\s)</item> + <tag>space</tag> <item>whitespace (not quite the same as \s)</item> <tag>upper</tag> <item>upper case letters</item> - <tag>word</tag> <item>"word" characters (same as \\w)</item> + <tag>word</tag> <item>"word" characters (same as \w)</item> <tag>xdigit</tag> <item>hexadecimal digits</item> </taglist> <p>The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13), and space (32). Notice that this list includes the VT character (code 11). This -makes "space" different to \\s, which does not include VT (for Perl +makes "space" different to \s, which does not include VT (for Perl compatibility).</p> <p>The name "word" is a Perl extension, and "blank" is a GNU extension @@ -1936,7 +1936,7 @@ match. Suppose you want to match the name of a weekday, either as a 3-letter abbreviation or as the full name, and in both cases you want to extract the abbreviation. This pattern (ignoring the line breaks) does the job:</p> -<code type="none"> +<code type="none"> (?<DN>Mon|Fri|Sun)(?:day)?| (?<DN>Tue)(?:sday)?| (?<DN>Wed)(?:nesday)?| @@ -1972,12 +1972,12 @@ following items:</p> <list> <item>a literal data character</item> <item>the dot metacharacter</item> - <item>the \\C escape sequence</item> - <item>the \\X escape sequence + <item>the \C escape sequence</item> + <item>the \X escape sequence (in UTF-8 mode with Unicode properties) </item> - <item>the \\R escape sequence</item> - <item>an escape such as \\d that matches a single character</item> + <item>the \R escape sequence</item> + <item>an escape such as \d that matches a single character</item> <item>a character class</item> <item>a back reference (see next section)</item> <item>a parenthesized subpattern (unless it is an assertion)</item> @@ -1999,7 +1999,7 @@ quantifier specifies an exact number of required matches. Thus</p> <p>matches at least 3 successive vowels, but may match many more, while</p> -<quote><p> \\d{8}</p></quote> +<quote><p> \d{8}</p></quote> <p>matches exactly 8 digits. An opening curly bracket that appears in a position where a quantifier is not allowed, or one that does not match the syntax of a @@ -2007,9 +2007,9 @@ quantifier, is taken as a literal character. For example, {,6} is not a quantifier, but a literal string of four characters.</p> <p>In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual -bytes. Thus, for example, \\x{100}{2} matches two UTF-8 characters, each of +bytes. Thus, for example, \x{100}{2} matches two UTF-8 characters, each of which is represented by a two-byte sequence. Similarly, when Unicode property -support is available, \\X{3} matches three Unicode extended sequences, each of +support is available, \X{3} matches three Unicode extended sequences, each of which may be several bytes long (and they may be of different lengths).</p> <p>The quantifier {0} is permitted, causing the expression to behave as if the @@ -2042,7 +2042,7 @@ is in trying to match comments in C programs. These appear between /* and */ and within the comment, individual * and / characters may appear. An attempt to match C comments by applying the pattern</p> -<quote><p> /\\*.*\\*/</p></quote> +<quote><p> /\*.*\*/</p></quote> <p>to the string</p> @@ -2055,14 +2055,14 @@ item.</p> greedy, and instead matches the minimum number of times possible, so the pattern</p> -<quote><p> /\\*.*?\\*/</p></quote> +<quote><p> /\*.*?\*/</p></quote> <p>does the right thing with the C comments. The meaning of the various quantifiers is not otherwise changed, just the preferred number of matches. Do not confuse this use of question mark with its use as a quantifier in its own right. Because it has two uses, it can sometimes appear doubled, as in</p> -<quote><p> \\d??\\d</p></quote> +<quote><p> \d??\d</p></quote> <p>which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches.</p> @@ -2081,7 +2081,7 @@ to Perl's /s) is set, thus allowing the dot to match newlines, the pattern is implicitly anchored, because whatever follows will be tried against every character position in the subject string, so there is no point in retrying the overall match at any position after the first. PCRE normally treats such a -pattern as though it were preceded by \\A.</p> +pattern as though it were preceded by \A.</p> <p>In cases where it is known that the subject string contains no newlines, it is worth setting <c>dotall</c> in order to obtain this optimization, or @@ -2092,7 +2092,7 @@ is inside capturing parentheses that are the subject of a backreference elsewhere in the pattern, a match at the start may fail where a later one succeeds. Consider, for example:</p> -<quote><p> (.*)abc\\1</p></quote> +<quote><p> (.*)abc\1</p></quote> <p>If the subject is "xyz123abc123" the match point is the fourth character. For this reason, such a pattern is not implicitly anchored.</p> @@ -2100,7 +2100,7 @@ this reason, such a pattern is not implicitly anchored.</p> <p>When a capturing subpattern is repeated, the value captured is the substring that matched the final iteration. For example, after</p> -<quote><p> (tweedle[dume]{3}\\s*)+</p></quote> +<quote><p> (tweedle[dume]{3}\s*)+</p></quote> <p>has matched "tweedledum tweedledee" the value of the captured substring is "tweedledee". However, if there are nested capturing subpatterns, the @@ -2123,12 +2123,12 @@ pattern to match. Sometimes it is useful to prevent this, either to change the nature of the match, or to cause it fail earlier than it otherwise might, when the author of the pattern knows there is no point in carrying on.</p> -<p>Consider, for example, the pattern \\d+foo when applied to the subject line</p> +<p>Consider, for example, the pattern \d+foo when applied to the subject line</p> <quote><p> 123456bar</p></quote> <p>After matching all 6 digits and then failing to match "foo", the normal -action of the matcher is to try again with only 5 digits matching the \\d+ +action of the matcher is to try again with only 5 digits matching the \d+ item, and then with 4, and so on, before ultimately failing. "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides the means for specifying that once a subpattern has matched, it is not to be re-evaluated in this way.</p> @@ -2137,7 +2137,7 @@ that once a subpattern has matched, it is not to be re-evaluated in this way.</p immediately on failing to match "foo" the first time. The notation is a kind of special parenthesis, starting with (?> as in this example:</p> -<quote><p> (?>\\d+)foo</p></quote> +<quote><p> (?>\d+)foo</p></quote> <p>This kind of parenthesis "locks up" the part of the pattern it contains once it has matched, and a failure further into the pattern is prevented from @@ -2150,9 +2150,9 @@ the current point in the subject string.</p> <p>Atomic grouping subpatterns are not capturing subpatterns. Simple cases such as the above example can be thought of as a maximizing repeat that must swallow -everything it can. So, while both \\d+ and \\d+? are prepared to adjust the +everything it can. So, while both \d+ and \d+? are prepared to adjust the number of digits they match in order to make the rest of the pattern match, -(?>\\d+) can only match an entire sequence of digits.</p> +(?>\d+) can only match an entire sequence of digits.</p> <p>Atomic groups in general can of course contain arbitrarily complicated subpatterns, and can be nested. However, when the subpattern for an atomic @@ -2161,7 +2161,7 @@ notation, called a "possessive quantifier" can be used. This consists of an additional + character following a quantifier. Using this notation, the previous example can be rewritten as</p> -<quote><p> \\d++foo</p></quote> +<quote><p> \d++foo</p></quote> <p>Note that a possessive quantifier can be used with an entire group, for example:</p> @@ -2189,7 +2189,7 @@ be repeated an unlimited number of times, the use of an atomic group is the only way to avoid some failing matches taking a very long time indeed. The pattern</p> -<quote><p> (\\D+|<\\d+>)*[!?]</p></quote> +<quote><p> (\D+|<\d+>)*[!?]</p></quote> <p>matches an unlimited number of substrings that either consist of non-digits, or digits enclosed in <>, followed by either ! or ?. When it matches, it runs @@ -2198,7 +2198,7 @@ quickly. However, if it is applied to</p> <quote><p> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</p></quote> <p>it takes a long time before reporting failure. This is because the string can -be divided between the internal \\D+ repeat and the external * repeat in a +be divided between the internal \D+ repeat and the external * repeat in a large number of ways, and all have to be tried. (The example uses [!?] rather than a single character at the end, because both PCRE and Perl have an optimization that allows for fast failure when a single character is used. They @@ -2206,7 +2206,7 @@ remember the last single character that is required for a match, and fail early if it is not present in the string.) If the pattern is changed so that it uses an atomic group, like this:</p> -<quote><p> ((?>\\D+)|<\\d+>)*[!?]</p></quote> +<quote><p> ((?>\D+)|<\d+>)*[!?]</p></quote> <p>sequences of non-digits cannot be broken, and failure happens quickly.</p> @@ -2229,22 +2229,22 @@ in an earlier iteration.</p> <p>It is not possible to have a numerical "forward back reference" to a subpattern whose number is 10 or more using this syntax because a -sequence such as \\50 is interpreted as a character defined in +sequence such as \50 is interpreted as a character defined in octal. See the subsection entitled "Non-printing characters" above for further details of the handling of digits following a backslash. There is no such problem when named parentheses are used. A back reference to any subpattern is possible using named parentheses (see below).</p> <p>Another way of avoiding the ambiguity inherent in the use of digits -following a backslash is to use the \\g escape sequence, which is a +following a backslash is to use the \g escape sequence, which is a feature introduced in Perl 5.10. This escape must be followed by an unsigned number or a negative number, optionally enclosed in braces. These examples are all identical:</p> <list> - <item>(ring), \\1</item> - <item>(ring), \\g1</item> - <item>(ring), \\g{1}</item> + <item>(ring), \1</item> + <item>(ring), \g1</item> + <item>(ring), \g{1}</item> </list> <p>An unsigned number specifies an absolute reference without the @@ -2252,11 +2252,11 @@ ambiguity that is present in the older syntax. It is also useful when literal digits follow the reference. A negative number is a relative reference. Consider this example:</p> -<quote><p> (abc(def)ghi)\\g{-1}</p></quote> +<quote><p> (abc(def)ghi)\g{-1}</p></quote> -<p>The sequence \\g{-1} is a reference to the most recently started capturing -subpattern before \\g, that is, is it equivalent to \\2. Similarly, \\g{-2} -would be equivalent to \\1. The use of relative references can be helpful in +<p>The sequence \g{-1} is a reference to the most recently started capturing +subpattern before \g, that is, is it equivalent to \2. Similarly, \g{-2} +would be equivalent to \1. The use of relative references can be helpful in long patterns, and also in patterns that are created by joining together fragments that contain references within themselves.</p> @@ -2265,29 +2265,29 @@ subpattern in the current subject string, rather than anything matching the subpattern itself (see "Subpatterns as subroutines" below for a way of doing that). So the pattern</p> -<quote><p> (sens|respons)e and \\1ibility</p></quote> +<quote><p> (sens|respons)e and \1ibility</p></quote> <p>matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If caseful matching is in force at the time of the back reference, the case of letters is relevant. For example,</p> -<quote><p> ((?i)rah)\\s+\\1</p></quote> +<quote><p> ((?i)rah)\s+\1</p></quote> <p>matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original capturing subpattern is matched caselessly.</p> <p>There are several different ways of writing back references to named -subpatterns. The .NET syntax \\k{name} and the Perl syntax \\k<name> or -\\k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified -back reference syntax, in which \\g can be used for both numeric and named +subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or +\k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's unified +back reference syntax, in which \g can be used for both numeric and named references, is also supported. We could rewrite the above example in any of the following ways:</p> <list> - <item>(?<p1>(?i)rah)\\s+\\k<p1></item> - <item>(?'p1'(?i)rah)\\s+\\k{p1}</item> - <item>(?P<p1>(?i)rah)\\s+(?P=p1)</item> - <item>(?<p1>(?i)rah)\\s+\\g{p1}</item> + <item>(?<p1>(?i)rah)\s+\k<p1></item> + <item>(?'p1'(?i)rah)\s+\k{p1}</item> + <item>(?P<p1>(?i)rah)\s+(?P=p1)</item> + <item>(?<p1>(?i)rah)\s+\g{p1}</item> </list> <p>A subpattern that is referenced by name may appear in the pattern before or @@ -2297,7 +2297,7 @@ after the reference.</p> subpattern has not actually been used in a particular match, any back references to it always fail. For example, the pattern</p> -<quote><p> (a|(bc))\\2</p></quote> +<quote><p> (a|(bc))\2</p></quote> <p>always fails if it starts to match "a" rather than "bc". Because there may be many capturing parentheses in a pattern, all digits @@ -2308,11 +2308,11 @@ some delimiter must be used to terminate the back reference. If the empty comment (see "Comments" below) can be used.</p> <p>A back reference that occurs inside the parentheses to which it refers fails -when the subpattern is first used, so, for example, (a\\1) never matches. +when the subpattern is first used, so, for example, (a\1) never matches. However, such references can be useful inside repeated subpatterns. For example, the pattern</p> -<quote><p> (a|b\\1)+</p></quote> +<quote><p> (a|b\1)+</p></quote> <p>matches any number of "a"s and also "aba", "ababbaa" etc. At each iteration of the subpattern, the back reference matches the character string corresponding @@ -2327,7 +2327,7 @@ minimum of zero.</p> <p>An assertion is a test on the characters following or preceding the current matching point that does not actually consume any characters. The simple -assertions coded as \\b, \\B, \\A, \\G, \\Z, \\z, ^ and $ are described +assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are described above.</p> @@ -2348,7 +2348,7 @@ because it does not make sense for negative assertions.</p> <p>Lookahead assertions start with (?= for positive assertions and (?! for negative assertions. For example,</p> -<quote><p> \\w+(?=;)</p></quote> +<quote><p> \w+(?=;)</p></quote> <p>matches a word followed by a semicolon, but does not include the semicolon in the match, and</p> @@ -2400,7 +2400,7 @@ lengths, but it is acceptable if rewritten to use two top-level branches:</p> <quote><p> (?<=abc|abde)</p></quote> -<p>In some cases, the Perl 5.10 escape sequence \\K (see above) can be +<p>In some cases, the Perl 5.10 escape sequence \K (see above) can be used instead of a lookbehind assertion; this is not restricted to a fixed-length.</p> @@ -2409,9 +2409,9 @@ temporarily move the current position back by the fixed length and then try to match. If there are insufficient characters before the current position, the assertion fails.</p> -<p>PCRE does not allow the \\C escape (which matches a single byte in UTF-8 mode) +<p>PCRE does not allow the \C escape (which matches a single byte in UTF-8 mode) to appear in lookbehind assertions, because it makes it impossible to calculate -the length of the lookbehind. The \\X and \\R escapes, which can match +the length of the lookbehind. The \X and \R escapes, which can match different numbers of bytes, are also not permitted.</p> <p>Possessive quantifiers can be used in conjunction with lookbehind assertions to @@ -2443,7 +2443,7 @@ approach makes a significant difference to the processing time.</p> <p>Several assertions (of any sort) may occur in succession. For example,</p> -<quote><p> (?<=\\d{3})(?<!999)foo</p></quote> +<quote><p> (?<=\d{3})(?<!999)foo</p></quote> <p>matches "foo" preceded by three digits that are not "999". Notice that each of the assertions is applied independently at the same point @@ -2454,7 +2454,7 @@ three characters are not "999". This pattern does <em>not</em> match the last three of which are not "999". For example, it doesn't match "123abcfoo". A pattern to do that is</p> -<quote><p> (?<=\\d{3}...)(?<!999)foo</p></quote> +<quote><p> (?<=\d{3}...)(?<!999)foo</p></quote> <p>This time the first assertion looks at the preceding six characters, checking that the first three are digits, and then the @@ -2468,7 +2468,7 @@ second assertion checks that the preceding three characters are not <p>matches an occurrence of "baz" that is preceded by "bar" which in turn is not preceded by "foo", while</p> -<quote><p> (?<=\\d{3}(?!999)...)foo</p></quote> +<quote><p> (?<=\d{3}(?!999)...)foo</p></quote> <p>is another pattern that matches "foo" preceded by three digits and any three characters that are not "999".</p> @@ -2510,7 +2510,7 @@ refer to subsequent groups with constructs such as (?(+2).</p> whitespace to make it more readable (assume the <c>extended</c> option) and to divide it into three parts for ease of discussion:</p> -<quote><p> ( \\( )? [^()]+ (?(1) \\) )</p></quote> +<quote><p> ( \( )? [^()]+ (?(1) \) )</p></quote> <p>The first part matches an optional opening parenthesis, and if that character is present, sets it as the first captured substring. The second part @@ -2525,7 +2525,7 @@ non-parentheses, optionally enclosed in parentheses.</p> <p>If you were embedding this pattern in a larger one, you could use a relative reference:</p> -<quote><p> ...other stuff... ( \\( )? [^()]+ (?(-1) \\) ) ...</p></quote> +<quote><p> ...other stuff... ( \( )? [^()]+ (?(-1) \) ) ...</p></quote> <p>This makes the fragment independent of the parentheses in the larger pattern.</p> @@ -2543,7 +2543,7 @@ consist entirely of digits is not recommended.</p> <p>Rewriting the above example to use a named subpattern gives this:</p> -<quote><p> (?<OPEN> \\( )? [^()]+ (?(<OPEN>) \\) )</p></quote> +<quote><p> (?<OPEN> \( )? [^()]+ (?(<OPEN>) \) )</p></quote> <p><em>Checking for pattern recursion</em></p> @@ -2571,8 +2571,8 @@ point in the pattern; the idea of DEFINE is that it can be used to define is described below.) For example, a pattern to match an IPv4 address could be written like this (ignore whitespace and line breaks):</p> -<quote><p> (?(DEFINE) (?<byte> 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) ) - \\b (?&byte) (\\.(?&byte)){3} \\b</p></quote> +<quote><p> (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) ) + \b (?&byte) (\.(?&byte)){3} \b</p></quote> <p>The first part of the pattern is a DEFINE group inside which a another group named "byte" is defined. This matches an individual component of an IPv4 @@ -2590,9 +2590,9 @@ assertion. This may be a positive or negative lookahead or lookbehind assertion. Consider this pattern, again containing non-significant whitespace, and with the two alternatives on the second line:</p> -<code type="none"> +<code type="none"> (?(?=[^a-z]*[a-z]) - \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )</code> + \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )</code> <p>The condition is a positive lookahead assertion that matches an optional sequence of non-letters followed by a letter. In other words, it tests for the @@ -2631,7 +2631,7 @@ can refer to the expression itself. A Perl pattern using code interpolation to solve the parentheses problem can be created like this:</p> -<quote><p> $re = qr{\\( (?: (?>[^()]+) | (?p{$re}) )* \\)}x;</p></quote> +<quote><p> $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;</p></quote> <p>The (?p{...}) item interpolates Perl code at run time, and in this case refers recursively to the pattern in which it appears.</p> @@ -2657,7 +2657,7 @@ failure.</p> <p>This PCRE pattern solves the nested parentheses problem (assume the <c>extended</c> option is set so that whitespace is ignored):</p> -<quote><p> \\( ( (?>[^()]+) | (?R) )* \\)</p></quote> +<quote><p> \( ( (?>[^()]+) | (?R) )* \)</p></quote> <p>First it matches an opening parenthesis. Then it matches any number of substrings which can either be a sequence of non-parentheses, or a @@ -2667,7 +2667,7 @@ parenthesized substring). Finally there is a closing parenthesis.</p> <p>If this were part of a larger pattern, you would not want to recurse the entire pattern, so instead you could use this:</p> -<quote><p> ( \\( ( (?>[^()]+) | (?1) )* \\) )</p></quote> +<quote><p> ( \( ( (?>[^()]+) | (?1) )* \) )</p></quote> <p>We have put the pattern into parentheses, and caused the recursion to refer to them instead of the whole pattern.</p> @@ -2691,7 +2691,7 @@ Perl syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also supported. We could rewrite the above example as follows:</p> -<quote><p> (?<pn> \\( ( (?>[^()]+) | (?&pn) )* \\) )</p></quote> +<quote><p> (?<pn> \( ( (?>[^()]+) | (?&pn) )* \) )</p></quote> <p>If there is more than one subpattern with the same name, the earliest one is used.</p> @@ -2727,7 +2727,7 @@ If the pattern above is matched against</p> on at the top level. If additional parentheses are added, giving</p> <code type="none"> - \\( ( ( (?>[^()]+) | (?R) )* ) \\) + \( ( ( (?>[^()]+) | (?R) )* ) \) ^ ^ ^ ^</code> @@ -2747,7 +2747,7 @@ brackets, allowing for arbitrary nesting. Only digits are allowed in nested brackets (that is, when recursing), whereas any characters are permitted at the outer level.</p> -<quote><p> < (?: (?(R) \\d++ | [^<>]*+) | (?R)) * ></p></quote> +<quote><p> < (?: (?(R) \d++ | [^<>]*+) | (?R)) * ></p></quote> <p>In this pattern, (?(R) is the start of a conditional subpattern, with two different alternatives for the recursive and non-recursive @@ -2771,7 +2771,7 @@ relative, as in these examples:</p> <p>An earlier example pointed out that the pattern</p> -<quote><p> (sens|respons)e and \\1ibility</p></quote> +<quote><p> (sens|respons)e and \1ibility</p></quote> <p>matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility". If instead the pattern</p> diff --git a/lib/stdlib/doc/src/regexp.xml b/lib/stdlib/doc/src/regexp.xml index 8da636e4ad..8c4191c88f 100644 --- a/lib/stdlib/doc/src/regexp.xml +++ b/lib/stdlib/doc/src/regexp.xml @@ -132,7 +132,7 @@ <v>RepCount = integer()</v> </type> <desc> - <p>Substitutes the first occurrence of a substring matching <c>RegExp</c> in <c>String</c> with the string <c>New</c>. A <c><![CDATA[&]]></c> in the string <c>New</c> is replaced by the matched substring of <c>String</c>. <c><![CDATA[\\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p> + <p>Substitutes the first occurrence of a substring matching <c>RegExp</c> in <c>String</c> with the string <c>New</c>. A <c><![CDATA[&]]></c> in the string <c>New</c> is replaced by the matched substring of <c>String</c>. <c><![CDATA[\&]]></c> puts a literal <c><![CDATA[&]]></c> into the replacement string. It returns as follows:</p> <taglist> <tag><c>{ok,NewString,RepCount}</c></tag> <item> @@ -286,7 +286,7 @@ <item> <p>matches the non-metacharacter <c>c</c>.</p> </item> - <tag>\\c</tag> + <tag>\c</tag> <item> <p>matches the escape sequence or literal character <c>c</c>.</p> </item> @@ -341,74 +341,74 @@ <p>The escape sequences allowed are the same as for Erlang strings:</p> <taglist> - <tag><c>\\b</c></tag> + <tag><c>\b</c></tag> <item> <p>backspace</p> </item> - <tag><c>\\f</c></tag> + <tag><c>\f</c></tag> <item> <p>form feed </p> </item> - <tag><c>\</c></tag> + <tag><c>\n</c></tag> <item> <p>newline (line feed) </p> </item> - <tag><c>\\r</c></tag> + <tag><c>\r</c></tag> <item> <p>carriage return </p> </item> - <tag><c>\\t</c></tag> + <tag><c>\t</c></tag> <item> <p>tab </p> </item> - <tag><c>\\e</c></tag> + <tag><c>\e</c></tag> <item> <p>escape </p> </item> - <tag><c>\\v</c></tag> + <tag><c>\v</c></tag> <item> <p>vertical tab </p> </item> - <tag><c>\\s</c></tag> + <tag><c>\s</c></tag> <item> <p>space </p> </item> - <tag><c>\\d</c></tag> + <tag><c>\d</c></tag> <item> <p>delete </p> </item> - <tag><c>\\ddd</c></tag> + <tag><c>\ddd</c></tag> <item> <p>the octal value ddd </p> </item> - <tag><c>\\xhh</c></tag> + <tag><c>\xhh</c></tag> <item> <p>The hexadecimal value <c>hh</c>.</p> </item> - <tag><c>\\x{h...}</c></tag> + <tag><c>\x{h...}</c></tag> <item> <p>The hexadecimal value <c>h...</c>.</p> </item> - <tag><c>\\c</c></tag> + <tag><c>\c</c></tag> <item> - <p>any other character literally, for example <c>\\\\</c> for backslash, - <c>\\"</c> for ")</p> + <p>any other character literally, for example <c>\\</c> for backslash, + <c>\"</c> for ")</p> </item> </taglist> <p>To make these functions easier to use, in combination with the function <c>io:get_line</c> which terminates the input line with a new line, the <c>$</c> characters also matches a string ending - with <c>"...\ "</c>. The following examples + with <c>"...\n"</c>. The following examples define Erlang data types:</p> <pre> Atoms [a-z][0-9a-zA-Z_]* Variables [A-Z_][0-9a-zA-Z_]* -Floats (\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?</pre> - <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\\</c> or <c>"</c> characters in a regular expression - string must be written with <c>\\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is: - <c>"(\\\\+|-)?[0-9]+\\\\.[0-9]+((E|e)(\\\\+|-)?[0-9]+)?"</c>.</p> +Floats (\+|-)?[0-9]+\.[0-9]+((E|e)(\+|-)?[0-9]+)?</pre> + <p>Regular expressions are written as Erlang strings when used with the functions in this module. This means that any <c>\</c> or <c>"</c> characters in a regular expression + string must be written with <c>\</c> as they are also escape characters for the string. For example, the regular expression string for Erlang floats is: + <c>"(\\+|-)?[0-9]+\\.[0-9]+((E|e)(\\+|-)?[0-9]+)?"</c>.</p> <p>It is not really necessary to have the escape sequences as part of the regular expression syntax as they can always be generated directly in the string. They are included for completeness and can they can also be useful when generating regular expressions, or when they are entered other than with Erlang strings.</p> </section> </erlref> diff --git a/lib/stdlib/doc/src/shell.xml b/lib/stdlib/doc/src/shell.xml index 24b845fee9..b8fc64f45e 100644 --- a/lib/stdlib/doc/src/shell.xml +++ b/lib/stdlib/doc/src/shell.xml @@ -333,10 +333,12 @@ undefined <0.57.0> 27> <input>get(aa).</input> hello -28> <input>io:format("hello hello\ ").</input> -hello hello ok +28> <input>io:format("hello hello\n").</input> +hello hello +ok 29> <input>e(28).</input> -hello hello ok +hello hello +ok 30> <input>v(28).</input> ok 31> <input>c(ex).</input> diff --git a/lib/stdlib/doc/src/string.xml b/lib/stdlib/doc/src/string.xml index 7ee38e496d..de1b99a2d5 100644 --- a/lib/stdlib/doc/src/string.xml +++ b/lib/stdlib/doc/src/string.xml @@ -117,9 +117,9 @@ from) Chars.</p> <p>For example:</p> <code type="none"> -> string:span("\\t abcdef", " \\t"). +> string:span("\t abcdef", " \t"). 5 -> string:cspan("\\t abcdef", " \\t"). +> string:cspan("\t abcdef", " \t"). 0 </code> </desc> </func> diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml index a395a8a415..10ead62073 100644 --- a/lib/stdlib/doc/src/sys.xml +++ b/lib/stdlib/doc/src/sys.xml @@ -4,23 +4,21 @@ <erlref> <header> <copyright> - <year>1996</year> - <year>2007</year> - <holder>Ericsson AB, All Rights Reserved</holder> + <year>1996</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + </legalnotice> <title>sys</title> @@ -237,6 +235,17 @@ </type> <desc> <p>Gets the status of the process.</p> + <p>The value of <c>Misc</c> varies for different types of + processes. For example, a <c>gen_server</c> process returns + the callback module's state, and a <c>gen_fsm</c> process + returns information such as its current state name. Callback + modules for <c>gen_server</c> and <c>gen_fsm</c> can also + customise the value of <c>Misc</c> by exporting + a <c>format_status/2</c> function that contributes + module-specific information; + see <seealso marker="gen_server#format_status/2">gen_server:format_status/2</seealso> + and <seealso marker="gen_fsm#format_status/2">gen_fsm:format_status/2</seealso> + for more details.</p> </desc> </func> <func> diff --git a/lib/stdlib/doc/src/win32reg.xml b/lib/stdlib/doc/src/win32reg.xml index d8055047b0..28960cd098 100644 --- a/lib/stdlib/doc/src/win32reg.xml +++ b/lib/stdlib/doc/src/win32reg.xml @@ -48,7 +48,7 @@ <p>Paths to keys are left to right, with sub-keys to the right and backslash between keys. (Remember that backslashes must be doubled in Erlang strings.) Case is preserved but not significant. - Example: <c>"\\\\hkey_local_machine\\\\software\\\\Ericsson\\\\Erlang\\\\5.0"</c> is the key + Example: <c>"\\hkey_local_machine\\software\\Ericsson\\Erlang\\5.0"</c> is the key for the installation data for the latest Erlang release.</p> <p>There are six entry points in the Windows registry, top level keys. They can be abbreviated in the <c>win32reg</c> module as:</p> @@ -66,7 +66,7 @@ current_config HKEY_CURRENT_CONFIG hkcc HKEY_CURRENT_CONFIG dyn_data HKEY_DYN_DATA hkdd HKEY_DYN_DATA</pre> - <p>The key above could be written as <c>"\\\\hklm\\\\software\\\\ericsson\\\\erlang\\\\5.0"</c>.</p> + <p>The key above could be written as <c>"\\hklm\\software\\ericsson\\erlang\\5.0"</c>.</p> <p>The <c>win32reg</c> module uses a current key. It works much like the current directory. From the current key, values can be fetched, sub-keys can be listed, and so on.</p> @@ -96,7 +96,7 @@ hkdd HKEY_DYN_DATA</pre> <desc> <p>Changes the current key to another key. Works like cd. The key can be specified as a relative path or as an - absolute path, starting with \\.</p> + absolute path, starting with \.</p> </desc> </func> <func> diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index 9e4cec5db2..433833e233 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -197,7 +197,9 @@ nc(File, Opts0) when is_list(Opts0) -> Opts = Opts0 ++ [report_errors, report_warnings], case compile:file(File, Opts) of {ok,Mod} -> - Fname = concat([File, code:objfile_extension()]), + Dir = outdir(Opts), + Obj = filename:basename(File, ".erl") ++ code:objfile_extension(), + Fname = filename:join(Dir, Obj), case file:read_file(Fname) of {ok,Bin} -> rpc:eval_everywhere(code,load_binary,[Mod,Fname,Bin]), diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl index f3775f967a..ba0275ae2b 100644 --- a/lib/stdlib/src/gen_fsm.erl +++ b/lib/stdlib/src/gen_fsm.erl @@ -603,7 +603,12 @@ get_msg(Msg) -> Msg. format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] = StatusData, - Header = lists:concat(["Status for state machine ", Name]), + NameTag = if is_pid(Name) -> + pid_to_list(Name); + is_atom(Name) -> + Name + end, + Header = lists:concat(["Status for state machine ", NameTag]), Log = sys:get_debug(log, Debug, []), Specfic = case erlang:function_exported(Mod, format_status, 2) of diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl index e0f2dbcd3c..12209c16d7 100644 --- a/lib/stdlib/src/sys.erl +++ b/lib/stdlib/src/sys.erl @@ -245,8 +245,17 @@ do_cmd(SysState, Other, _Parent, _Mod, Debug, Misc) -> {SysState, {error, {unknown_system_msg, Other}}, Debug, Misc}. get_status(SysState, Parent, Mod, Debug, Misc) -> + PDict = get(), + FmtMisc = + case erlang:function_exported(Mod, format_status, 2) of + true -> + FmtArgs = [PDict, SysState, Parent, Debug, Misc], + Mod:format_status(normal, FmtArgs); + _ -> + Misc + end, {status, self(), {module, Mod}, - [get(), SysState, Parent, Debug, Misc]}. + [PDict, SysState, Parent, Debug, FmtMisc]}. %%----------------------------------------------------------------- %% These are the system debug commands. diff --git a/lib/stdlib/test/c_SUITE.erl b/lib/stdlib/test/c_SUITE.erl index 5608d73d19..2edbc7ab4c 100644 --- a/lib/stdlib/test/c_SUITE.erl +++ b/lib/stdlib/test/c_SUITE.erl @@ -18,15 +18,16 @@ %% -module(c_SUITE). -export([all/1]). --export([c_1/1, c_2/1, c_3/1, c_4/1, memory/1]). +-export([c_1/1, c_2/1, c_3/1, c_4/1, nc_1/1, nc_2/1, nc_3/1, nc_4/1, + memory/1]). -include("test_server.hrl"). --import(c, [c/2]). +-import(c, [c/2, nc/2]). all(doc) -> ["Test cases for the 'c' module."]; all(suite) -> - [c_1, c_2, c_3, c_4, memory]. + [c_1, c_2, c_3, c_4, nc_1, nc_2, nc_3, nc_4, memory]. %%% Write output to a directory other than current directory: @@ -34,7 +35,7 @@ c_1(doc) -> ["Checks that c:c works also with option 'outdir' [ticket OTP-1209]."]; c_1(suite) -> []; -c_1(Config) when list(Config) -> +c_1(Config) when is_list(Config) -> ?line R = filename:join(?config(data_dir, Config), "m.erl"), ?line W = ?config(priv_dir, Config), ?line Result = c(R,[{outdir,W}]), @@ -44,7 +45,7 @@ c_2(doc) -> ["Checks that c:c works also with option 'outdir' [ticket OTP-1209]."]; c_2(suite) -> []; -c_2(Config) when list(Config) -> +c_2(Config) when is_list(Config) -> ?line R = filename:join(?config(data_dir, Config), "m"), ?line W = ?config(priv_dir, Config), ?line Result = c(R,[{outdir,W}]), @@ -59,7 +60,7 @@ c_3(doc) -> "directory). [ticket OTP-1209]."]; c_3(suite) -> []; -c_3(Config) when list(Config) -> +c_3(Config) when is_list(Config) -> ?line R = filename:join(?config(data_dir, Config), "m.erl"), ?line W = ?config(priv_dir, Config), ?line file:set_cwd(W), @@ -71,18 +72,68 @@ c_4(doc) -> "directory). [ticket OTP-1209]."]; c_4(suite) -> []; -c_4(Config) when list(Config) -> +c_4(Config) when is_list(Config) -> ?line R = filename:join(?config(data_dir, Config), "m"), ?line W = ?config(priv_dir, Config), ?line file:set_cwd(W), ?line Result = c(R,[{outdir,W}]), ?line {ok, m} = Result. +%%% Write output to a directory other than current directory: + +nc_1(doc) -> + ["Checks that c:nc works also with option 'outdir'."]; +nc_1(suite) -> + []; +nc_1(Config) when is_list(Config) -> + ?line R = filename:join(?config(data_dir, Config), "m.erl"), + ?line W = ?config(priv_dir, Config), + ?line Result = nc(R,[{outdir,W}]), + ?line {ok, m} = Result. + +nc_2(doc) -> + ["Checks that c:nc works also with option 'outdir'."]; +nc_2(suite) -> + []; +nc_2(Config) when is_list(Config) -> + ?line R = filename:join(?config(data_dir, Config), "m"), + ?line W = ?config(priv_dir, Config), + ?line Result = nc(R,[{outdir,W}]), + ?line {ok, m} = Result. + + +%%% Put results in current directory (or rather, change current dir +%%% to the output dir): + +nc_3(doc) -> + ["Checks that c:nc works also with option 'outdir' (same as current" + "directory)."]; +nc_3(suite) -> + []; +nc_3(Config) when is_list(Config) -> + ?line R = filename:join(?config(data_dir, Config), "m.erl"), + ?line W = ?config(priv_dir, Config), + ?line file:set_cwd(W), + ?line Result = nc(R,[{outdir,W}]), + ?line {ok, m} = Result. + +nc_4(doc) -> + ["Checks that c:nc works also with option 'outdir' (same as current" + "directory)."]; +nc_4(suite) -> + []; +nc_4(Config) when is_list(Config) -> + ?line R = filename:join(?config(data_dir, Config), "m"), + ?line W = ?config(priv_dir, Config), + ?line file:set_cwd(W), + ?line Result = nc(R,[{outdir,W}]), + ?line {ok, m} = Result. + memory(doc) -> ["Checks that c:memory/[0,1] returns consistent results."]; memory(suite) -> []; -memory(Config) when list(Config) -> +memory(Config) when is_list(Config) -> try ?line ML = c:memory(), ?line T = mget(total, ML), @@ -112,5 +163,5 @@ mget(K, L) -> ?line test_v(V). % Help function for c_SUITE:memory/1 -test_v(V) when integer(V) -> +test_v(V) when is_integer(V) -> ?line V. diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl index 62f8b2f9dd..23c1d9a193 100644 --- a/lib/stdlib/test/gen_fsm_SUITE.erl +++ b/lib/stdlib/test/gen_fsm_SUITE.erl @@ -30,7 +30,7 @@ -export([shutdown/1]). --export([sys/1, sys1/1]). +-export([sys/1, sys1/1, call_format_status/1]). -export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]). @@ -42,7 +42,7 @@ % The gen_fsm behaviour -export([init/1, handle_event/3, handle_sync_event/4, terminate/3, - handle_info/3]). + handle_info/3, format_status/2]). -export([idle/2, idle/3, timeout/2, wfor_conf/2, wfor_conf/3, @@ -305,7 +305,7 @@ shutdown(Config) when is_list(Config) -> ok. -sys(suite) -> [sys1]. +sys(suite) -> [sys1, call_format_status]. sys1(Config) when is_list(Config) -> ?line {ok, Pid} = @@ -317,6 +317,13 @@ sys1(Config) when is_list(Config) -> ?line sys:resume(Pid), ?line stop_it(Pid). +call_format_status(Config) when is_list(Config) -> + ?line {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, [], []), + ?line Status = sys:get_status(Pid), + ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data]} = Status, + ?line [format_status_called | _] = lists:reverse(Data), + ?line stop_it(Pid). + %% Hibernation hibernate(suite) -> []; @@ -836,3 +843,6 @@ handle_sync_event(stop_shutdown_reason, _From, _State, Data) -> {stop, {shutdown,reason}, {shutdown,reason}, Data}; handle_sync_event({get, _Pid}, _From, State, Data) -> {reply, {state, State, Data}, State, Data}. + +format_status(_Opt, [_Pdict, _StateData]) -> + [format_status_called]. diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl index 86a5a65ba3..6efdce78a1 100644 --- a/lib/stdlib/test/gen_server_SUITE.erl +++ b/lib/stdlib/test/gen_server_SUITE.erl @@ -30,7 +30,7 @@ call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1, spec_init_local_registered_parent/1, spec_init_global_registered_parent/1, - otp_5854/1, hibernate/1, otp_7669/1 + otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1 ]). % spawn export @@ -42,7 +42,7 @@ % The gen_server behaviour -export([init/1, handle_call/3, handle_cast/2, - handle_info/2, terminate/2]). + handle_info/2, terminate/2, format_status/2]). all(suite) -> [start, crash, call, cast, cast_fast, info, @@ -51,7 +51,7 @@ all(suite) -> call_remote_n2, call_remote_n3, spec_init, spec_init_local_registered_parent, spec_init_global_registered_parent, - otp_5854,hibernate,otp_7669]. + otp_5854, hibernate, otp_7669, call_format_status]. -define(default_timeout, ?t:minutes(1)). @@ -851,7 +851,7 @@ otp_5854(Config) when is_list(Config) -> ok. %% If initialization fails (with ignore or {stop,Reason}), -%% make sure that the process is not registered when gen_sever:start() +%% make sure that the process is not registered when gen_server:start() %% returns. otp_7669(Config) when is_list(Config) -> @@ -887,6 +887,24 @@ do_otp_7669_stop() -> ?MODULE, stop, []), ?line undefined = global:whereis_name(?MODULE). +%% Verify that sys:get_status correctly calls our format_status/2 fun +%% +call_format_status(suite) -> + []; +call_format_status(doc) -> + ["Test that sys:get_status/1,2 calls format_status/2"]; +call_format_status(Config) when is_list(Config) -> + ?line {ok, Pid} = gen_server:start_link({local, call_format_status}, + gen_server_SUITE, [], []), + ?line Status1 = sys:get_status(call_format_status), + ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data1]} = Status1, + ?line [format_status_called | _] = lists:reverse(Data1), + ?line Status2 = sys:get_status(call_format_status, 5000), + ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data2]} = Status2, + ?line [format_status_called | _] = lists:reverse(Data2), + ok. + + %%-------------------------------------------------------------- %% Help functions to spec_init_* start_link(Init, Options) -> @@ -1046,4 +1064,5 @@ terminate({From, stopped_info}, _State) -> terminate(_Reason, _State) -> ok. - +format_status(_Opt, [_PDict, _State]) -> + [format_status_called]. diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml index 3d95813c14..42c965b496 100644 --- a/lib/test_server/doc/src/test_server_ctrl.xml +++ b/lib/test_server/doc/src/test_server_ctrl.xml @@ -582,7 +582,7 @@ Optional, if not given the test server controller node <br></br> <c>erl -noshell -s test_server_ctrl run_test KEY1 Value1 KEY2 Value2 ... -s erlang halt</c></p> <p>Or make an alias (this is for unix/tcsh) <br></br> -<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \\!* -s erlang halt'</c></p> +<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \!* -s erlang halt'</c></p> <p>And then use it like this <br></br> <c>erl_test KEY1 Value1 KEY2 Value2 ...</c> <br></br> </p> diff --git a/lib/test_server/doc/src/write_framework_chapter.xml b/lib/test_server/doc/src/write_framework_chapter.xml index 2fde67132e..8a20e9afec 100644 --- a/lib/test_server/doc/src/write_framework_chapter.xml +++ b/lib/test_server/doc/src/write_framework_chapter.xml @@ -103,7 +103,7 @@ <p>A typical command line may look like this <br></br> <c>erl -noshell -s test_server_ctrl run_test KEY1 Value1 KEY2 Value2 ... -s erlang halt</c></p> <p>Or make an alias (this is for unix/tcsh) <br></br> -<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \\!* -s erlang halt'</c></p> +<c>alias erl_test 'erl -noshell -s test_server_ctrl run_test \!* -s erlang halt'</c></p> <p>And then use it like this <br></br> <c>erl_test KEY1 Value1 KEY2 Value2 ...</c> <br></br> </p> diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml index 72770898c2..912c442153 100644 --- a/lib/tools/doc/src/erlang_mode.xml +++ b/lib/tools/doc/src/erlang_mode.xml @@ -51,7 +51,7 @@ <list type="bulleted"> <item><em><c>TAB</c></em> (<c>erlang-indent-command</c>) - Indents the current line of code. </item> - <item><em><c>M-C-\\</c></em> (<c>indent-region</c>) - Indents all + <item><em><c>M-C-\</c></em> (<c>indent-region</c>) - Indents all lines in the region. </item> <item><em><c>M-l</c></em> (<c>indent-for-comment</c>) - Insert a comment character to the right of the code on the line (if diff --git a/lib/tools/doc/src/erlang_mode_chapter.xml b/lib/tools/doc/src/erlang_mode_chapter.xml index cf043e3302..b22c6b1809 100644 --- a/lib/tools/doc/src/erlang_mode_chapter.xml +++ b/lib/tools/doc/src/erlang_mode_chapter.xml @@ -74,10 +74,10 @@ environment variable is set, Emacs will look for the <c>.emacs</c> file in the directory indicated by the <em>HOME</em> variable. If <em>HOME</em> is not set, Emacs - will look for the <c>.emacs</c> file in <c>C:\\ </c>.</p> + will look for the <c>.emacs</c> file in <c>C:\ </c>.</p> <p>Below is a complete example of what should be added to a user's <c>.emacs</c> provided that OTP is installed in the directory - <c><![CDATA[C:\\Program Files\\erl<Ver>]]></c>: </p> + <c><![CDATA[C:\Program Files\erl<Ver>]]></c>: </p> <code type="none"><![CDATA[ (setq load-path (cons "C:/Program Files/erl<Ver>/lib/tools-<ToolsVer>/emacs" load-path)) @@ -87,7 +87,7 @@ ]]></code> <note> <p>In .emacs, the slash character "/" can be used as path - separator. But if you decide to use the backslash character "\\", + separator. But if you decide to use the backslash character "\", please not that you must use double backslashes, since they are treated as escape characters by Emacs.</p> </note> diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 59f600145e..e6c074cc7d 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,21 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.6.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>A bug concerning bit comprehensions has been fixed + in Cover. The bug was introduced in R13B03. + (Thanks to Matthew Sackman.)</p> + <p>Own Id: OTP-8340</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.6.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/doc/src/notes_history.xml b/lib/tools/doc/src/notes_history.xml index ef5ce1c03d..3791d5270a 100644 --- a/lib/tools/doc/src/notes_history.xml +++ b/lib/tools/doc/src/notes_history.xml @@ -4,23 +4,21 @@ <chapter> <header> <copyright> - <year>2006</year> - <year>2007</year> - <holder>Ericsson AB, All Rights Reserved</holder> + <year>2006</year><year>2009</year> + <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - The Initial Developer of the Original Code is Ericsson AB. + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + </legalnotice> <title>Tools Release Notes</title> @@ -63,7 +61,7 @@ <p>Own Id: OTP-5073</p> </item> <item> - <p>Previous patch from open source messed up \\M-q so part of + <p>Previous patch from open source messed up \M-q so part of that patch was backed out.</p> <p>Own Id: OTP-5074</p> </item> diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml index 6fff68fe9f..407a7392ad 100644 --- a/lib/tools/doc/src/xref.xml +++ b/lib/tools/doc/src/xref.xml @@ -1176,7 +1176,7 @@ Evaluates a predefined analysis. <item> <p><c>no_functions</c>. Functions in library modules and the functions <c>module_info/0,1</c> are not counted by - <c>info</c>. Assuming that <c>"Extra := _:module_info/\\"(0|1)\\" + LM"</c> has been evaluated, the + <c>info</c>. Assuming that <c>"Extra := _:module_info/\"(0|1)\" + LM"</c> has been evaluated, the sum of the number of local and exported functions are:</p> <list type="bulleted"> <item><c>"# (F - Extra)"</c> (info/1)</item> diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl index aff3927db3..1a7ebdc69a 100644 --- a/lib/tools/src/cover.erl +++ b/lib/tools/src/cover.erl @@ -1685,8 +1685,8 @@ munge_expr({lc,Line,Expr,Qs}, Vars) -> {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), {{lc,Line,MungedExpr,MungedQs}, Vars3}; munge_expr({bc,Line,Expr,Qs}, Vars) -> - {bin,BLine,[{bin_element,EL,Val,Sz,TSL}]} = Expr, - Expr2 = {bin,BLine,[{bin_element,EL,?BLOCK1(Val),Sz,TSL}]}, + {bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]} = Expr, + Expr2 = {bin,BLine,[{bin_element,EL,?BLOCK1(Val),Sz,TSL}|Es]}, {MungedExpr,Vars2} = munge_expr(Expr2, Vars), {MungedQs, Vars3} = munge_qualifiers(Qs, Vars2), {{bc,Line,MungedExpr,MungedQs}, Vars3}; diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 644e8b719b..13cf5af9f5 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -16,4 +16,4 @@ # # %CopyrightEnd% -TOOLS_VSN = 2.6.5 +TOOLS_VSN = 2.6.5.1 diff --git a/lib/webtool/doc/src/webtool_chapter.xml b/lib/webtool/doc/src/webtool_chapter.xml index ceadce382d..f72a255b0a 100644 --- a/lib/webtool/doc/src/webtool_chapter.xml +++ b/lib/webtool/doc/src/webtool_chapter.xml @@ -212,16 +212,13 @@ http://Servername:Port/ErlScriptAlias/Mod/Func<?QueryString> ]]></code> header("text/html"). header(MimeType) -> - "Content-type: " ++ MimeType ++ "\\r\ -\\r\ -". + "Content-type: " ++ MimeType ++ "\r\n\r\n". html_header() -> "<HTML> <HEAD> <TITLE>Hello world Example </TITLE> - </HEAD>\ -". + </HEAD>\n". helloworld_body()-> "<BODY>Hello World</BODY>". diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index df154f0125..4a646650ea 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -985,7 +985,9 @@ {class, wxFileDialog, wxDialog, [{skip, [{wxFileDialog,0}]}], ['wxFileDialog','~wxFileDialog','GetDirectory','GetFilename', {'GetFilenames',[{"files", out}]}, - 'GetFilterIndex','GetMessage','GetPath','GetPaths','GetWildcard', + 'GetFilterIndex','GetMessage','GetPath', + {'GetPaths', [{"paths", out}]}, + 'GetWildcard', 'SetDirectory','SetFilename','SetFilterIndex','SetMessage','SetPath', 'SetWildcard']}. diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index cb662fc91b..ccbacce9b9 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -20582,19 +20582,11 @@ case wxFileDialog_GetPath: { // wxFileDialog::GetPath break; } case wxFileDialog_GetPaths: { // wxFileDialog::GetPaths - wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4; - int * pathsLen = (int *) bp; bp += 4; wxArrayString paths; - int pathsASz = 0, * pathsTemp; - for(int i=0; i < *pathsLen; i++) { - pathsTemp = (int *) bp; bp += 4; - paths.Add(wxString(bp, wxConvUTF8)); - bp += *pathsTemp; - pathsASz += *pathsTemp+4; - } - bp += (8-((0+ pathsASz) & 7 )) & 7; + wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4; if(!This) throw wxe_badarg(0); This->GetPaths(paths); + rt.add(paths); break; } case wxFileDialog_GetWildcard: { // wxFileDialog::GetWildcard diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 7dc8d6e831..2b47f86baa 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -1,3 +1,21 @@ +dnl Process this file with autoconf to produce a configure script. -*-m4-*- + +dnl %CopyrightBegin% +dnl +dnl Copyright Ericsson AB 2008-2009. All Rights Reserved. +dnl +dnl The contents of this file are subject to the Erlang Public License, +dnl Version 1.1, (the "License"); you may not use this file except in +dnl compliance with the License. You should have received a copy of the +dnl Erlang Public License along with this software. If not, it can be +dnl retrieved online at http://www.erlang.org/. +dnl +dnl Software distributed under the License is distributed on an "AS IS" +dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +dnl the License for the specific language governing rights and limitations +dnl under the License. +dnl +dnl %CopyrightEnd% AC_INIT() @@ -101,7 +119,7 @@ AC_SUBST(MIXED_CYGWIN) ## Check that we are in 32 bits mode on darwin ## (wxWidgets require that it currently uses 32-bits Carbon) ## Otherwise skip building wxErlang -AC_CHECK_SIZEOF(void *, 4) +AC_CHECK_SIZEOF(void *) case $ac_cv_sizeof_void_p-$host_os in 8-darwin*) diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile index d18daa753a..fd9f7441a3 100644 --- a/lib/wx/doc/src/Makefile +++ b/lib/wx/doc/src/Makefile @@ -31,12 +31,6 @@ GenMods = $(shell ls ../../src/gen | grep 'wx[A-Z].*\.erl') \ glu.erl \ gl.erl -# GenMods = \ -# wx_misc.erl \ -# glu.erl \ -# gl.erl - - ModsNoExt = $(ErlMods:%.erl=%) $(GenMods:%.erl=%) ifneq ($(INSIDE_ERLSRC),true) @@ -126,9 +120,9 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%) xml: $(XML_REF3_FILES) $(XML_CHAPTER_FILES) -ref_man.xml: ref_man.src.xml +ref_man.xml: ref_man.xml.src @echo Preparing ref_man.xml - @cat ref_man.src.xml > ref_man.xml + @cat ref_man.xml.src > ref_man.xml @for d in $(ModsNoExt); do \ echo " <xi:include href=\"$$d.xml\"/>" >> ref_man.xml ; \ done diff --git a/lib/wx/doc/src/ref_man.src.xml b/lib/wx/doc/src/ref_man.xml.src index 77fd16b050..77fd16b050 100644 --- a/lib/wx/doc/src/ref_man.src.xml +++ b/lib/wx/doc/src/ref_man.xml.src diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl index 22b39aa150..efe1ff57f3 100644 --- a/lib/wx/src/gen/wxFileDialog.erl +++ b/lib/wx/src/gen/wxFileDialog.erl @@ -31,7 +31,7 @@ -module(wxFileDialog). -include("wxe.hrl"). -export([destroy/1,getDirectory/1,getFilename/1,getFilenames/1,getFilterIndex/1, - getMessage/1,getPath/1,getPaths/2,getWildcard/1,new/1,new/2,setDirectory/2, + getMessage/1,getPath/1,getPaths/1,getWildcard/1,new/1,new/2,setDirectory/2, setFilename/2,setFilterIndex/2,setMessage/2,setPath/2,setWildcard/2]). %% inherited exports @@ -152,15 +152,12 @@ getPath(#wx_ref{type=ThisT,ref=ThisRef}) -> wxe_util:call(?wxFileDialog_GetPath, <<ThisRef:32/?UI>>). -%% @spec (This::wxFileDialog(), Paths::[[string()]]) -> ok +%% @spec (This::wxFileDialog()) -> [[string()]] %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html#wxfiledialoggetpaths">external documentation</a>. -getPaths(#wx_ref{type=ThisT,ref=ThisRef},Paths) - when is_list(Paths) -> +getPaths(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxFileDialog), - Paths_UCA = [unicode:characters_to_binary([PathsTemp,0]) || - PathsTemp <- Paths], - wxe_util:cast(?wxFileDialog_GetPaths, - <<ThisRef:32/?UI,(length(Paths_UCA)):32/?UI, (<< <<(byte_size(UC_Str)):32/?UI, UC_Str/binary>>|| UC_Str <- Paths_UCA>>)/binary, 0:(((8- ((0 + lists:sum([byte_size(S)+4||S<-Paths_UCA])) band 16#7)) band 16#7))/unit:8>>). + wxe_util:call(?wxFileDialog_GetPaths, + <<ThisRef:32/?UI>>). %% @spec (This::wxFileDialog()) -> string() %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html#wxfiledialoggetwildcard">external documentation</a>. |