[squeak-dev] The Trunk: Collections-nice.151.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Oct 3 19:36:59 UTC 2009


Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.151.mcz

==================== Summary ====================

Name: Collections-nice.151
Author: nice
Time: 3 October 2009, 9:36:34 am
UUID: 1c18912c-877b-4777-b8ad-d6f8a9e27717
Ancestors: Collections-ar.150

Merge patch from http://bugs.squeak.org/view.php?id=6366

Avoid direct use of findSubstring:in:starting:matchTable: and CaseSensitiveOrder / CaseInsensitiveOrder because it does not work with WideString

=============== Diff against Collections-ar.150 ===============

Item was changed:
  ----- Method: String>>findString:startingAt:caseSensitive: (in category 'accessing') -----
+ findString: key startingAt: start caseSensitive: caseSensitive 
+ 	"Answer the index in this String at which the substring key first occurs,
+ 	at or beyond start. The match can be case-sensitive or not. If no match
+ 	is found, zero will be returned."
+ 	
+ 	"IMPLEMENTATION NOTE: do not use CaseSensitiveOrder because it is broken for WideString
+ 	This is a temporary work around until Wide CaseSensitiveOrder search is fixed
+ 	Code should revert to:
- findString: key startingAt: start caseSensitive: caseSensitive
- 	"Answer the index in this String at which the substring key first occurs, at or beyond start.  The match can be case-sensitive or not.  If no match is found, zero will be returned."
- 
  	caseSensitive
+ 		ifTrue: [^ self findSubstring: key in: self startingAt: start matchTable: CaseSensitiveOrder]
+ 		ifFalse: [^ self findSubstring: key in: self startingAt: start matchTable: CaseInsensitiveOrder]"
+ 		
+ 	^caseSensitive
+ 		ifTrue: [
+ 			(self class isBytes and: [key class isBytes])
+ 				ifTrue: [self
+ 						findSubstring: key
+ 						in: self
+ 						startingAt: start
+ 						matchTable: CaseSensitiveOrder]
+ 				ifFalse: [WideString new
+ 						findSubstring: key
+ 						in: self
+ 						startingAt: start
+ 						matchTable: nil]]
+ 		ifFalse: [
+ 			(self class isBytes and: [key class isBytes])
+ 				ifTrue: [self
+ 						findSubstring: key
+ 						in: self
+ 						startingAt: start
+ 						matchTable: CaseInsensitiveOrder]
+ 				ifFalse: [WideString new
+ 						findSubstring: key
+ 						in: self
+ 						startingAt: start
+ 						matchTable: CaseInsensitiveOrder]]!
- 	ifTrue: [^ self findSubstring: key in: self startingAt: start matchTable: CaseSensitiveOrder]
- 	ifFalse: [^ self findSubstring: key in: self startingAt: start matchTable: CaseInsensitiveOrder]!

Item was changed:
  ----- Method: String>>numArgs (in category 'system primitives') -----
  numArgs 
  	"Answer either the number of arguments that the receiver would take if considered a selector.  Answer -1 if it couldn't be a selector.  Note that currently this will answer -1 for anything begining with an uppercase letter even though the system will accept such symbols as selectors.  It is intended mostly for the assistance of spelling correction."
  
  	| firstChar numColons excess start ix |
  	self size = 0 ifTrue: [^ -1].
  	firstChar := self at: 1.
  	(firstChar isLetter or: [firstChar = $:]) ifTrue:
