diff --git a/src/Collections-Strings-Tests/StringTest.class.st b/src/Collections-Strings-Tests/StringTest.class.st index db82d0b6ad7..0799ea6b544 100644 --- a/src/Collections-Strings-Tests/StringTest.class.st +++ b/src/Collections-Strings-Tests/StringTest.class.st @@ -440,11 +440,12 @@ StringTest >> testAsHTMLString [ { #category : 'tests - converting' } StringTest >> testAsInteger [ - self assert: '1796exportFixes-tkMX' asInteger equals: 1796. - self assert: 'donald' asInteger isNil. - self assert: 'abc234def567' asInteger equals: 234. + self should: [ '1796exportFixes-tkMX' asInteger ] raise: Error. + self should: [ 'donald' asInteger ] raise: Error. + self should: [ 'abc234def567' asInteger ] raise: Error. + self should: [ '123 4' asInteger ] raise: Error. self assert: '-94' asInteger equals: -94. - self assert: 'foo-bar-92' asInteger equals: -92 + self assert: '9432' asInteger equals: 9432 ] { #category : 'tests' } @@ -533,6 +534,16 @@ StringTest >> testAsTime [ self assert: '13' asTime asString equals: '1:00 pm' ] +{ #category : 'tests' } +StringTest >> testAsUnsignedInteger [ + + self should: [ 'test' asUnsignedInteger ] raise: Error. + self should: [ 'test-10test' asUnsignedInteger ] raise: Error. + self assert: '-1234567890' asUnsignedInteger equals: 1234567890. + self assert: '-12345' asUnsignedInteger equals: 12345. + self assert: '111' asUnsignedInteger equals: 111 +] + { #category : 'tests' } StringTest >> testAsUppercase [ @@ -860,6 +871,16 @@ StringTest >> testExpandMacrosWithArgumentsLongText [ self assert: ('<1p>' expandMacrosWith: ('a' repeat: 100000)) size equals: 100002 ] +{ #category : 'tests' } +StringTest >> testExtractIntegerPart [ + + self assert: '1796exportFixes-tkMX' extractIntegerPart equals: 1796. + self assert: 'donald' extractIntegerPart isNil. + self assert: 'abc234def567' extractIntegerPart equals: 234. + self assert: '-94' extractIntegerPart equals: -94. + self assert: 'foo-bar-92' extractIntegerPart equals: -92 +] + { #category : 'tests' } StringTest >> testFindAnySubstringStartingAt [ diff --git a/src/Collections-Strings-Tests/WideStringTest.class.st b/src/Collections-Strings-Tests/WideStringTest.class.st index 62feaf5da89..c770763af83 100644 --- a/src/Collections-Strings-Tests/WideStringTest.class.st +++ b/src/Collections-Strings-Tests/WideStringTest.class.st @@ -18,27 +18,6 @@ WideStringTest >> classToBeTested [ ^ WideString ] -{ #category : 'tests - converting' } -WideStringTest >> testAsInteger [ - self assert: '1796exportFixes-tkMX' asWideString asInteger equals: 1796. - self assert: 'donald' asWideString asInteger isNil. - self assert: 'abc234def567' asWideString asInteger equals: 234. - self assert: '-94' asWideString asInteger equals: -94. - self assert: 'foo-bar-92' asWideString asInteger equals: -92. - - self assert: '1796exportFixes-tkMX' asWideString asSignedInteger equals: 1796. - self assert: 'donald' asWideString asSignedInteger isNil. - self assert: 'abc234def567' asWideString asSignedInteger equals: 234. - self assert: '-94' asWideString asSignedInteger equals: -94. - self assert: 'foo-bar-92' asWideString asSignedInteger equals: -92. - - self assert: '1796exportFixes-tkMX' asWideString asUnsignedInteger equals: 1796. - self assert: 'donald' asWideString asUnsignedInteger isNil. - self assert: 'abc234def567' asWideString asUnsignedInteger equals: 234. - self assert: '-94' asWideString asUnsignedInteger equals: 94. - self assert: 'foo-bar-92' asWideString asUnsignedInteger equals: 92 -] - { #category : 'testing' } WideStringTest >> testAtPut [ "Non regression test for http://bugs.squeak.org/view.php?id=6998" diff --git a/src/Collections-Strings/String.class.st b/src/Collections-Strings/String.class.st index c6b84026f8c..39226011323 100644 --- a/src/Collections-Strings/String.class.st +++ b/src/Collections-Strings/String.class.st @@ -696,13 +696,16 @@ String >> asHex [ { #category : 'converting' } String >> asInteger [ - "Return the integer present in the receiver, or nil. In case of float, returns the integer part." + "Return the integer present in the receiver. The receiver has to be a valid integer." + "'1' asInteger >>> 1" "'-1' asInteger >>> -1" "'10' asInteger >>> 10" - "'a' asInteger >>> nil" "'1.234' asInteger >>> 1" - ^self asSignedInteger + + (NumberParser isNumber: self) ifFalse: [ + self error: 'The string ', self surroundedBySingleQuotes , ' is not a valid integer' ]. + ^ NumberParser parse: self ] { #category : 'converting' } @@ -741,19 +744,6 @@ String >> asPluralBasedOn: aNumberOrCollection [ ifFalse: [self, 's'] ] -{ #category : 'converting' } -String >> asSignedInteger [ - "Returns the first signed integer it can find or nil." - - | start stream | - start := self findFirst: [:char | char isDigit]. - start isZero ifTrue: [^ nil]. - stream := self readStream position: start - 1. - ((stream position ~= 0) and: [stream peekBack = $-]) - ifTrue: [stream back]. - ^ Integer readFrom: stream -] - { #category : 'converting' } String >> asString [ "Answer this string." @@ -776,12 +766,9 @@ String >> asTime [ { #category : 'converting' } String >> asUnsignedInteger [ - "Returns the first integer it can find or nil." - | start stream | - start := self findFirst: [ :char | char isDigit ]. - start isZero ifTrue: [ ^ nil ]. - stream := self readStream position: start - 1. - ^ Integer readFrom: stream + + + ^ self asInteger abs ] { #category : 'converting' } @@ -1384,6 +1371,27 @@ String >> expandMacrosWithArguments: anArray [ ifFalse: [ char ]) ] ] ] ] +{ #category : 'converting' } +String >> extractIntegerPart [ + "Returns the first signed integer it can find or nil." + + "'1' extractIntegerPart >>> 1" + "'-1' extractIntegerPart >>> -1" + "'10qwe' extractIntegerPart >>> 10" + "'a10q' extractIntegerPart >>> 10" + "'a10q22' extractIntegerPart >>> 10" + "'1.234' extractIntegerPart >>> 1" + "'a' extractIntegerPart >>> nil" + + | start stream | + start := self findFirst: [ :char | char isDigit ]. + start isZero ifTrue: [ ^ nil ]. + stream := self readStream position: start - 1. + (stream position ~= 0 and: [ stream peekBack = $- ]) ifTrue: [ + stream back ]. + ^ Integer readFrom: stream +] + { #category : 'finding/searching' } String >> findAnySubstring: aCollection startingAt: start [ "Answer the index where an element of aCollection begins. If none are found, answer size + 1. aCollection is an Array of Strings or Characters." diff --git a/src/Deprecated13/String.extension.st b/src/Deprecated13/String.extension.st new file mode 100644 index 00000000000..6d891325d43 --- /dev/null +++ b/src/Deprecated13/String.extension.st @@ -0,0 +1,13 @@ +Extension { #name : 'String' } + +{ #category : '*Deprecated13' } +String >> asSignedInteger [ + "Returns the first signed integer it can find or nil." + + self + deprecated: + 'Use #asInteger to convert to a valid integer. If you want to extract the integer part, use #extractIntegerPart' + transformWith: + '`@receiver asSignedInteger' -> '`@receiver extractIntegerPart'. + ^ self extractIntegerPart +] diff --git a/src/Metacello-Core/MetacelloSemanticVersionNumber.class.st b/src/Metacello-Core/MetacelloSemanticVersionNumber.class.st index 364053f1737..c4143f237a0 100644 --- a/src/Metacello-Core/MetacelloSemanticVersionNumber.class.st +++ b/src/Metacello-Core/MetacelloSemanticVersionNumber.class.st @@ -199,22 +199,18 @@ MetacelloSemanticVersionNumber class >> fromString: aString forPattern: forPatte { #category : 'private' } MetacelloSemanticVersionNumber class >> integerFromString: aString [ - aString - detect: [ :char | char isDigit not ] - ifNone: [ - | integer | - integer := aString asInteger. - ((aString at: 1) = $0 and: [ aString size > 1 ]) - ifTrue: [ - self - error: - 'invalid version number: normal version component must not have leading 0s' - , aString asString ]. - ^ integer ]. - self - error: - 'invalid version number: normal version component must be integer ' - , aString asString + + aString detect: [ :char | char isDigit not ] ifNone: [ + | integer | + integer := aString extractIntegerPart. + ((aString at: 1) = $0 and: [ aString size > 1 ]) ifTrue: [ + self error: + 'invalid version number: normal version component must not have leading 0s' + , aString asString ]. + ^ integer ]. + self error: + 'invalid version number: normal version component must be integer ' + , aString asString ] { #category : 'private' } diff --git a/src/Ombu/OmBlock.class.st b/src/Ombu/OmBlock.class.st index b4a3454abff..95dfd8d3b0d 100644 --- a/src/Ombu/OmBlock.class.st +++ b/src/Ombu/OmBlock.class.st @@ -33,11 +33,11 @@ OmBlock >> atLocalName: aString ifPresent: presentBlockClosure ifAbsent: absentB | index | self checkIfMustRefreshBlock. - index := aString asInteger - self firstLocalNameAsInteger + 1. + index := aString extractIntegerPart - self firstLocalNameAsInteger + 1. ^ index > positions size - ifTrue: [ absentBlockClosure value ] - ifFalse: [presentBlockClosure value: (positions at: index) ] + ifTrue: [ absentBlockClosure value ] + ifFalse: [ presentBlockClosure value: (positions at: index) ] ] { #category : 'refreshing' } @@ -58,7 +58,8 @@ OmBlock >> firstEntryReference [ { #category : 'accessing' } OmBlock >> firstLocalNameAsInteger [ - ^ self firstEntryReference localName asInteger + + ^ self firstEntryReference localName extractIntegerPart ] { #category : 'initialization' } diff --git a/src/Ombu/OmBlockFileStore.class.st b/src/Ombu/OmBlockFileStore.class.st index 1c6c792903d..81502c7dd66 100644 --- a/src/Ombu/OmBlockFileStore.class.st +++ b/src/Ombu/OmBlockFileStore.class.st @@ -52,11 +52,11 @@ OmBlockFileStore >> initialize [ { #category : 'accessing' } OmBlockFileStore >> readEntryForLocalName: aString ifPresent: presentBlockClosure ifAbsent: absentBlockClosure [ - ^ (self blockForLocalNameAsInteger: aString asInteger) - atLocalName: aString - ifPresent: [ :position | - presentBlockClosure value: (self nextEntryFromPosition: position) ] - ifAbsent: absentBlockClosure + ^ (self blockForLocalNameAsInteger: aString extractIntegerPart) + atLocalName: aString + ifPresent: [ :position | + presentBlockClosure value: (self nextEntryFromPosition: position) ] + ifAbsent: absentBlockClosure ] { #category : 'refreshing' } diff --git a/src/Ombu/OmFileStore.class.st b/src/Ombu/OmFileStore.class.st index ff3665590dd..5256fc86674 100644 --- a/src/Ombu/OmFileStore.class.st +++ b/src/Ombu/OmFileStore.class.st @@ -415,16 +415,17 @@ OmFileStore >> refreshEntryPositionsByLocalNameStartingAt: firstStreamPosition s (+ would need special care of WideStrings)" | localNameAsInteger | - localNameAsInteger := initialLocalName asInteger. + localNameAsInteger := initialLocalName extractIntegerPart. - self readEntriesWith: [:readStream | + self readEntriesWith: [ :readStream | readStream position: firstStreamPosition. self newEntryReader stream: readStream; entryPositionsDo: [ :entryPosition | - entryPositionsByLocalName at: localNameAsInteger asString put: entryPosition. - localNameAsInteger := localNameAsInteger + 1 ]. - ] + entryPositionsByLocalName + at: localNameAsInteger asString + put: entryPosition. + localNameAsInteger := localNameAsInteger + 1 ] ] ] { #category : 'accessing' } diff --git a/src/Ombu/OmMemoryStore.class.st b/src/Ombu/OmMemoryStore.class.st index 38a7283ad48..8e3044a1b65 100644 --- a/src/Ombu/OmMemoryStore.class.st +++ b/src/Ombu/OmMemoryStore.class.st @@ -56,12 +56,12 @@ OmMemoryStore >> entriesDo: aBlockClosure [ OmMemoryStore >> entryFor: aReference ifPresent: presentBlockClosure ifAbsent: absentBlockClosure [ | entry | - (aReference isNull or: [ aReference globalName ~= self globalName]) + (aReference isNull or: [ aReference globalName ~= self globalName ]) ifTrue: [ ^ absentBlockClosure value ]. entry := entries - at: aReference localName asInteger - ifAbsent: [ ^ absentBlockClosure value ]. + at: aReference localName extractIntegerPart + ifAbsent: [ ^ absentBlockClosure value ]. ^ presentBlockClosure cull: entry ] diff --git a/src/Reflectivity/Context.extension.st b/src/Reflectivity/Context.extension.st index 039b26089db..fa512c0d827 100644 --- a/src/Reflectivity/Context.extension.st +++ b/src/Reflectivity/Context.extension.st @@ -55,7 +55,7 @@ Context >> currentBytecode: currentBytecode equalsToNewBytecode: newBytecode wit ifFalse: [ false ] ifTrue: [ | currentJumpPc newJumpPc currentJumpBytecode newJumpBytecode | - currentJumpPc := (currentSplitDescription at: 2) asInteger. + currentJumpPc := (currentSplitDescription at: 2) extractIntegerPart. newJumpPc := (newSplitDescription at: 2) asInteger. currentJumpBytecode := currentSymbolicBytecodes detect: [ :csb | diff --git a/src/System-Support/SystemVersion.class.st b/src/System-Support/SystemVersion.class.st index 9b45b3525f2..3fb8f553b65 100644 --- a/src/System-Support/SystemVersion.class.st +++ b/src/System-Support/SystemVersion.class.st @@ -124,7 +124,7 @@ SystemVersion class >> useCurrent: aSystemVersion during: aBlock [ { #category : 'accessing - properties' } SystemVersion >> build [ - ^ build asInteger + ^ build extractIntegerPart ] { #category : 'accessing - properties' } @@ -247,7 +247,7 @@ SystemVersion >> initialize [ SystemVersion >> major [ "Answer the major number of a version. 1 in '1.2'" - ^ major asInteger + ^ major extractIntegerPart ] { #category : 'accessing - properties' } @@ -295,7 +295,7 @@ SystemVersion >> majorMinorVersion [ SystemVersion >> minor [ "Answer the minor number of a version. 2 in '1.2'" - ^ minor asInteger + ^ minor extractIntegerPart ] { #category : 'accessing - properties' } @@ -308,7 +308,7 @@ SystemVersion >> minor: anInteger [ { #category : 'accessing' } SystemVersion >> patch [ - ^ patch asInteger + ^ patch extractIntegerPart ] { #category : 'accessing' } diff --git a/src/System-Time/DateAndTime.class.st b/src/System-Time/DateAndTime.class.st index 90bf41da1aa..c4fbb7355d2 100644 --- a/src/System-Time/DateAndTime.class.st +++ b/src/System-Time/DateAndTime.class.st @@ -165,22 +165,22 @@ DateAndTime class >> fuzzyReadFrom: aStream [ aStream peek = $- ifTrue: [ aStream next. bc := -1] ifFalse: [bc := 1]. - year := (aStream upTo: $-) asInteger * bc. - month := (aStream upTo: $-) asInteger ifNil: [1]. - day := (aStream upTo: $T) asInteger ifNil: [1]. - hour := (aStream upTo: $:) asInteger ifNil: [0]. + year := (aStream upTo: $-) extractIntegerPart * bc. + month := (aStream upTo: $-) extractIntegerPart ifNil: [1]. + day := (aStream upTo: $T) extractIntegerPart ifNil: [1]. + hour := (aStream upTo: $:) extractIntegerPart ifNil: [0]. buffer := '00:' copy. ch := nil. minute := buffer writeStream. [ aStream atEnd | (ch = $:) | (ch = $+) | (ch = $-) ] whileFalse: [ ch := minute nextPut: aStream next. ]. (ch isNil or: [ch isDigit]) ifTrue: [ ch := $: ]. - minute := (buffer readStream upTo: ch) asInteger. + minute := (buffer readStream upTo: ch) extractIntegerPart. buffer := '00.' copy. second := buffer writeStream. [ aStream atEnd | (ch = $.) | (ch = $+) | (ch = $-) ] whileFalse: [ ch := second nextPut: aStream next. ]. (ch isNil or: [ch isDigit]) ifTrue: [ ch := $. ]. - second := (buffer readStream upTo: ch) asInteger. + second := (buffer readStream upTo: ch) extractIntegerPart. buffer := '000000000' copy. (ch = $.) ifTrue: [ nanos := buffer writeStream. @@ -189,7 +189,7 @@ DateAndTime class >> fuzzyReadFrom: aStream [ (ch isNil or: [ch isDigit]) ifTrue: [ ch := $+ ]. ]. - nanos := buffer asInteger. + nanos := buffer extractIntegerPart. aStream atEnd ifTrue: [ offset := Duration zero ] ifFalse: [ch := aStream next. diff --git a/src/System-Time/DateParser.class.st b/src/System-Time/DateParser.class.st index c80b39c1af4..bf9cf2c4a55 100644 --- a/src/System-Time/DateParser.class.st +++ b/src/System-Time/DateParser.class.st @@ -156,7 +156,7 @@ DateParser >> parse: aTimeUnitName [ DateParser >> parse: timeUnitName expectedSize: anInteger [ | extractedString result | extractedString := inputStream next: anInteger. - result := extractedString asInteger. + result := extractedString extractIntegerPart. (result isNil or: [ extractedString size ~= anInteger ]) ifTrue: [ DateError signal: ' Expect a two digit ', timeUnitName, ', got ', extractedString ]. ^ result diff --git a/src/System-Time/Duration.class.st b/src/System-Time/Duration.class.st index aeb778a97ff..0fc7fb9dbf7 100644 --- a/src/System-Time/Duration.class.st +++ b/src/System-Time/Duration.class.st @@ -100,10 +100,10 @@ Duration class >> readFrom: aStream [ | sign days hours minutes seconds nanos nanosBuffer | sign := (aStream peekFor: $-) ifTrue: [-1] ifFalse: [1]. - days := (aStream upTo: $:) asInteger sign: sign. - hours := (aStream upTo: $:) asInteger sign: sign. - minutes := (aStream upTo: $:) asInteger sign: sign. - seconds := (aStream upTo: $.) asInteger sign: sign. + days := (aStream upTo: $:) extractIntegerPart sign: sign. + hours := (aStream upTo: $:) extractIntegerPart sign: sign. + minutes := (aStream upTo: $:) extractIntegerPart sign: sign. + seconds := (aStream upTo: $.) extractIntegerPart sign: sign. nanosBuffer := '000000000' copy. nanos := nanosBuffer writeStream. [aStream atEnd not and: [aStream peek isDigit]] @@ -114,7 +114,7 @@ Duration class >> readFrom: aStream [ hours: hours minutes: minutes seconds: seconds - nanoSeconds: (nanosBuffer asInteger sign: sign) + nanoSeconds: (nanosBuffer extractIntegerPart sign: sign) ] { #category : 'instance creation simple' } diff --git a/src/UnifiedFFI-Tests/FFICalloutMethodBuilderTestRequestor.class.st b/src/UnifiedFFI-Tests/FFICalloutMethodBuilderTestRequestor.class.st index 8aab5acf8db..c966b7a405c 100644 --- a/src/UnifiedFFI-Tests/FFICalloutMethodBuilderTestRequestor.class.st +++ b/src/UnifiedFFI-Tests/FFICalloutMethodBuilderTestRequestor.class.st @@ -16,6 +16,6 @@ FFICalloutMethodBuilderTestRequestor >> loaderFromMethodArgsNamed: argName [ ifTrue: [ ^ FFIMethodArgument new argName: argName; - index: (argName allButFirst: 3) asInteger ]. + index: (argName allButFirst: 3) extractIntegerPart ]. ^ nil ]