CharacterArray.st
changeset 14765 c1769994b460
parent 14681 35b3d29d3b46
child 14768 1da413c31c24
equal deleted inserted replaced
14764:2497dc2ff1ab 14765:c1769994b460
   323    invalid:
   323    invalid:
   324      CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ]
   324      CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ]
   325      CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ]
   325      CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ]
   326     "
   326     "
   327 ! !
   327 ! !
       
   328 
   328 
   329 
   329 !CharacterArray class methodsFor:'pattern matching'!
   330 !CharacterArray class methodsFor:'pattern matching'!
   330 
   331 
   331 matchEscapeCharacter
   332 matchEscapeCharacter
   332     "return the character used to escape a matchCharacter
   333     "return the character used to escape a matchCharacter
   675      Abstract subclasses must redefine again."
   676      Abstract subclasses must redefine again."
   676 
   677 
   677     ^ self == CharacterArray
   678     ^ self == CharacterArray
   678 ! !
   679 ! !
   679 
   680 
       
   681 
   680 !CharacterArray methodsFor:'Compatibility-ANSI'!
   682 !CharacterArray methodsFor:'Compatibility-ANSI'!
   681 
   683 
   682 addLineDelimiters
   684 addLineDelimiters
   683     "Ansi compatibility - same as withCRs"
   685     "Ansi compatibility - same as withCRs"
   684 
   686 
  1570     "added for visual works compatibility"
  1572     "added for visual works compatibility"
  1571     ^ true
  1573     ^ true
  1572 ! !
  1574 ! !
  1573 
  1575 
  1574 
  1576 
       
  1577 
  1575 !CharacterArray methodsFor:'character searching'!
  1578 !CharacterArray methodsFor:'character searching'!
  1576 
  1579 
  1577 includesMatchCharacters
  1580 includesMatchCharacters
  1578     "return true if the receiver includes any GLOB meta-match characters (i.e. $* or $#)
  1581     "return true if the receiver includes any GLOB meta-match characters (i.e. $* or $#)
  1579      for match operations; false if not.
  1582      for match operations; false if not.
  4383 
  4386 
  4384     "Created: / 08-03-2012 / 03:11:11 / cg"
  4387     "Created: / 08-03-2012 / 03:11:11 / cg"
  4385 ! !
  4388 ! !
  4386 
  4389 
  4387 
  4390 
       
  4391 
  4388 !CharacterArray methodsFor:'padded copying'!
  4392 !CharacterArray methodsFor:'padded copying'!
  4389 
  4393 
  4390 centerPaddedTo:newSize
  4394 centerPaddedTo:newSize
  4391      "return a new string consisting of the receivers characters,
  4395      "return a new string consisting of the receivers characters,
  4392      plus spaces up to length and center the receivers characters in
  4396      plus spaces up to length and center the receivers characters in
  4907 
  4911 
  4908     "Created: 12.5.1996 / 20:09:29 / cg"
  4912     "Created: 12.5.1996 / 20:09:29 / cg"
  4909     "Modified: 17.4.1997 / 12:50:23 / cg"
  4913     "Modified: 17.4.1997 / 12:50:23 / cg"
  4910 ! !
  4914 ! !
  4911 
  4915 
       
  4916 
  4912 !CharacterArray methodsFor:'special string converting'!
  4917 !CharacterArray methodsFor:'special string converting'!
       
  4918 
       
  4919 expandPlaceholders:escapeCharacter with:argArrayOrDictionary on:aStream
       
  4920     "this is the generic version of the old %-escaping method, allowing for an arbitrary
       
  4921      escape character to be used (typically $$ or $% are effectively used).
       
  4922      Write the receiver to aStream, where all %i escapes are
       
  4923      replaced by corresponding arguments' printStrings from the argArrayOrDictionary.
       
  4924      I.e. 'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') results
       
  4925      in the new string 'hello world; how is this'.
       
  4926      As an extension, the argument may also be a dictionary, providing
       
  4927      values for symbolic keys.
       
  4928      In this case, %a .. %z and %(...) are also allowed.
       
  4929      (%1..%9 require a numeric key in the dictionary, however)
       
  4930      To get a '%' character, use a '%%'-escape.
       
  4931      To get an integer-indexed placeHolder followed by another digit,
       
  4932      or an index > 9, you must use %(digit).
       
  4933      See also bindWith:... for VisualAge compatibility.
       
  4934      Use %<cr> to insert a CR and %<tab> to insert a TAB."
       
  4935 
       
  4936     |next v key
       
  4937      idx   "{ SmallInteger }"
       
  4938      idx2  "{ SmallInteger }"
       
  4939      start "{ SmallInteger }"
       
  4940      stop  "{ SmallInteger }"|
       
  4941 
       
  4942     stop := self size.
       
  4943     start := 1.
       
  4944     [start <= stop] whileTrue:[
       
  4945         idx := self indexOf:escapeCharacter startingAt:start.
       
  4946         (idx == 0 or:[idx == stop]) ifTrue:[
       
  4947             aStream nextPutAll:self startingAt:start to:stop.
       
  4948             ^ self.
       
  4949         ].
       
  4950         "found an escapeCharacter"
       
  4951         aStream nextPutAll:self startingAt:start to:(idx - 1).
       
  4952         next := self at:(idx + 1).
       
  4953         (next == escapeCharacter) ifTrue:[
       
  4954             aStream nextPut:escapeCharacter.
       
  4955         ] ifFalse:[
       
  4956             next == $< ifTrue:[
       
  4957                 idx2 := self indexOf:$> startingAt:idx+2.
       
  4958                 key := self copyFrom:idx+2 to:idx2-1.
       
  4959                 idx := idx2 - 1.
       
  4960                 key := key asSymbolIfInterned.
       
  4961                 (#(cr tab nl return lf ff null) includesIdentical:key) ifTrue:[
       
  4962                     aStream nextPut:(Character perform:key).
       
  4963                 ].
       
  4964             ] ifFalse:[
       
  4965                 next isDigit ifTrue:[
       
  4966                     v := argArrayOrDictionary at:(next digitValue) ifAbsent:''
       
  4967                 ] ifFalse:[
       
  4968                     next == $( ifTrue:[
       
  4969                         idx2 := self indexOf:$) startingAt:idx+2.
       
  4970                         key := self copyFrom:idx+2 to:idx2-1.
       
  4971                         idx := idx2 - 1.
       
  4972                         (argArrayOrDictionary includesKey:key) ifTrue:[
       
  4973                             v := argArrayOrDictionary at:key
       
  4974                         ] ifFalse:[
       
  4975                             key := key asSymbolIfInterned ? key.
       
  4976                             (argArrayOrDictionary includesKey:key) ifTrue:[
       
  4977                                 v := argArrayOrDictionary at:key
       
  4978                             ] ifFalse:[
       
  4979                                 (key size == 1 and:[ argArrayOrDictionary includesKey:(key at:1)]) ifTrue:[
       
  4980                                     v := argArrayOrDictionary at:(key at:1)
       
  4981                                 ] ifFalse:[
       
  4982                                     key isNumeric ifTrue:[
       
  4983                                         key := Integer readFrom:key onError:nil.
       
  4984                                     ].
       
  4985                                     v := argArrayOrDictionary at:key ifAbsent:''
       
  4986                                 ]
       
  4987                             ].
       
  4988                         ].
       
  4989                     ] ifFalse:[
       
  4990                         (next isLetter and:[argArrayOrDictionary isSequenceable not "is a Dictionary"]) ifTrue:[
       
  4991                             "so next is a non-numeric single character."
       
  4992                             v := argArrayOrDictionary
       
  4993                                     at:next
       
  4994                                     ifAbsent:[
       
  4995                                         "try symbol instead of character"
       
  4996                                         argArrayOrDictionary
       
  4997                                             at:next asSymbol
       
  4998                                             ifAbsent:[String with:escapeCharacter with:next].
       
  4999                                  ].
       
  5000                         ] ifFalse:[
       
  5001                             v := String with:$% with:next.
       
  5002                         ].
       
  5003                     ]
       
  5004                 ].
       
  5005                 "/ v notNil ifTrue:[
       
  5006                     v isBlock ifTrue:[
       
  5007                         v := v value
       
  5008                     ].
       
  5009 
       
  5010                     v printOn:aStream.
       
  5011                 "/ ].
       
  5012             ]
       
  5013         ].
       
  5014         start := idx + 2
       
  5015     ].
       
  5016 
       
  5017     "
       
  5018      String streamContents:[:s|
       
  5019         'hello %1' expandPlaceholders:$% with:#('world') on:s.
       
  5020         s cr.
       
  5021         'hello $1; how is $2' expandPlaceholders:$$ with:#('world' 'this') on:s.
       
  5022         s cr.
       
  5023         'hello %2; how is %1' expandPlaceholders:$% with:#('world' 'this') on:s.
       
  5024         s cr.
       
  5025         '%1 plus %2 gives %3 ' expandPlaceholders:$% with:#(4 5 9) on:s.
       
  5026         s cr.
       
  5027         '%%(1)0 gives %(1)0' expandPlaceholders:$% with:#(123) on:s.
       
  5028         s cr.
       
  5029         '%%10 gives %10' expandPlaceholders:$% with:#(123) on:s.
       
  5030         s cr.
       
  5031         '%%(10) gives %(10) %<cr>%<tab>next line' expandPlaceholders:$% with:#(123) on:s.
       
  5032         s cr.
       
  5033         '%test gives %1' expandPlaceholders:$% with:#(123) on:s.
       
  5034      ]  
       
  5035     "
       
  5036 
       
  5037     "
       
  5038      |dict|
       
  5039 
       
  5040      dict := Dictionary new.
       
  5041      dict at:1 put:'one'.
       
  5042      dict at:$a put:'AAAAA'.
       
  5043      dict at:$b put:[ Time now ].
       
  5044      String streamContents:[:s|
       
  5045          'hello $1 $a $b' expandPlaceholders:$$ with:dict on:s.
       
  5046      ].
       
  5047     "
       
  5048 
       
  5049     "Modified: / 18-11-2010 / 15:43:28 / cg"
       
  5050 !
  4913 
  5051 
  4914 expandPlaceholdersWith:argArrayOrDictionary
  5052 expandPlaceholdersWith:argArrayOrDictionary
  4915     "return a copy of the receiver, where all %i escapes are
  5053     "return a copy of the receiver, where all %i escapes are
  4916      replaced by corresponding arguments' printStrings from the argArrayOrDictionary.
  5054      replaced by corresponding arguments' printStrings from the argArrayOrDictionary.
  4917      I.e. 'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') results
  5055      I.e. 'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') results
  4972      To get an integer-indexed placeHolder followed by another digit,
  5110      To get an integer-indexed placeHolder followed by another digit,
  4973      or an index > 9, you must use %(digit).
  5111      or an index > 9, you must use %(digit).
  4974      See also bindWith:... for VisualAge compatibility.
  5112      See also bindWith:... for VisualAge compatibility.
  4975      Use %<cr> to insert a CR and %<tab> to insert a TAB."
  5113      Use %<cr> to insert a CR and %<tab> to insert a TAB."
  4976 
  5114 
  4977     |next v key
  5115     ^ self expandPlaceholders:$% with:argArrayOrDictionary on:aStream
  4978      idx   "{ SmallInteger }"
       
  4979      idx2  "{ SmallInteger }"
       
  4980      start "{ SmallInteger }"
       
  4981      stop  "{ SmallInteger }"|
       
  4982 
       
  4983     stop := self size.
       
  4984     start := 1.
       
  4985     [start <= stop] whileTrue:[
       
  4986 	idx := self indexOf:$% startingAt:start.
       
  4987 	(idx == 0 or:[idx == stop]) ifTrue:[
       
  4988 	    aStream nextPutAll:self startingAt:start to:stop.
       
  4989 	    ^ self.
       
  4990 	].
       
  4991 	"found a %"
       
  4992 	aStream nextPutAll:self startingAt:start to:(idx - 1).
       
  4993 	next := self at:(idx + 1).
       
  4994 	(next == $%) ifTrue:[
       
  4995 	    aStream nextPut:$%.
       
  4996 	] ifFalse:[
       
  4997 	    next == $< ifTrue:[
       
  4998 		idx2 := self indexOf:$> startingAt:idx+2.
       
  4999 		key := self copyFrom:idx+2 to:idx2-1.
       
  5000 		idx := idx2 - 1.
       
  5001 		key := key asSymbolIfInterned.
       
  5002 		(#(cr tab nl return lf ff null) includesIdentical:key) ifTrue:[
       
  5003 		    aStream nextPut:(Character perform:key).
       
  5004 		].
       
  5005 	    ] ifFalse:[
       
  5006 		next isDigit ifTrue:[
       
  5007 		    v := argArrayOrDictionary at:(next digitValue) ifAbsent:''
       
  5008 		] ifFalse:[
       
  5009 		    next == $( ifTrue:[
       
  5010 			idx2 := self indexOf:$) startingAt:idx+2.
       
  5011 			key := self copyFrom:idx+2 to:idx2-1.
       
  5012 			idx := idx2 - 1.
       
  5013 			(argArrayOrDictionary includesKey:key) ifTrue:[
       
  5014 			    v := argArrayOrDictionary at:key
       
  5015 			] ifFalse:[
       
  5016 			    key := key asSymbolIfInterned ? key.
       
  5017 			    (argArrayOrDictionary includesKey:key) ifTrue:[
       
  5018 				v := argArrayOrDictionary at:key
       
  5019 			    ] ifFalse:[
       
  5020 				(key size == 1 and:[ argArrayOrDictionary includesKey:(key at:1)]) ifTrue:[
       
  5021 				    v := argArrayOrDictionary at:(key at:1)
       
  5022 				] ifFalse:[
       
  5023 				    key isNumeric ifTrue:[
       
  5024 					key := Integer readFrom:key onError:nil.
       
  5025 				    ].
       
  5026 				    v := argArrayOrDictionary at:key ifAbsent:''
       
  5027 				]
       
  5028 			    ].
       
  5029 			].
       
  5030 		    ] ifFalse:[
       
  5031 			(next isLetter and:[argArrayOrDictionary isSequenceable not "is a Dictionary"]) ifTrue:[
       
  5032 			    "so next is a non-numeric single character."
       
  5033 			    v := argArrayOrDictionary
       
  5034 				    at:next
       
  5035 				    ifAbsent:[
       
  5036 					"try symbol instead of character"
       
  5037 					argArrayOrDictionary
       
  5038 					    at:next asSymbol
       
  5039 					    ifAbsent:[String with:$% with:next].
       
  5040 				 ].
       
  5041 			] ifFalse:[
       
  5042 			    v := String with:$% with:next.
       
  5043 			].
       
  5044 		    ]
       
  5045 		].
       
  5046 		"/ v notNil ifTrue:[
       
  5047 		    v isBlock ifTrue:[
       
  5048 			v := v value
       
  5049 		    ].
       
  5050 
       
  5051 		    v printOn:aStream.
       
  5052 		"/ ].
       
  5053 	    ]
       
  5054 	].
       
  5055 	start := idx + 2
       
  5056     ].
       
  5057 
  5116 
  5058     "
  5117     "
  5059      String streamContents:[:s|
  5118      String streamContents:[:s|
  5060 	'hello %1' expandPlaceholdersWith:#('world') on:s.
  5119         'hello %1' expandPlaceholdersWith:#('world') on:s.
  5061 	s cr.
  5120         s cr.
  5062 	'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') on:s.
  5121         'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') on:s.
  5063 	s cr.
  5122         s cr.
  5064 	'hello %2; how is %1' expandPlaceholdersWith:#('world' 'this') on:s.
  5123         'hello %2; how is %1' expandPlaceholdersWith:#('world' 'this') on:s.
  5065 	s cr.
  5124         s cr.
  5066 	'%1 plus %2 gives %3 ' expandPlaceholdersWith:#(4 5 9) on:s.
  5125         '%1 plus %2 gives %3 ' expandPlaceholdersWith:#(4 5 9) on:s.
  5067 	s cr.
  5126         s cr.
  5068 	'%%(1)0 gives %(1)0' expandPlaceholdersWith:#(123) on:s.
  5127         '%%(1)0 gives %(1)0' expandPlaceholdersWith:#(123) on:s.
  5069 	s cr.
  5128         s cr.
  5070 	'%%10 gives %10' expandPlaceholdersWith:#(123) on:s.
  5129         '%%10 gives %10' expandPlaceholdersWith:#(123) on:s.
  5071 	s cr.
  5130         s cr.
  5072 	'%%(10) gives %(10) %<cr>%<tab>next line' expandPlaceholdersWith:#(123) on:s.
  5131         '%%(10) gives %(10) %<cr>%<tab>next line' expandPlaceholdersWith:#(123) on:s.
  5073 	s cr.
  5132         s cr.
  5074 	'%test gives %1' expandPlaceholdersWith:#(123) on:s.
  5133         '%test gives %1' expandPlaceholdersWith:#(123) on:s.
  5075      ]
  5134      ]
  5076     "
  5135     "
  5077 
  5136 
  5078     "
  5137     "
  5079      |dict|
  5138      |dict|
  5081      dict := Dictionary new.
  5140      dict := Dictionary new.
  5082      dict at:1 put:'one'.
  5141      dict at:1 put:'one'.
  5083      dict at:$a put:'AAAAA'.
  5142      dict at:$a put:'AAAAA'.
  5084      dict at:$b put:[ Time now ].
  5143      dict at:$b put:[ Time now ].
  5085      String streamContents:[:s|
  5144      String streamContents:[:s|
  5086 	 'hello %1 %a %b' expandPlaceholdersWith:dict on:s.
  5145          'hello %1 %a %b' expandPlaceholdersWith:dict on:s.
  5087      ].
  5146      ].
  5088     "
  5147     "
  5089 
  5148 
  5090     "Modified: / 18-11-2010 / 15:43:28 / cg"
  5149     "Modified: / 18-11-2010 / 15:43:28 / cg"
  5091 !
  5150 !
  5711      ('  ' , Character tab asString , ' foo   ') withoutTrailingSeparators inspect
  5770      ('  ' , Character tab asString , ' foo   ') withoutTrailingSeparators inspect
  5712      ('   foo' , Character tab asString) withoutTrailingSeparators inspect
  5771      ('   foo' , Character tab asString) withoutTrailingSeparators inspect
  5713     "
  5772     "
  5714 ! !
  5773 ! !
  5715 
  5774 
       
  5775 
  5716 !CharacterArray methodsFor:'substring searching'!
  5776 !CharacterArray methodsFor:'substring searching'!
  5717 
  5777 
  5718 findString:subString
  5778 findString:subString
  5719     "find a substring. if found, return the index;
  5779     "find a substring. if found, return the index;
  5720      if not found, return 0."
  5780      if not found, return 0."
  6202 ! !
  6262 ! !
  6203 
  6263 
  6204 !CharacterArray class methodsFor:'documentation'!
  6264 !CharacterArray class methodsFor:'documentation'!
  6205 
  6265 
  6206 version
  6266 version
  6207     ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.492 2013-01-22 14:11:02 cg Exp $'
  6267     ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.493 2013-02-08 09:51:37 cg Exp $'
  6208 !
  6268 !
  6209 
  6269 
  6210 version_CVS
  6270 version_CVS
  6211     ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.492 2013-01-22 14:11:02 cg Exp $'
  6271     ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.493 2013-02-08 09:51:37 cg Exp $'
  6212 ! !
  6272 ! !
  6213 
  6273 
  6214 
  6274 
  6215 CharacterArray initialize!
  6275 CharacterArray initialize!