+ 		["Fast reject if any chars are non-alphanumeric
+ 		NOTE: fast only for Byte things - Broken for Wide"
+ 		self class isBytes
+ 			ifTrue: [(self findSubstring: '~' in: self startingAt: 1 matchTable: Tokenish) > 0 ifTrue: [^ -1]]
+ 			ifFalse: [2 to: self size do: [:i | (self at: i) tokenish ifFalse: [^ -1]]].
- 		["Fast reject if any chars are non-alphanumeric"
- 		(self findSubstring: '~' in: self startingAt: 1 matchTable: Tokenish) > 0 ifTrue: [^ -1].
  		"Fast colon count"
  		numColons := 0.  start := 1.
+ 		[(ix := self indexOf: $: startingAt: start) > 0]
- 		[(ix := self findSubstring: ':' in: self startingAt: start matchTable: CaseSensitiveOrder) > 0]
  			whileTrue:
  				[numColons := numColons + 1.
  				start := ix + 1].
  		numColons = 0 ifTrue: [^ 0].
  		firstChar = $:
  			ifTrue: [excess := 2 "Has an initial keyword, as #:if:then:else:"]
  			ifFalse: [excess := 0].
  		self last = $:
  			ifTrue: [^ numColons - excess]
  			ifFalse: [^ numColons - excess - 1 "Has a final keywords as #nextPut::andCR"]].
  	firstChar isSpecial ifTrue:
  		[self size = 1 ifTrue: [^ 1].
  		2 to: self size do: [:i | (self at: i) isSpecial ifFalse: [^ -1]].
  		^ 1].
  	^ -1.!

Item was changed:
  ----- Method: String>>indexOfSubCollection:startingAt:ifAbsent: (in category 'accessing') -----
  indexOfSubCollection: sub startingAt: start ifAbsent: exceptionBlock
  	| index |
+ 	index := self findString: sub startingAt: start.
- 	index := self findSubstring: sub in: self startingAt: start matchTable: CaseSensitiveOrder.
  	index = 0 ifTrue: [^ exceptionBlock value].
  	^ index!

Item was changed:
  ----- Method: String>>findWordStart:startingAt: (in category 'accessing') -----
  findWordStart: key startingAt: start
  	| ind |
  	"HyperCard style searching.  Answer the index in self of the substring key, when that key is preceeded by a separator character.  Must occur at or beyond start.  The match is case-insensitive.  If no match is found, zero will be returned."
  
  	ind := start.
+ 	[ind := self findString: key startingAt: ind caseSensitive: false.
- 	[ind := self findSubstring: key in: self startingAt: ind matchTable: CaseInsensitiveOrder.
  	ind = 0 ifTrue: [^ 0].	"not found"
  	ind = 1 ifTrue: [^ 1].	"First char is the start of a word"
  	(self at: ind-1) isSeparator] whileFalse: [ind := ind + 1].
  	^ ind	"is a word start"!

Item was changed:
  ----- Method: String>>findString:startingAt: (in category 'accessing') -----
  findString: subString startingAt: start 
  	"Answer the index of subString within the receiver, starting at start. If 
  	the receiver does not contain subString, answer 0."
  
+ 	^self findString: subString startingAt: start caseSensitive: true!
- 	^ self findSubstring: subString in: self startingAt: start matchTable: CaseSensitiveOrder!

Item was changed:
  ----- Method: String>>endsWith: (in category 'comparing') -----
  endsWith: suffix
  	"Answer whether the tail end of the receiver is the same as suffix.
  	The comparison is case-sensitive."
+ 	
  	| extra |
  	(extra := self size - suffix size) < 0 ifTrue: [^ false].
+ 	^ (self findString: suffix startingAt: extra + 1) > 0
- 	^ (self findSubstring: suffix in: self startingAt: extra + 1
- 			matchTable: CaseSensitiveOrder) > 0
  "
    'Elvis' endsWith: 'vis'
  "!

Item was changed:
  ----- Method: Symbol class>>selectorsContaining: (in category 'access') -----
  selectorsContaining: aString
  	"Answer a list of selectors that contain aString within them. Case-insensitive.  Does return symbols that begin with a capital letter."
  
  	| size selectorList ascii |
  
  	selectorList := OrderedCollection new.
  	(size := aString size) = 0 ifTrue: [^selectorList].
  
  	aString size = 1 ifTrue:
  		[
  			ascii := aString first asciiValue.
  			ascii < 128 ifTrue: [selectorList add: (OneCharacterSymbols at: ascii+1)]
  		].
  
  	aString first isLetter ifFalse:
  		[
  			aString size == 2 ifTrue: 
  				[Symbol hasInterned: aString ifTrue:
  					[:s | selectorList add: s]].
  			^selectorList
  		].
  
  	selectorList := selectorList copyFrom: 2 to: selectorList size.
  
  	self allSymbolTablesDo: [:each |
  		each size >= size ifTrue:
+ 			[(each findString: aString startingAt: 1 caseSensitive: false) > 0
- 			[(each findSubstring: aString in: each startingAt: 1 
- 				matchTable: CaseInsensitiveOrder) > 0
  						ifTrue: [selectorList add: each]]].
  
  	^selectorList reject: [:each | "reject non-selectors, but keep ones that begin with an uppercase"
  		each numArgs < 0 and: [each asString withFirstCharacterDownshifted numArgs < 0]].
  
  "Symbol selectorsContaining: 'scon'"!

Item was changed:
  ----- Method: String>>findLastOccuranceOfString:startingAt: (in category 'accessing') -----
  findLastOccuranceOfString: subString startingAt: start 
  	"Answer the index of the last occurance of subString within the receiver, starting at start. If 
  	the receiver does not contain subString, answer 0."
  
  	| last now |
+ 	last := self findString: subString startingAt: start.
- 	last := self findSubstring: subString in: self startingAt: start matchTable: CaseSensitiveOrder.
  	last = 0 ifTrue: [^ 0].
  	[last > 0] whileTrue: [
  		now := last.
+ 		last := self findString: subString startingAt: last + 1.
- 		last := self findSubstring: subString in: self startingAt: last + 1 matchTable: CaseSensitiveOrder.
  	].
  
  	^ now.
  !




More information about the Squeak-dev mailing list