changeset 8874 | f1fdda306d51 |
parent 8862 | 6f550a144c6a |
child 8875 | 1d326cc89ff9 |
8873:eecab5af2679 | 8874:f1fdda306d51 |
---|---|
39 documentation |
39 documentation |
40 " |
40 " |
41 CharacterArray is a superclass for all kinds of Strings (i.e. |
41 CharacterArray is a superclass for all kinds of Strings (i.e. |
42 (singleByte-)Strings, TwoByteStrings and whatever comes in the future. |
42 (singleByte-)Strings, TwoByteStrings and whatever comes in the future. |
43 |
43 |
44 This class is abstract, meaning that there are no instances of it. |
44 This class is abstract, meaning that there are no instances of it. |
45 All this class does is provide common protocol for concrete subclasses. |
45 All this class does is provide common protocol for concrete subclasses. |
46 |
46 |
47 [author:] |
47 [author:] |
48 Claus Gittinger |
48 Claus Gittinger |
49 |
49 |
50 [see also:] |
50 [see also:] |
51 String TwoByteString |
51 String TwoByteString |
52 StringCollection |
52 StringCollection |
53 " |
53 " |
54 ! ! |
54 ! ! |
55 |
55 |
56 !CharacterArray class methodsFor:'initialization'! |
56 !CharacterArray class methodsFor:'initialization'! |
57 |
57 |
58 initialize |
58 initialize |
59 DecodingFailedSignal isNil ifTrue:[ |
59 DecodingFailedSignal isNil ifTrue:[ |
60 DecodingFailedSignal := DecodingError. |
60 DecodingFailedSignal := DecodingError. |
61 DecodingFailedSignal notifierString:'error during decode'. |
61 DecodingFailedSignal notifierString:'error during decode'. |
62 |
62 |
63 EncodingFailedSignal :=EncodingError. |
63 EncodingFailedSignal :=EncodingError. |
64 EncodingFailedSignal notifierString:'error during encode'. |
64 EncodingFailedSignal notifierString:'error during encode'. |
65 ] |
65 ] |
66 |
66 |
67 " |
67 " |
68 CharacterArray initialize |
68 CharacterArray initialize |
69 " |
69 " |
87 |mySize nBytes newString dstIdx| |
87 |mySize nBytes newString dstIdx| |
88 |
88 |
89 nBytes := aByteCollection size. |
89 nBytes := aByteCollection size. |
90 mySize := self basicNew bitsPerCharacter. |
90 mySize := self basicNew bitsPerCharacter. |
91 mySize == 16 ifTrue:[ |
91 mySize == 16 ifTrue:[ |
92 newString := self basicNew:(nBytes // 2). |
92 newString := self basicNew:(nBytes // 2). |
93 dstIdx := 1. |
93 dstIdx := 1. |
94 aByteCollection pairWiseDo:[:hi :lo | |
94 aByteCollection pairWiseDo:[:hi :lo | |
95 newString at:dstIdx put:(Character value:(hi bitShift:8)+lo). |
95 newString at:dstIdx put:(Character value:(hi bitShift:8)+lo). |
96 dstIdx := dstIdx + 1 |
96 dstIdx := dstIdx + 1 |
97 ]. |
97 ]. |
98 ^ newString. |
98 ^ newString. |
99 ]. |
99 ]. |
100 |
100 |
101 ^ (self basicNew:nBytes) replaceFrom:1 with:aByteCollection |
101 ^ (self basicNew:nBytes) replaceFrom:1 with:aByteCollection |
102 |
102 |
103 " |
103 " |
132 |
132 |
133 |newString first| |
133 |newString first| |
134 |
134 |
135 newString := ''. |
135 newString := ''. |
136 first := true. |
136 first := true. |
137 aCollectionOfStrings do:[:s | |
137 aCollectionOfStrings do:[:s | |
138 first ifFalse:[ |
138 first ifFalse:[ |
139 newString := newString , aSeparatorString |
139 newString := newString , aSeparatorString |
140 ] ifTrue:[ |
140 ] ifTrue:[ |
141 first := false |
141 first := false |
142 ]. |
142 ]. |
159 This only handles up-to 16bit characters" |
159 This only handles up-to 16bit characters" |
160 |
160 |
161 ^ self decodeFromUTF8:aByteCollection. |
161 ^ self decodeFromUTF8:aByteCollection. |
162 |
162 |
163 " |
163 " |
164 CharacterArray fromUTF8Bytes:#[ 16r41 16r42 ] |
164 CharacterArray fromUTF8Bytes:#[ 16r41 16r42 ] |
165 CharacterArray fromUTF8Bytes:#[ 16rC1 16r02 ] |
165 CharacterArray fromUTF8Bytes:#[ 16rC1 16r02 ] |
166 CharacterArray fromUTF8Bytes:#[ 16rE0 16r81 16r02 ] |
166 CharacterArray fromUTF8Bytes:#[ 16rE0 16r81 16r02 ] |
167 CharacterArray fromUTF8Bytes:#[ 16rEF 16rBF 16rBF ] |
167 CharacterArray fromUTF8Bytes:#[ 16rEF 16rBF 16rBF ] |
168 |
168 |
169 rfc2279 examples: |
169 rfc2279 examples: |
170 CharacterArray fromUTF8Bytes:#[ 16r41 16rE2 16r89 16rA2 16rCE 16r91 16r2E ] |
170 CharacterArray fromUTF8Bytes:#[ 16r41 16rE2 16r89 16rA2 16rCE 16r91 16r2E ] |
171 CharacterArray fromUTF8Bytes:#[ 16rED 16r95 16r9C 16rEA 16rB5 16rAD 16rEC 16r96 16rB4 ] |
171 CharacterArray fromUTF8Bytes:#[ 16rED 16r95 16r9C 16rEA 16rB5 16rAD 16rEC 16r96 16rB4 ] |
172 CharacterArray fromUTF8Bytes:#[ 16rE6 16r97 16rA5 16rE6 16r9C 16rAC 16rE8 16rAA 16r9E ] |
172 CharacterArray fromUTF8Bytes:#[ 16rE6 16r97 16rA5 16rE6 16r9C 16rAC 16rE8 16rAA 16r9E ] |
173 |
173 |
174 invalid: |
174 invalid: |
175 CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ] |
175 CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ] |
176 CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ] |
176 CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ] |
177 " |
177 " |
178 ! |
178 ! |
179 |
179 |
180 new |
180 new |
181 "return a new empty string" |
181 "return a new empty string" |
232 This only handles up-to 16bit characters." |
232 This only handles up-to 16bit characters." |
233 |
233 |
234 ^ CharacterEncoderImplementations::ISO10646_to_UTF8 decodeString:aStringOrByteCollection |
234 ^ CharacterEncoderImplementations::ISO10646_to_UTF8 decodeString:aStringOrByteCollection |
235 |
235 |
236 " |
236 " |
237 CharacterArray fromUTF8Bytes:#[ 16r41 16r42 ] |
237 CharacterArray fromUTF8Bytes:#[ 16r41 16r42 ] |
238 CharacterArray fromUTF8Bytes:#[ 16rC1 16r02 ] |
238 CharacterArray fromUTF8Bytes:#[ 16rC1 16r02 ] |
239 CharacterArray fromUTF8Bytes:#[ 16rE0 16r81 16r02 ] |
239 CharacterArray fromUTF8Bytes:#[ 16rE0 16r81 16r02 ] |
240 CharacterArray fromUTF8Bytes:#[ 16rEF 16rBF 16rBF ] |
240 CharacterArray fromUTF8Bytes:#[ 16rEF 16rBF 16rBF ] |
241 |
241 |
242 rfc2279 examples: |
242 rfc2279 examples: |
243 CharacterArray fromUTF8Bytes:#[ 16r41 16rE2 16r89 16rA2 16rCE 16r91 16r2E ] |
243 CharacterArray fromUTF8Bytes:#[ 16r41 16rE2 16r89 16rA2 16rCE 16r91 16r2E ] |
244 CharacterArray fromUTF8Bytes:#[ 16rED 16r95 16r9C 16rEA 16rB5 16rAD 16rEC 16r96 16rB4 ] |
244 CharacterArray fromUTF8Bytes:#[ 16rED 16r95 16r9C 16rEA 16rB5 16rAD 16rEC 16r96 16rB4 ] |
245 CharacterArray fromUTF8Bytes:#[ 16rE6 16r97 16rA5 16rE6 16r9C 16rAC 16rE8 16rAA 16r9E ] |
245 CharacterArray fromUTF8Bytes:#[ 16rE6 16r97 16rA5 16rE6 16r9C 16rAC 16rE8 16rAA 16r9E ] |
246 |
246 |
247 invalid: |
247 invalid: |
248 CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ] |
248 CharacterArray fromUTF8Bytes:#[ 16rC0 16r80 ] |
249 CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ] |
249 CharacterArray fromUTF8Bytes:#[ 16rE0 16r80 16r80 ] |
250 " |
250 " |
251 ! ! |
251 ! ! |
252 |
252 |
253 !CharacterArray class methodsFor:'pattern matching'! |
253 !CharacterArray class methodsFor:'pattern matching'! |
254 |
254 |
262 matchScan:matchScanArray from:matchStart to:matchStop with:aString from:start to:stop ignoreCase:ignoreCase |
262 matchScan:matchScanArray from:matchStart to:matchStop with:aString from:start to:stop ignoreCase:ignoreCase |
263 "helper for match; return true if the characters from start to stop in |
263 "helper for match; return true if the characters from start to stop in |
264 aString are matching the scan in matchScan from matchStart to matchStop. |
264 aString are matching the scan in matchScan from matchStart to matchStop. |
265 The matchScan is as created by asMatchScanArray. |
265 The matchScan is as created by asMatchScanArray. |
266 |
266 |
267 This algorithm is not at all the most efficient; |
267 This algorithm is not at all the most efficient; |
268 for heavy duty pattern matching, an interface (primitive) to the regex |
268 for heavy duty pattern matching, an interface (primitive) to the regex |
269 pattern matching package should be added." |
269 pattern matching package should be added." |
270 |
270 |
271 |matchEntry |
271 |matchEntry |
272 mStart "{ Class: SmallInteger }" |
272 mStart "{ Class: SmallInteger }" |
273 mStop "{ Class: SmallInteger }" |
273 mStop "{ Class: SmallInteger }" |
274 sStart "{ Class: SmallInteger }" |
274 sStart "{ Class: SmallInteger }" |
275 sStop "{ Class: SmallInteger }" |
275 sStop "{ Class: SmallInteger }" |
276 mSize "{ Class: SmallInteger }" |
276 mSize "{ Class: SmallInteger }" |
283 mStop := matchStop. |
283 mStop := matchStop. |
284 sStart := start. |
284 sStart := start. |
285 sStop := stop. |
285 sStop := stop. |
286 |
286 |
287 [true] whileTrue:[ |
287 [true] whileTrue:[ |
288 "/ Transcript showCR:('match: ''' , (aString copyFrom:sStart to:sStop) , |
288 "/ Transcript showCR:('match: ''' , (aString copyFrom:sStart to:sStop) , |
289 "/ ''' against:' , (matchScanArray copyFrom:mStart to:mStop) printString). |
289 "/ ''' against:' , (matchScanArray copyFrom:mStart to:mStop) printString). |
290 |
290 |
291 mSize := mStop - mStart + 1. |
291 mSize := mStop - mStart + 1. |
292 sSize := sStop - sStart + 1. |
292 sSize := sStop - sStart + 1. |
293 |
293 |
294 "empty strings match" |
294 "empty strings match" |
295 (mSize == 0) ifTrue:[^ (sSize == 0)]. |
295 (mSize == 0) ifTrue:[^ (sSize == 0)]. |
296 |
296 |
297 matchEntry := matchScanArray at:mStart. |
297 matchEntry := matchScanArray at:mStart. |
298 |
298 |
299 "/ the most common case first: |
299 "/ the most common case first: |
300 (sSize ~~ 0 |
300 (sSize ~~ 0 |
301 and:[(checkChar := (aString at:sStart)) = matchEntry]) ifTrue:[ |
301 and:[(checkChar := (aString at:sStart)) = matchEntry]) ifTrue:[ |
302 "advance by one and continue" |
302 "advance by one and continue" |
303 mStart := mStart + 1. |
303 mStart := mStart + 1. |
304 sStart := sStart + 1 |
304 sStart := sStart + 1 |
305 ] ifFalse:[ |
305 ] ifFalse:[ |
306 (matchEntry == #any) ifTrue:[ |
306 (matchEntry == #any) ifTrue:[ |
307 "restString empty -> no match" |
307 "restString empty -> no match" |
308 (sSize == 0) ifTrue:[^ false]. |
308 (sSize == 0) ifTrue:[^ false]. |
309 "# matches single character" |
309 "# matches single character" |
310 ((sSize == 1) and:[mSize == 1]) ifTrue:[^ true]. |
310 ((sSize == 1) and:[mSize == 1]) ifTrue:[^ true]. |
311 "advance by one and continue" |
311 "advance by one and continue" |
312 mStart := mStart + 1. |
312 mStart := mStart + 1. |
313 sStart := sStart + 1 |
313 sStart := sStart + 1 |
314 ] ifFalse:[ |
314 ] ifFalse:[ |
315 (matchEntry == #anyString) ifTrue:[ |
315 (matchEntry == #anyString) ifTrue:[ |
316 "* alone matches anything" |
316 "* alone matches anything" |
317 (mSize == 1) ifTrue:[^ true]. |
317 (mSize == 1) ifTrue:[^ true]. |
318 "restString empty & matchString not empty -> no match" |
318 "restString empty & matchString not empty -> no match" |
319 (sSize == 0) ifTrue:[^ false]. |
319 (sSize == 0) ifTrue:[^ false]. |
320 |
320 |
321 " |
321 " |
322 try to avoid some of the recursion by checking last |
322 try to avoid some of the recursion by checking last |
323 character and continue with shortened strings if possible |
323 character and continue with shortened strings if possible |
324 " |
324 " |
325 quickCheck := false. |
325 quickCheck := false. |
326 (mStop >= mStart) ifTrue:[ |
326 (mStop >= mStart) ifTrue:[ |
327 matchLast := matchScanArray at:mStop. |
327 matchLast := matchScanArray at:mStop. |
328 (matchLast ~~ #anyString) ifTrue:[ |
328 (matchLast ~~ #anyString) ifTrue:[ |
329 (matchLast == #any) ifTrue:[ |
329 (matchLast == #any) ifTrue:[ |
330 quickCheck := true |
330 quickCheck := true |
331 ] ifFalse:[ |
331 ] ifFalse:[ |
332 matchLast == (aString at:sStop) ifTrue:[ |
332 matchLast == (aString at:sStop) ifTrue:[ |
333 quickCheck := true |
333 quickCheck := true |
334 ] ifFalse:[ |
334 ] ifFalse:[ |
335 matchLast isString ifTrue:[ |
335 matchLast isString ifTrue:[ |
336 quickCheck := matchLast includes:(aString at:sStop) |
336 quickCheck := matchLast includes:(aString at:sStop) |
337 ] |
337 ] |
338 ] |
338 ] |
339 ] |
339 ] |
340 ] |
340 ] |
341 ]. |
341 ]. |
342 quickCheck ifTrue:[ |
342 quickCheck ifTrue:[ |
343 " |
343 " |
344 quickCheck ok, advance from the right |
344 quickCheck ok, advance from the right |
345 " |
345 " |
346 mStop := mStop - 1. |
346 mStop := mStop - 1. |
347 sStop := sStop - 1 |
347 sStop := sStop - 1 |
348 ] ifFalse:[ |
348 ] ifFalse:[ |
349 "/ no quick check; |
349 "/ no quick check; |
350 "/ look for the next character(s) |
350 "/ look for the next character(s) |
351 "/ and try matching there |
351 "/ and try matching there |
352 "/ (to avoid recursion) |
352 "/ (to avoid recursion) |
353 |
353 |
354 mStart < mStop ifTrue:[ |
354 mStart < mStop ifTrue:[ |
355 nextMatchEntry := matchScanArray at:mStart+1. |
355 nextMatchEntry := matchScanArray at:mStart+1. |
356 nextMatchEntry isCharacter ifTrue:[ |
356 nextMatchEntry isCharacter ifTrue:[ |
357 sStart <= sStop ifTrue:[ |
357 sStart <= sStop ifTrue:[ |
358 [true] whileTrue:[ |
358 [true] whileTrue:[ |
359 ignoreCase ifFalse:[ |
359 ignoreCase ifFalse:[ |
360 index := aString indexOf:nextMatchEntry startingAt:sStart |
360 index := aString indexOf:nextMatchEntry startingAt:sStart |
361 ] ifTrue:[ |
361 ] ifTrue:[ |
362 index := aString findFirst:[:c | c asLowercase = nextMatchEntry asLowercase] |
362 index := aString findFirst:[:c | c asLowercase = nextMatchEntry asLowercase] |
363 startingAt:sStart. |
363 startingAt:sStart. |
364 ]. |
364 ]. |
365 (index == 0 or:[index > sStop]) ifTrue:[ |
365 (index == 0 or:[index > sStop]) ifTrue:[ |
366 ^ false |
366 ^ false |
367 ]. |
367 ]. |
368 (self matchScan:matchScanArray |
368 (self matchScan:matchScanArray |
369 from:(mStart + 1) |
369 from:(mStart + 1) |
370 to:mStop |
370 to:mStop |
371 with:aString |
371 with:aString |
372 from:index |
372 from:index |
373 to:sStop |
373 to:sStop |
374 ignoreCase:ignoreCase |
374 ignoreCase:ignoreCase |
375 ) ifTrue:[ |
375 ) ifTrue:[ |
376 ^ true |
376 ^ true |
377 ]. |
377 ]. |
378 sStart := index + 1. |
378 sStart := index + 1. |
379 ] |
379 ] |
380 ] |
380 ] |
381 ] |
381 ] |
382 ]. |
382 ]. |
383 |
383 |
384 " |
384 " |
385 no quick check possible; |
385 no quick check possible; |
386 loop over all possible substrings |
386 loop over all possible substrings |
387 " |
387 " |
388 index := sStart. |
388 index := sStart. |
389 [index <= sStop] whileTrue:[ |
389 [index <= sStop] whileTrue:[ |
390 (self matchScan:matchScanArray |
390 (self matchScan:matchScanArray |
391 from:(mStart + 1) |
391 from:(mStart + 1) |
392 to:mStop |
392 to:mStop |
393 with:aString |
393 with:aString |
394 from:index |
394 from:index |
395 to:sStop |
395 to:sStop |
396 ignoreCase:ignoreCase |
396 ignoreCase:ignoreCase |
397 ) ifTrue:[ |
397 ) ifTrue:[ |
398 ^ true |
398 ^ true |
399 ]. |
399 ]. |
400 index := index + 1 |
400 index := index + 1 |
401 ]. |
401 ]. |
402 ^ false |
402 ^ false |
403 ]. |
403 ]. |
404 ] ifFalse:[ |
404 ] ifFalse:[ |
405 (matchEntry isString) ifTrue:[ |
405 (matchEntry isString) ifTrue:[ |
406 "testString empty -> no match" |
406 "testString empty -> no match" |
407 (sSize == 0) ifTrue:[^ false]. |
407 (sSize == 0) ifTrue:[^ false]. |
408 |
408 |
409 included := false. |
409 included := false. |
410 "/ checkChar := aString at:sStart. |
410 "/ checkChar := aString at:sStart. |
411 included := matchEntry includes:checkChar. |
411 included := matchEntry includes:checkChar. |
412 included ifFalse:[ |
412 included ifFalse:[ |
413 ignoreCase ifTrue:[ |
413 ignoreCase ifTrue:[ |
414 checkChar isUppercase ifTrue:[ |
414 checkChar isUppercase ifTrue:[ |
415 included := matchEntry includes:checkChar asLowercase. |
415 included := matchEntry includes:checkChar asLowercase. |
416 ] ifFalse:[ |
416 ] ifFalse:[ |
417 included := matchEntry includes:checkChar asUppercase. |
417 included := matchEntry includes:checkChar asUppercase. |
418 ] |
418 ] |
419 ]. |
419 ]. |
420 ]. |
420 ]. |
421 mStart := mStart + 1. |
421 mStart := mStart + 1. |
422 mSize := mSize - 1. |
422 mSize := mSize - 1. |
423 included ifFalse:[^ false]. |
423 included ifFalse:[^ false]. |
424 |
424 |
425 ((sSize == 1) and:[mSize == 0]) ifTrue:[^ true]. |
425 ((sSize == 1) and:[mSize == 0]) ifTrue:[^ true]. |
426 "cut off 1st char and continue" |
426 "cut off 1st char and continue" |
427 sStart := sStart + 1 |
427 sStart := sStart + 1 |
428 ] ifFalse:[ |
428 ] ifFalse:[ |
429 "/ must be single character |
429 "/ must be single character |
430 |
430 |
431 "testString empty ?" |
431 "testString empty ?" |
432 (sSize == 0) ifTrue:[^ false]. |
432 (sSize == 0) ifTrue:[^ false]. |
433 |
433 |
434 "first characters equal ?" |
434 "first characters equal ?" |
435 "/ checkChar := aString at:sStart. |
435 "/ checkChar := aString at:sStart. |
436 ignoreCase ifFalse:[^ false]. |
436 ignoreCase ifFalse:[^ false]. |
437 (checkChar asUppercase ~= matchEntry asUppercase) ifTrue:[^ false]. |
437 (checkChar asUppercase ~= matchEntry asUppercase) ifTrue:[^ false]. |
438 |
438 |
439 "advance and continue" |
439 "advance and continue" |
440 mStart := mStart + 1. |
440 mStart := mStart + 1. |
441 sStart := sStart + 1 |
441 sStart := sStart + 1 |
442 ] |
442 ] |
443 ] |
443 ] |
444 ] |
444 ] |
445 ] |
445 ] |
446 ]. |
446 ]. |
447 |
447 |
448 " |
448 " |
449 |scanArray s| |
449 |scanArray s| |
450 |
450 |
451 scanArray := self matchScanArrayFrom:'*hello'. |
451 scanArray := self matchScanArrayFrom:'*hello'. |
452 s := 'foo bar hello world'. |
452 s := 'foo bar hello world'. |
453 CharacterArray |
453 CharacterArray |
454 matchScan:scanArray |
454 matchScan:scanArray |
455 from:1 |
455 from:1 |
456 to:scanArray size |
456 to:scanArray size |
457 with:s |
457 with:s |
458 from:1 |
458 from:1 |
459 to:s size |
459 to:s size |
460 ignoreCase:false |
460 ignoreCase:false |
461 " |
461 " |
462 " |
462 " |
463 |scanArray s| |
463 |scanArray s| |
464 |
464 |
465 scanArray := self matchScanArrayFrom:'*hello*'. |
465 scanArray := self matchScanArrayFrom:'*hello*'. |
466 s := 'foo bar hello world'. |
466 s := 'foo bar hello world'. |
467 CharacterArray |
467 CharacterArray |
468 matchScan:scanArray |
468 matchScan:scanArray |
469 from:1 |
469 from:1 |
470 to:scanArray size |
470 to:scanArray size |
471 with:s |
471 with:s |
472 from:1 |
472 from:1 |
473 to:s size |
473 to:s size |
474 ignoreCase:false |
474 ignoreCase:false |
475 " |
475 " |
476 |
476 |
477 "Modified: / 15.10.1998 / 13:39:25 / cg" |
477 "Modified: / 15.10.1998 / 13:39:25 / cg" |
478 ! |
478 ! |
479 |
479 |
480 matchScanArrayFrom:aString |
480 matchScanArrayFrom:aString |
481 "scan a pattern string and decompose it into a scanArray. |
481 "scan a pattern string and decompose it into a scanArray. |
482 This is processed faster (especially with character ranges), and |
482 This is processed faster (especially with character ranges), and |
483 can also be reused later. (if the same pattern is to be searched again)" |
483 can also be reused later. (if the same pattern is to be searched again)" |
484 |
484 |
485 |coll |
485 |coll |
486 idx "{ Class: SmallInteger }" |
486 idx "{ Class: SmallInteger }" |
487 end c1 c2 matchSet previous escape| |
487 end c1 c2 matchSet previous escape| |
488 |
488 |
489 previous := nil. |
489 previous := nil. |
490 escape := self matchEscapeCharacter. |
490 escape := self matchEscapeCharacter. |
491 |
491 |
492 coll := OrderedCollection new. |
492 coll := OrderedCollection new. |
493 idx := 1. end := aString size. |
493 idx := 1. end := aString size. |
494 [idx <= end] whileTrue:[ |
494 [idx <= end] whileTrue:[ |
495 |char this| |
495 |char this| |
496 |
496 |
497 char := aString at:idx. |
497 char := aString at:idx. |
498 char == $* ifTrue:[ |
498 char == $* ifTrue:[ |
499 previous ~~ #anyString ifTrue:[ |
499 previous ~~ #anyString ifTrue:[ |
500 this := #anyString |
500 this := #anyString |
501 ] |
501 ] |
502 ] ifFalse:[ |
502 ] ifFalse:[ |
503 char == $# ifTrue:[ |
503 char == $# ifTrue:[ |
504 previous ~~ #anyString ifTrue:[ |
504 previous ~~ #anyString ifTrue:[ |
505 this := #any |
505 this := #any |
506 ] |
506 ] |
507 ] ifFalse:[ |
507 ] ifFalse:[ |
508 char == $[ ifTrue:[ |
508 char == $[ ifTrue:[ |
509 matchSet := IdentitySet new. |
509 matchSet := IdentitySet new. |
510 idx := idx + 1. |
510 idx := idx + 1. |
511 idx > end ifTrue:[^ nil]. |
511 idx > end ifTrue:[^ nil]. |
512 char := aString at:idx. |
512 char := aString at:idx. |
513 c1 := nil. |
513 c1 := nil. |
514 [char ~~ $]] whileTrue:[ |
514 [char ~~ $]] whileTrue:[ |
515 ((char == $-) and:[c1 notNil]) ifTrue:[ |
515 ((char == $-) and:[c1 notNil]) ifTrue:[ |
516 idx := idx + 1. |
516 idx := idx + 1. |
517 idx > end ifTrue:[^ nil]. |
517 idx > end ifTrue:[^ nil]. |
518 c2 := aString at:idx. |
518 c2 := aString at:idx. |
519 c1 to:c2 do:[:c | matchSet add:c]. |
519 c1 to:c2 do:[:c | matchSet add:c]. |
520 c1 := nil. |
520 c1 := nil. |
521 idx := idx + 1. |
521 idx := idx + 1. |
522 ] ifFalse:[ |
522 ] ifFalse:[ |
523 (char ~~ $]) ifTrue:[ |
523 (char ~~ $]) ifTrue:[ |
524 matchSet add:char. |
524 matchSet add:char. |
525 c1 := char. |
525 c1 := char. |
526 idx := idx + 1 |
526 idx := idx + 1 |
527 ] |
527 ] |
528 ]. |
528 ]. |
529 idx > end ifTrue:[^ nil]. |
529 idx > end ifTrue:[^ nil]. |
530 char := aString at:idx |
530 char := aString at:idx |
531 ]. |
531 ]. |
532 this := matchSet asString |
532 this := matchSet asString |
533 ] ifFalse:[ |
533 ] ifFalse:[ |
534 char == escape ifTrue:[ |
534 char == escape ifTrue:[ |
535 idx := idx + 1. |
535 idx := idx + 1. |
536 idx > end ifTrue:[ |
536 idx > end ifTrue:[ |
537 "/ mhmh - what should we do here ? |
537 "/ mhmh - what should we do here ? |
538 this := char |
538 this := char |
539 ] ifFalse:[ |
539 ] ifFalse:[ |
540 this := aString at:idx. |
540 this := aString at:idx. |
541 ] |
541 ] |
542 ] ifFalse:[ |
542 ] ifFalse:[ |
543 this := char |
543 this := char |
544 ] |
544 ] |
545 ] |
545 ] |
546 ] |
546 ] |
547 ]. |
547 ]. |
548 this notNil ifTrue:[coll add:this. previous := this]. |
548 this notNil ifTrue:[coll add:this. previous := this]. |
549 idx := idx + 1 |
549 idx := idx + 1 |
550 ]. |
550 ]. |
551 |
551 |
552 ^ coll asArray |
552 ^ coll asArray |
553 |
553 |
554 " |
554 " |
555 String matchScanArrayFrom:'*ute*' |
555 String matchScanArrayFrom:'*ute*' |
556 String matchScanArrayFrom:'**ute**' |
556 String matchScanArrayFrom:'**ute**' |
557 String matchScanArrayFrom:'*uter' |
557 String matchScanArrayFrom:'*uter' |
558 String matchScanArrayFrom:'\*uter' |
558 String matchScanArrayFrom:'\*uter' |
559 String matchScanArrayFrom:'[cC]#mpute[rR]' |
559 String matchScanArrayFrom:'[cC]#mpute[rR]' |
560 String matchScanArrayFrom:'[abcd]*' |
560 String matchScanArrayFrom:'[abcd]*' |
561 String matchScanArrayFrom:'[a-k]*' |
561 String matchScanArrayFrom:'[a-k]*' |
562 String matchScanArrayFrom:'*some*compl*ern*' |
562 String matchScanArrayFrom:'*some*compl*ern*' |
563 String matchScanArrayFrom:'[a-' |
563 String matchScanArrayFrom:'[a-' |
564 String matchScanArrayFrom:'[a-zA-Z]' |
564 String matchScanArrayFrom:'[a-zA-Z]' |
565 String matchScanArrayFrom:'[a-z01234A-Z]' |
565 String matchScanArrayFrom:'[a-z01234A-Z]' |
566 " |
566 " |
567 |
567 |
568 "Modified: 2.4.1997 / 16:20:29 / cg" |
568 "Modified: 2.4.1997 / 16:20:29 / cg" |
569 ! ! |
569 ! ! |
570 |
570 |
593 |
593 |
594 |ds| |
594 |ds| |
595 |
595 |
596 ds := WriteStream on:(self species new). |
596 ds := WriteStream on:(self species new). |
597 self do:[:eachChar | |
597 self do:[:eachChar | |
598 |repl| |
598 |repl| |
599 |
599 |
600 repl := expandTable at:eachChar ifAbsent:nil. |
600 repl := expandTable at:eachChar ifAbsent:nil. |
601 repl isNil ifTrue:[ |
601 repl isNil ifTrue:[ |
602 ds nextPut:eachChar |
602 ds nextPut:eachChar |
603 ] ifFalse:[ |
603 ] ifFalse:[ |
604 repl size == 0 ifTrue:[ |
604 repl size == 0 ifTrue:[ |
605 ds nextPut:repl |
605 ds nextPut:repl |
606 ] ifFalse:[ |
606 ] ifFalse:[ |
607 ds nextPutAll:repl |
607 ds nextPutAll:repl |
608 ] |
608 ] |
609 ]. |
609 ]. |
610 ]. |
610 ]. |
611 ^ ds contents. |
611 ^ ds contents. |
612 ! |
612 ! |
613 |
613 |
614 formatWith:aString |
614 formatWith:aString |
653 "/ ]. |
653 "/ ]. |
654 ^ super at:index put:(Character value:aByte) |
654 ^ super at:index put:(Character value:aByte) |
655 |
655 |
656 " |
656 " |
657 'hello' copy at:1 put:$H asciiValue; yourself |
657 'hello' copy at:1 put:$H asciiValue; yourself |
658 'hello' copy byteAt:1 put:72; yourself |
658 'hello' copy byteAt:1 put:72; yourself |
659 'hello' copy byteAt:1 put:0; yourself |
659 'hello' copy byteAt:1 put:0; yourself |
660 " |
660 " |
661 |
661 |
662 "Modified: 6.5.1996 / 10:35:26 / cg" |
662 "Modified: 6.5.1996 / 10:35:26 / cg" |
663 ! |
663 ! |
664 |
664 |
668 This is an ST/V compatibility method." |
668 This is an ST/V compatibility method." |
669 |
669 |
670 ^ self copyReplaceAll:oldChar with:newChar |
670 ^ self copyReplaceAll:oldChar with:newChar |
671 |
671 |
672 " |
672 " |
673 '12345678901234567890' replChar:$0 with:$* |
673 '12345678901234567890' replChar:$0 with:$* |
674 " |
674 " |
675 |
675 |
676 "Modified: / 18.7.1998 / 22:52:57 / cg" |
676 "Modified: / 18.7.1998 / 22:52:57 / cg" |
677 ! |
677 ! |
678 |
678 |
686 tmpStream := WriteStream on:(self class new). |
686 tmpStream := WriteStream on:(self class new). |
687 self do:[:element | |
687 self do:[:element | |
688 element = oldChar ifTrue:[ |
688 element = oldChar ifTrue:[ |
689 tmpStream nextPutAll:newString |
689 tmpStream nextPutAll:newString |
690 ] ifFalse:[ |
690 ] ifFalse:[ |
691 tmpStream nextPut:element |
691 tmpStream nextPut:element |
692 ]. |
692 ]. |
693 ]. |
693 ]. |
694 ^ tmpStream contents |
694 ^ tmpStream contents |
695 |
695 |
696 " |
696 " |
697 '12345678901234567890' replChar:$0 withString:'foo' |
697 '12345678901234567890' replChar:$0 withString:'foo' |
698 'a string with spaces' replChar:$ withString:' foo ' |
698 'a string with spaces' replChar:$ withString:' foo ' |
699 " |
699 " |
700 ! |
700 ! |
701 |
701 |
702 replString:subString withString:newString |
702 replString:subString withString:newString |
703 "return a copy of the receiver, with all sequences of subString replaced |
703 "return a copy of the receiver, with all sequences of subString replaced |
704 by newString (i.e. slice in the newString in place of the oldString)." |
704 by newString (i.e. slice in the newString in place of the oldString)." |
705 |
705 |
706 ^ self copyReplaceString:subString withString:newString |
706 ^ self copyReplaceString:subString withString:newString |
707 |
707 |
708 " |
708 " |
709 '12345678901234567890' replString:'123' withString:'OneTwoThree' |
709 '12345678901234567890' replString:'123' withString:'OneTwoThree' |
710 '12345678901234567890' replString:'123' withString:'*' |
710 '12345678901234567890' replString:'123' withString:'*' |
711 '12345678901234567890' replString:'234' withString:'foo' |
711 '12345678901234567890' replString:'234' withString:'foo' |
712 |
712 |
713 ('a string with spaces' replChar:$ withString:' foo ') |
713 ('a string with spaces' replChar:$ withString:' foo ') |
714 replString:'foo' withString:'bar' |
714 replString:'foo' withString:'bar' |
715 " |
715 " |
716 |
716 |
717 "Modified: / 12-05-2004 / 12:00:27 / cg" |
717 "Modified: / 12-05-2004 / 12:00:27 / cg" |
718 ! |
718 ! |
719 |
719 |
723 This is an ST/V compatibility method." |
723 This is an ST/V compatibility method." |
724 |
724 |
725 ^ self withoutSpaces |
725 ^ self withoutSpaces |
726 |
726 |
727 " |
727 " |
728 ' spaces at beginning' trimBlanks |
728 ' spaces at beginning' trimBlanks |
729 'spaces at end ' trimBlanks |
729 'spaces at end ' trimBlanks |
730 ' spaces at beginning and end ' trimBlanks |
730 ' spaces at beginning and end ' trimBlanks |
731 'no spaces' trimBlanks |
731 'no spaces' trimBlanks |
732 " |
732 " |
733 ! ! |
733 ! ! |
734 |
734 |
735 !CharacterArray methodsFor:'Compatibility-Squeak'! |
735 !CharacterArray methodsFor:'Compatibility-Squeak'! |
736 |
736 |
738 "Many allowed forms, see Date.readFrom:" |
738 "Many allowed forms, see Date.readFrom:" |
739 |
739 |
740 ^ Date readFrom: (ReadStream on: self) |
740 ^ Date readFrom: (ReadStream on: self) |
741 |
741 |
742 " |
742 " |
743 '30 Apr 1999' asDate dayName capitalized |
743 '30 Apr 1999' asDate dayName capitalized |
744 " |
744 " |
745 ! |
745 ! |
746 |
746 |
747 capitalized |
747 capitalized |
748 ^ self asUppercaseFirst |
748 ^ self asUppercaseFirst |
752 " |
752 " |
753 ! |
753 ! |
754 |
754 |
755 displayProgressAt:aPointOrNil from:start to:stop during:aBlock |
755 displayProgressAt:aPointOrNil from:start to:stop during:aBlock |
756 ProgressIndicator |
756 ProgressIndicator |
757 displayProgress:self |
757 displayProgress:self |
758 at:aPointOrNil |
758 at:aPointOrNil |
759 from:start |
759 from:start |
760 to:stop |
760 to:stop |
761 during:aBlock. |
761 during:aBlock. |
762 |
762 |
763 " |
763 " |
764 'dobedobedoobedoo' |
764 'dobedobedoobedoo' |
765 displayProgressAt:(Screen current center) |
765 displayProgressAt:(Screen current center) |
766 from:0 to:100 |
766 from:0 to:100 |
767 during:[:val | |
767 during:[:val | |
768 0 to:100 do:[:i | |
768 0 to:100 do:[:i | |
769 val value:i. |
769 val value:i. |
770 Delay waitForSeconds:0.05. |
770 Delay waitForSeconds:0.05. |
771 ] |
771 ] |
772 ] |
772 ] |
773 " |
773 " |
774 ! |
774 ! |
775 |
775 |
776 endsWithDigit |
776 endsWithDigit |
777 "Answer whether the receiver's final character represents a digit. 3/11/96 sw" |
777 "Answer whether the receiver's final character represents a digit. 3/11/96 sw" |
783 "cg: I am not sure, if this is really the squeak semantics (w.r.t. empty fields)" |
783 "cg: I am not sure, if this is really the squeak semantics (w.r.t. empty fields)" |
784 |
784 |
785 ^ self asCollectionOfSubstringsSeparatedByAny:delimiters |
785 ^ self asCollectionOfSubstringsSeparatedByAny:delimiters |
786 |
786 |
787 " |
787 " |
788 'a|b#c||e' findTokens:#($# $|) |
788 'a|b#c||e' findTokens:#($# $|) |
789 " |
789 " |
790 ! |
790 ! |
791 |
791 |
792 includesSubString:aString |
792 includesSubString:aString |
793 "return true, if a substring is contained in the receiver. |
793 "return true, if a substring is contained in the receiver. |
794 The compare is case sensitive." |
794 The compare is case sensitive." |
795 |
795 |
796 ^ self includesString:aString |
796 ^ self includesString:aString |
797 |
797 |
798 " |
798 " |
799 'hello world' includesSubString:'Hel' |
799 'hello world' includesSubString:'Hel' |
800 'hello world' includesSubString:'hel' |
800 'hello world' includesSubString:'hel' |
801 'hello world' includesSubString:'llo' |
801 'hello world' includesSubString:'llo' |
802 " |
802 " |
803 |
803 |
804 |
804 |
805 |
805 |
806 ! |
806 ! |
810 The argument, caseSensitive controls if case is ignored in the compare." |
810 The argument, caseSensitive controls if case is ignored in the compare." |
811 |
811 |
812 "/ for now, a q&d hack ... |
812 "/ for now, a q&d hack ... |
813 |
813 |
814 caseSensitive ifFalse:[ |
814 caseSensitive ifFalse:[ |
815 ^ self asLowercase includesString:aString asLowercase |
815 ^ self asLowercase includesString:aString asLowercase |
816 ]. |
816 ]. |
817 ^ self includesString:aString |
817 ^ self includesString:aString |
818 |
818 |
819 " |
819 " |
820 'hello world' includesSubstring:'Hel' caseSensitive:true |
820 'hello world' includesSubstring:'Hel' caseSensitive:true |
821 'hello world' includesSubstring:'Hel' caseSensitive:false |
821 'hello world' includesSubstring:'Hel' caseSensitive:false |
822 " |
822 " |
823 |
823 |
824 |
824 |
825 |
825 |
826 ! |
826 ! |
840 ^ self lastIndexOfSeparator |
840 ^ self lastIndexOfSeparator |
841 ! |
841 ! |
842 |
842 |
843 padded:leftOrRight to:paddedSize with:padCharacter |
843 padded:leftOrRight to:paddedSize with:padCharacter |
844 leftOrRight == #left ifTrue:[ |
844 leftOrRight == #left ifTrue:[ |
845 ^ self leftPaddedTo:paddedSize with:padCharacter |
845 ^ self leftPaddedTo:paddedSize with:padCharacter |
846 ]. |
846 ]. |
847 ^ self paddedTo:paddedSize with:padCharacter |
847 ^ self paddedTo:paddedSize with:padCharacter |
848 |
848 |
849 " |
849 " |
850 'hello' padded:#right to:10 with:$. |
850 'hello' padded:#right to:10 with:$. |
851 'hello' padded:#left to:10 with:$. |
851 'hello' padded:#left to:10 with:$. |
852 " |
852 " |
853 ! |
853 ! |
854 |
854 |
855 skipDelimiters:delimiters startingAt:start |
855 skipDelimiters:delimiters startingAt:start |
856 "Answer the index of the character within the receiver, starting at start, |
856 "Answer the index of the character within the receiver, starting at start, |
857 that does NOT match one of the delimiters. |
857 that does NOT match one of the delimiters. |
858 If the receiver does not contain any of the delimiters, answer size + 1. |
858 If the receiver does not contain any of the delimiters, answer size + 1. |
859 Assumes the delimiters to be a non-empty string." |
859 Assumes the delimiters to be a non-empty string." |
860 |
860 |
861 start to:self size do:[:i | |
861 start to:self size do:[:i | |
862 delimiters detect:[:delim | delim = (self at:i) ] ifNone:[ ^ i ] |
862 delimiters detect:[:delim | delim = (self at:i) ] ifNone:[ ^ i ] |
863 ]. |
863 ]. |
864 ^ self size + 1 |
864 ^ self size + 1 |
865 |
865 |
866 " |
866 " |
867 '123***7890' skipDelimiters:'*' startingAt:4 |
867 '123***7890' skipDelimiters:'*' startingAt:4 |
868 '123***7890' skipDelimiters:'*' startingAt:3 |
868 '123***7890' skipDelimiters:'*' startingAt:3 |
869 '123***7890' skipDelimiters:'*' startingAt:10 |
869 '123***7890' skipDelimiters:'*' startingAt:10 |
870 '123*******' skipDelimiters:'*' startingAt:10 |
870 '123*******' skipDelimiters:'*' startingAt:10 |
871 " |
871 " |
872 ! |
872 ! |
873 |
873 |
874 substrings |
874 substrings |
875 ^ self asCollectionOfWords |
875 ^ self asCollectionOfWords |
884 |
884 |
885 self size <= smallSize ifTrue:[^ self]. |
885 self size <= smallSize ifTrue:[^ self]. |
886 ^ self copyFrom: 1 to: smallSize |
886 ^ self copyFrom: 1 to: smallSize |
887 |
887 |
888 " |
888 " |
889 'hello world' truncateTo:5 |
889 'hello world' truncateTo:5 |
890 'hello' truncateTo:10 |
890 'hello' truncateTo:10 |
891 |
891 |
892 'hello world' copyTo:5 |
892 'hello world' copyTo:5 |
893 'hello' copyTo:10 |
893 'hello' copyTo:10 |
894 " |
894 " |
895 ! |
895 ! |
896 |
896 |
897 withBlanksTrimmed |
897 withBlanksTrimmed |
898 "Return a copy of the receiver from which leading and trailing blanks have been trimmed." |
898 "Return a copy of the receiver from which leading and trailing blanks have been trimmed." |
899 |
899 |
900 ^ self withoutSpaces |
900 ^ self withoutSpaces |
901 |
901 |
902 " |
902 " |
903 ' hello world ' withBlanksTrimmed |
903 ' hello world ' withBlanksTrimmed |
904 " |
904 " |
905 |
905 |
906 |
906 |
907 |
907 |
908 ! |
908 ! |
914 |
914 |
915 aNumber isNumber not | (aNumber < 1) ifTrue: [self error: 'too narrow']. |
915 aNumber isNumber not | (aNumber < 1) ifTrue: [self error: 'too narrow']. |
916 listOfLines _ OrderedCollection new. |
916 listOfLines _ OrderedCollection new. |
917 currentLast _ 0. |
917 currentLast _ 0. |
918 [currentLast < self size] whileTrue: |
918 [currentLast < self size] whileTrue: |
919 [currentStart _ currentLast + 1. |
919 [currentStart _ currentLast + 1. |
920 putativeLast _ (currentStart + aNumber - 1) min: self size. |
920 putativeLast _ (currentStart + aNumber - 1) min: self size. |
921 putativeLine _ self copyFrom: currentStart to: putativeLast. |
921 putativeLine _ self copyFrom: currentStart to: putativeLast. |
922 (crPosition _ putativeLine indexOf: Character cr) > 0 ifTrue: |
922 (crPosition _ putativeLine indexOf: Character cr) > 0 ifTrue: |
923 [putativeLast _ currentStart + crPosition - 1. |
923 [putativeLast _ currentStart + crPosition - 1. |
924 putativeLine _ self copyFrom: currentStart to: putativeLast]. |
924 putativeLine _ self copyFrom: currentStart to: putativeLast]. |
925 currentLast _ putativeLast == self size |
925 currentLast _ putativeLast == self size |
926 ifTrue: |
926 ifTrue: |
927 [putativeLast] |
927 [putativeLast] |
928 ifFalse: |
928 ifFalse: |
929 [currentStart + putativeLine lastSpacePosition - 1]. |
929 [currentStart + putativeLine lastSpacePosition - 1]. |
930 currentLast <= currentStart ifTrue: |
930 currentLast <= currentStart ifTrue: |
931 ["line has NO spaces; baleout!!" |
931 ["line has NO spaces; baleout!!" |
932 currentLast _ putativeLast]. |
932 currentLast _ putativeLast]. |
933 listOfLines add: (self copyFrom: currentStart to: currentLast) withBlanksTrimmed]. |
933 listOfLines add: (self copyFrom: currentStart to: currentLast) withBlanksTrimmed]. |
934 |
934 |
935 listOfLines size > 0 ifFalse: [^ '']. |
935 listOfLines size > 0 ifFalse: [^ '']. |
936 resultString _ listOfLines first. |
936 resultString _ listOfLines first. |
937 2 to: listOfLines size do: |
937 2 to: listOfLines size do: |
938 [:i | resultString _ resultString, Character cr asString, (listOfLines at: i)]. |
938 [:i | resultString _ resultString, Character cr asString, (listOfLines at: i)]. |
939 ^ resultString |
939 ^ resultString |
940 |
940 |
941 " |
941 " |
942 #(5 7 20) collect: |
942 #(5 7 20) collect: |
943 [:i | 'Fred the bear went down to the brook to read his book in silence' withNoLineLongerThan: i] |
943 [:i | 'Fred the bear went down to the brook to read his book in silence' withNoLineLongerThan: i] |
944 " |
944 " |
945 |
945 |
946 |
946 |
947 |
947 |
948 ! ! |
948 ! ! |
1020 bindWith:str1 with:str2 with:str3 with:str4 with:str5 with:str6 |
1020 bindWith:str1 with:str2 with:str3 with:str4 with:str5 with:str6 |
1021 "return a copy of the receiver, where a '%1' .. '%6' escapes |
1021 "return a copy of the receiver, where a '%1' .. '%6' escapes |
1022 are replaced by str1 .. str5 respectively. |
1022 are replaced by str1 .. str5 respectively. |
1023 This has been added for VisualAge compatibility." |
1023 This has been added for VisualAge compatibility." |
1024 |
1024 |
1025 ^ self expandPlaceholdersWith:(Array with:str1 with:str2 |
1025 ^ self expandPlaceholdersWith:(Array with:str1 with:str2 |
1026 with:str3 with:str4 |
1026 with:str3 with:str4 |
1027 with:str5 with:str6) |
1027 with:str5 with:str6) |
1028 |
1028 |
1029 ! |
1029 ! |
1030 |
1030 |
1031 bindWithArguments:anArrayOfStrings |
1031 bindWithArguments:anArrayOfStrings |
1032 "return a copy of the receiver, where a '%i' escape |
1032 "return a copy of the receiver, where a '%i' escape |
1151 |
1151 |
1152 in := self readStream. |
1152 in := self readStream. |
1153 out := WriteStream on:(String uninitializedNew:self size). |
1153 out := WriteStream on:(String uninitializedNew:self size). |
1154 |
1154 |
1155 [in atEnd] whileFalse:[ |
1155 [in atEnd] whileFalse:[ |
1156 c := in next. |
1156 c := in next. |
1157 c == $% ifTrue:[ |
1157 c == $% ifTrue:[ |
1158 c := in next. |
1158 c := in next. |
1159 out nextPut:c |
1159 out nextPut:c |
1160 ] ifFalse:[ |
1160 ] ifFalse:[ |
1161 c == $< ifTrue:[ |
1161 c == $< ifTrue:[ |
1162 [in peek == $<] whileTrue:[ |
1162 [in peek == $<] whileTrue:[ |
1163 out nextPut:$<. |
1163 out nextPut:$<. |
1164 in next. |
1164 in next. |
1165 ]. |
1165 ]. |
1166 in peek == $n ifTrue:[ |
1166 in peek == $n ifTrue:[ |
1167 out nextPut:Character cr. |
1167 out nextPut:Character cr. |
1168 in next |
1168 in next |
1169 ] ifFalse:[in peek == $t ifTrue:[ |
1169 ] ifFalse:[in peek == $t ifTrue:[ |
1170 out nextPut:Character tab. |
1170 out nextPut:Character tab. |
1171 in next |
1171 in next |
1172 ] ifFalse:[ |
1172 ] ifFalse:[ |
1173 in peek isDigit ifFalse:[ |
1173 in peek isDigit ifFalse:[ |
1174 nr := 1 |
1174 nr := 1 |
1175 ] ifTrue:[ |
1175 ] ifTrue:[ |
1176 "/ start an argument expansion ... |
1176 "/ start an argument expansion ... |
1177 nr := Integer readFrom:in onError:nil. |
1177 nr := Integer readFrom:in onError:nil. |
1178 nr isNil ifTrue:[ |
1178 nr isNil ifTrue:[ |
1179 "/ what does VW do here ? |
1179 "/ what does VW do here ? |
1180 self error:'invalid format' mayProceed:true. |
1180 self error:'invalid format' mayProceed:true. |
1181 ^ self |
1181 ^ self |
1182 ]. |
1182 ]. |
1183 (nr between:1 and:argArray size) ifFalse:[ |
1183 (nr between:1 and:argArray size) ifFalse:[ |
1184 "/ what does VW do here ? |
1184 "/ what does VW do here ? |
1185 self error:'invalid format - bad argNr' mayProceed:true. |
1185 self error:'invalid format - bad argNr' mayProceed:true. |
1186 ^ self |
1186 ^ self |
1187 ]. |
1187 ]. |
1188 ]. |
1188 ]. |
1189 arg := argArray at:nr. |
1189 arg := argArray at:nr. |
1190 |
1190 |
1191 fmt := in next. |
1191 fmt := in next. |
1192 (fmt == $p) ifTrue:[ |
1192 (fmt == $p) ifTrue:[ |
1193 "/ expand with args printString |
1193 "/ expand with args printString |
1194 out nextPutAll:arg printString. |
1194 out nextPutAll:arg printString. |
1195 ] ifFalse:[ (fmt == $s) ifTrue:[ |
1195 ] ifFalse:[ (fmt == $s) ifTrue:[ |
1196 "/ expand with arg itself |
1196 "/ expand with arg itself |
1197 arg isText ifTrue:[ |
1197 arg isText ifTrue:[ |
1198 out := (WriteStream on:(Text new)) nextPutAll:(out contents); yourself. |
1198 out := (WriteStream on:(Text new)) nextPutAll:(out contents); yourself. |
1199 out nextPutAll:arg asText. |
1199 out nextPutAll:arg asText. |
1200 ] ifFalse:[ |
1200 ] ifFalse:[ |
1201 out nextPutAll:arg asString string. |
1201 out nextPutAll:arg asString string. |
1202 ] |
1202 ] |
1203 ] ifFalse:[ (fmt == $?) ifTrue:[ |
1203 ] ifFalse:[ (fmt == $?) ifTrue:[ |
1204 s1 := in upTo:$:. |
1204 s1 := in upTo:$:. |
1205 s2 := in nextUpTo:$>. |
1205 s2 := in nextUpTo:$>. |
1206 arg ifTrue:[ |
1206 arg ifTrue:[ |
1207 out nextPutAll:s1 |
1207 out nextPutAll:s1 |
1208 ] ifFalse:[ |
1208 ] ifFalse:[ |
1209 out nextPutAll:s2 |
1209 out nextPutAll:s2 |
1210 ]. |
1210 ]. |
1211 ] ifFalse:[ |
1211 ] ifFalse:[ |
1212 "/ what does VW do here ? |
1212 "/ what does VW do here ? |
1213 self error:'invalid format' mayProceed:true. |
1213 self error:'invalid format' mayProceed:true. |
1214 ^ self |
1214 ^ self |
1215 ]]]. |
1215 ]]]. |
1216 ]]. |
1216 ]]. |
1217 c := in next. |
1217 c := in next. |
1218 c ~~ $> ifTrue:[ |
1218 c ~~ $> ifTrue:[ |
1219 "/ what does VW do here ? |
1219 "/ what does VW do here ? |
1220 self error:'invalid format' mayProceed:true. |
1220 self error:'invalid format' mayProceed:true. |
1221 ^ self |
1221 ^ self |
1222 ] |
1222 ] |
1223 ] ifFalse:[ |
1223 ] ifFalse:[ |
1224 out nextPut:c |
1224 out nextPut:c |
1225 ] |
1225 ] |
1226 ]. |
1226 ]. |
1227 ]. |
1227 ]. |
1228 ^ out contents |
1228 ^ out contents |
1229 |
1229 |
1230 " |
1230 " |
1231 'hello <1s> how are you' expandMacrosWith:(OperatingSystem getLoginName) |
1231 'hello <1s> how are you' expandMacrosWith:(OperatingSystem getLoginName) |
1232 'one plus one is <1p>' expandMacrosWith:2 |
1232 'one plus one is <1p>' expandMacrosWith:2 |
1233 " |
1233 " |
1234 |
1234 |
1235 "Modified: / 18.6.1998 / 16:04:46 / cg" |
1235 "Modified: / 18.6.1998 / 16:04:46 / cg" |
1236 ! |
1236 ! |
1237 |
1237 |
1241 ! ! |
1241 ! ! |
1242 |
1242 |
1243 !CharacterArray methodsFor:'character searching'! |
1243 !CharacterArray methodsFor:'character searching'! |
1244 |
1244 |
1245 includesMatchCharacters |
1245 includesMatchCharacters |
1246 "return true if the receiver includes any meta characters (i.e. $* or $#) |
1246 "return true if the receiver includes any meta characters (i.e. $* or $#) |
1247 for match operations; false if not. |
1247 for match operations; false if not. |
1248 Here, do not care for $\ escapes" |
1248 Here, do not care for $\ escapes" |
1249 |
1249 |
1250 ^ self includesAny:'*#[' |
1250 ^ self includesAny:'*#[' |
1251 |
1251 |
1252 " |
1252 " |
1253 '*foo' includesMatchCharacters |
1253 '*foo' includesMatchCharacters |
1254 '\*foo' includesMatchCharacters |
1254 '\*foo' includesMatchCharacters |
1255 '\*foo' includesUnescapedMatchCharacters |
1255 '\*foo' includesUnescapedMatchCharacters |
1256 '*foo' includesMatchCharacters |
1256 '*foo' includesMatchCharacters |
1257 '\\*foo' includesMatchCharacters |
1257 '\\*foo' includesMatchCharacters |
1258 'foo*' includesMatchCharacters |
1258 'foo*' includesMatchCharacters |
1259 'foo\*' includesMatchCharacters |
1259 'foo\*' includesMatchCharacters |
1260 'foo\' includesMatchCharacters |
1260 'foo\' includesMatchCharacters |
1261 " |
1261 " |
1267 "return true, if the receiver contains any whitespace characters" |
1267 "return true, if the receiver contains any whitespace characters" |
1268 |
1268 |
1269 ^ (self indexOfSeparator ~~ 0) |
1269 ^ (self indexOfSeparator ~~ 0) |
1270 |
1270 |
1271 " |
1271 " |
1272 'hello world' includesSeparator |
1272 'hello world' includesSeparator |
1273 'helloworld' includesSeparator |
1273 'helloworld' includesSeparator |
1274 " |
1274 " |
1275 ! |
1275 ! |
1276 |
1276 |
1277 includesUnescapedMatchCharacters |
1277 includesUnescapedMatchCharacters |
1278 "return true if the receiver really includes any meta characters (i.e. $* or $#) |
1278 "return true if the receiver really includes any meta characters (i.e. $* or $#) |
1279 for match operations; false if not. |
1279 for match operations; false if not. |
1280 Here, care for $\ escapes" |
1280 Here, care for $\ escapes" |
1281 |
1281 |
1282 |idx sz specialChars escape| |
1282 |idx sz specialChars escape| |
1283 |
1283 |
1284 idx := 1. |
1284 idx := 1. |
1285 sz := self size. |
1285 sz := self size. |
1286 specialChars := '*#[\'. |
1286 specialChars := '*#[\'. |
1287 (escape := self class matchEscapeCharacter) ~~ $\ ifTrue:[ |
1287 (escape := self class matchEscapeCharacter) ~~ $\ ifTrue:[ |
1288 specialChars := specialChars copy. |
1288 specialChars := specialChars copy. |
1289 specialChars at:specialChars size put:escape |
1289 specialChars at:specialChars size put:escape |
1290 ]. |
1290 ]. |
1291 |
1291 |
1292 [true] whileTrue:[ |
1292 [true] whileTrue:[ |
1293 idx := self indexOfAny:specialChars startingAt:idx. |
1293 idx := self indexOfAny:specialChars startingAt:idx. |
1294 idx == 0 ifTrue:[^ false]. |
1294 idx == 0 ifTrue:[^ false]. |
1295 (self at:idx) == escape ifFalse:[^ true]. |
1295 (self at:idx) == escape ifFalse:[^ true]. |
1296 idx := idx + 2. |
1296 idx := idx + 2. |
1297 idx > sz ifTrue:[^ false]. |
1297 idx > sz ifTrue:[^ false]. |
1298 ]. |
1298 ]. |
1299 |
1299 |
1300 " |
1300 " |
1301 '*foo' includesUnescapedMatchCharacters |
1301 '*foo' includesUnescapedMatchCharacters |
1302 '\*foo' includesUnescapedMatchCharacters |
1302 '\*foo' includesUnescapedMatchCharacters |
1303 '\\foo' includesUnescapedMatchCharacters |
1303 '\\foo' includesUnescapedMatchCharacters |
1304 '\\\$foo' includesUnescapedMatchCharacters |
1304 '\\\$foo' includesUnescapedMatchCharacters |
1305 '*foo' includesUnescapedMatchCharacters |
1305 '*foo' includesUnescapedMatchCharacters |
1306 '\\*foo' includesUnescapedMatchCharacters |
1306 '\\*foo' includesUnescapedMatchCharacters |
1307 'foo*' includesUnescapedMatchCharacters |
1307 'foo*' includesUnescapedMatchCharacters |
1308 'foo\*' includesUnescapedMatchCharacters |
1308 'foo\*' includesUnescapedMatchCharacters |
1309 'foo\' includesUnescapedMatchCharacters |
1309 'foo\' includesUnescapedMatchCharacters |
1324 |
1324 |
1325 start := startIndex. |
1325 start := startIndex. |
1326 mySize := self size. |
1326 mySize := self size. |
1327 |
1327 |
1328 start to:mySize do:[:index | |
1328 start to:mySize do:[:index | |
1329 (self at:index) isControlCharacter ifTrue:[^ index] |
1329 (self at:index) isControlCharacter ifTrue:[^ index] |
1330 ]. |
1330 ]. |
1331 ^ 0 |
1331 ^ 0 |
1332 |
1332 |
1333 " |
1333 " |
1334 'hello world' asTwoByteString indexOfControlCharacterStartingAt:1 |
1334 'hello world' asTwoByteString indexOfControlCharacterStartingAt:1 |
1343 return 0 if no non-separator was found" |
1343 return 0 if no non-separator was found" |
1344 |
1344 |
1345 ^ self indexOfNonSeparatorStartingAt:1. |
1345 ^ self indexOfNonSeparatorStartingAt:1. |
1346 |
1346 |
1347 " |
1347 " |
1348 ' hello world' indexOfNonSeparator |
1348 ' hello world' indexOfNonSeparator |
1349 ' ' indexOfNonSeparator |
1349 ' ' indexOfNonSeparator |
1350 'a ' indexOfNonSeparator |
1350 'a ' indexOfNonSeparator |
1351 'abc' indexOfNonSeparator |
1351 'abc' indexOfNonSeparator |
1352 ' ' indexOfNonSeparator |
1352 ' ' indexOfNonSeparator |
1353 '' indexOfNonSeparator |
1353 '' indexOfNonSeparator |
1354 " |
1354 " |
1355 ! |
1355 ! |
1356 |
1356 |
1357 indexOfNonSeparatorStartingAt:startIndex |
1357 indexOfNonSeparatorStartingAt:startIndex |
1358 "return the index of the next non-whitespace character, |
1358 "return the index of the next non-whitespace character, |
1364 |
1364 |
1365 start := startIndex. |
1365 start := startIndex. |
1366 mySize := self size. |
1366 mySize := self size. |
1367 |
1367 |
1368 start to:mySize do:[:index | |
1368 start to:mySize do:[:index | |
1369 (self at:index) isSeparator ifFalse:[^ index] |
1369 (self at:index) isSeparator ifFalse:[^ index] |
1370 ]. |
1370 ]. |
1371 ^ 0 |
1371 ^ 0 |
1372 |
1372 |
1373 " |
1373 " |
1374 ' hello world' indexOfNonSeparatorStartingAt:1 |
1374 ' hello world' indexOfNonSeparatorStartingAt:1 |
1375 ' ' indexOfNonSeparatorStartingAt:1 |
1375 ' ' indexOfNonSeparatorStartingAt:1 |
1376 'a ' indexOfNonSeparatorStartingAt:2 |
1376 'a ' indexOfNonSeparatorStartingAt:2 |
1377 " |
1377 " |
1378 |
1378 |
1379 " |
1379 " |
1380 |s index1 index2| |
1380 |s index1 index2| |
1381 s := ' foo bar baz'. |
1381 s := ' foo bar baz'. |
1391 return 0 if no separator was found" |
1391 return 0 if no separator was found" |
1392 |
1392 |
1393 ^ self indexOfSeparatorStartingAt:1 |
1393 ^ self indexOfSeparatorStartingAt:1 |
1394 |
1394 |
1395 " |
1395 " |
1396 'hello world' indexOfSeparator |
1396 'hello world' indexOfSeparator |
1397 'helloworld' indexOfSeparator |
1397 'helloworld' indexOfSeparator |
1398 'hello ' indexOfSeparator |
1398 'hello ' indexOfSeparator |
1399 ' hello' indexOfSeparator |
1399 ' hello' indexOfSeparator |
1400 " |
1400 " |
1401 ! |
1401 ! |
1402 |
1402 |
1403 indexOfSeparatorStartingAt:startIndex |
1403 indexOfSeparatorStartingAt:startIndex |
1404 "return the index of the next whitespace character, |
1404 "return the index of the next whitespace character, |
1410 |
1410 |
1411 start := startIndex. |
1411 start := startIndex. |
1412 mySize := self size. |
1412 mySize := self size. |
1413 |
1413 |
1414 start to:mySize do:[:index | |
1414 start to:mySize do:[:index | |
1415 (self at:index) isSeparator ifTrue:[^ index] |
1415 (self at:index) isSeparator ifTrue:[^ index] |
1416 ]. |
1416 ]. |
1417 ^ 0 |
1417 ^ 0 |
1418 |
1418 |
1419 " |
1419 " |
1420 'hello world' indexOfSeparatorStartingAt:3 |
1420 'hello world' indexOfSeparatorStartingAt:3 |
1421 ' hello world' indexOfSeparatorStartingAt:3 |
1421 ' hello world' indexOfSeparatorStartingAt:3 |
1422 'hello world ' indexOfSeparatorStartingAt:3 |
1422 'hello world ' indexOfSeparatorStartingAt:3 |
1423 'hello world ' indexOfSeparatorStartingAt:6 |
1423 'hello world ' indexOfSeparatorStartingAt:6 |
1424 'hello world ' indexOfSeparatorStartingAt:7 |
1424 'hello world ' indexOfSeparatorStartingAt:7 |
1425 'helloworld ' indexOfSeparatorStartingAt:7 |
1425 'helloworld ' indexOfSeparatorStartingAt:7 |
1426 'helloworld' indexOfSeparatorStartingAt:7 |
1426 'helloworld' indexOfSeparatorStartingAt:7 |
1427 " |
1427 " |
1428 ! |
1428 ! |
1429 |
1429 |
1430 lastIndexOfSeparator |
1430 lastIndexOfSeparator |
1431 "return the last index of the whitespace character. |
1431 "return the last index of the whitespace character. |
1433 Returns 0 if no separator is found." |
1433 Returns 0 if no separator is found." |
1434 |
1434 |
1435 ^ self lastIndexOfSeparatorStartingAt:(self size) |
1435 ^ self lastIndexOfSeparatorStartingAt:(self size) |
1436 |
1436 |
1437 " |
1437 " |
1438 'hello world' lastIndexOfSeparator |
1438 'hello world' lastIndexOfSeparator |
1439 'helloworld' lastIndexOfSeparator |
1439 'helloworld' lastIndexOfSeparator |
1440 'hel lo wor ld' lastIndexOfSeparator |
1440 'hel lo wor ld' lastIndexOfSeparator |
1441 'hel ' lastIndexOfSeparator 6 |
1441 'hel ' lastIndexOfSeparator 6 |
1442 " |
1442 " |
1443 ! |
1443 ! |
1444 |
1444 |
1445 lastIndexOfSeparatorStartingAt:startIndex |
1445 lastIndexOfSeparatorStartingAt:startIndex |
1446 "return the index of the previous whitespace character, |
1446 "return the index of the previous whitespace character, |
1450 |start "{ Class: SmallInteger }"| |
1450 |start "{ Class: SmallInteger }"| |
1451 |
1451 |
1452 start := startIndex. |
1452 start := startIndex. |
1453 |
1453 |
1454 start to:1 by:-1 do:[:index | |
1454 start to:1 by:-1 do:[:index | |
1455 (self at:index) isSeparator ifTrue:[^ index] |
1455 (self at:index) isSeparator ifTrue:[^ index] |
1456 ]. |
1456 ]. |
1457 ^ 0 |
1457 ^ 0 |
1458 |
1458 |
1459 " |
1459 " |
1460 'hello world' lastIndexOfSeparatorStartingAt:3 |
1460 'hello world' lastIndexOfSeparatorStartingAt:3 |
1461 'hello world' lastIndexOfSeparatorStartingAt:7 |
1461 'hello world' lastIndexOfSeparatorStartingAt:7 |
1462 'helloworld' lastIndexOfSeparatorStartingAt:7 |
1462 'helloworld' lastIndexOfSeparatorStartingAt:7 |
1463 ' helloworld' lastIndexOfSeparatorStartingAt:7 |
1463 ' helloworld' lastIndexOfSeparatorStartingAt:7 |
1464 " |
1464 " |
1465 ! ! |
1465 ! ! |
1466 |
1466 |
1467 !CharacterArray methodsFor:'comparing'! |
1467 !CharacterArray methodsFor:'comparing'! |
1468 |
1468 |
1469 < aString |
1469 < aString |
1470 "Compare the receiver with the argument and return true if the |
1470 "Compare the receiver with the argument and return true if the |
1471 receiver is greater than the argument. Otherwise return false. |
1471 receiver is greater than the argument. Otherwise return false. |
1472 This comparison is based on the elements ascii code - |
1472 This comparison is based on the elements ascii code - |
1473 i.e. upper/lowercase & upper/lowercase & national characters are NOT treated specially." |
1473 i.e. upper/lowercase & upper/lowercase & national characters are NOT treated specially." |
1474 |
1474 |
1475 |mySize "{ Class: SmallInteger }" |
1475 |mySize "{ Class: SmallInteger }" |
1476 otherSize "{ Class: SmallInteger }" |
1476 otherSize "{ Class: SmallInteger }" |
1477 n "{ Class: SmallInteger }" |
1477 n "{ Class: SmallInteger }" |
1478 c1 c2| |
1478 c1 c2| |
1479 |
1479 |
1480 mySize := self size. |
1480 mySize := self size. |
1481 otherSize := aString string size. |
1481 otherSize := aString string size. |
1482 n := mySize min:otherSize. |
1482 n := mySize min:otherSize. |
1483 |
1483 |
1484 1 to:n do:[:index | |
1484 1 to:n do:[:index | |
1485 c1 := self at:index. |
1485 c1 := self at:index. |
1486 c2 := aString at:index. |
1486 c2 := aString at:index. |
1487 (c1 == c2 or:[c1 = c2]) ifFalse:[^ c1 < c2]. |
1487 (c1 == c2 or:[c1 = c2]) ifFalse:[^ c1 < c2]. |
1488 ]. |
1488 ]. |
1489 ^ mySize < otherSize |
1489 ^ mySize < otherSize |
1490 ! |
1490 ! |
1491 |
1491 |
1492 = aString |
1492 = aString |
1493 "Compare the receiver with the argument and return true if the |
1493 "Compare the receiver with the argument and return true if the |
1494 receiver is equal to the argument. Otherwise return false. |
1494 receiver is equal to the argument. Otherwise return false. |
1495 |
1495 |
1496 This compare does NOT ignore case differences, |
1496 This compare does NOT ignore case differences, |
1497 therefore 'foo' = 'Foo' will return false. |
1497 therefore 'foo' = 'Foo' will return false. |
1498 Since this is incompatible to ST-80 (at least, V2.x) , this may change." |
1498 Since this is incompatible to ST-80 (at least, V2.x) , this may change." |
1499 |
1499 |
1500 |mySize "{ Class: SmallInteger }" |
1500 |mySize "{ Class: SmallInteger }" |
1501 otherSize | |
1501 otherSize | |
1502 |
1502 |
1503 (aString isString or:[aString species == self species]) ifFalse:[ |
1503 (aString isString or:[aString species == self species]) ifFalse:[ |
1504 ^ false |
1504 ^ false |
1505 ]. |
1505 ]. |
1506 mySize := self size. |
1506 mySize := self size. |
1507 otherSize := aString size. |
1507 otherSize := aString size. |
1508 mySize == otherSize ifFalse:[^ false]. |
1508 mySize == otherSize ifFalse:[^ false]. |
1509 |
1509 |
1510 1 to:mySize do:[:index | |
1510 1 to:mySize do:[:index | |
1511 (self at:index) = (aString at:index) ifFalse:[^ false]. |
1511 (self at:index) = (aString at:index) ifFalse:[^ false]. |
1512 ]. |
1512 ]. |
1513 ^ true |
1513 ^ true |
1514 |
1514 |
1515 " |
1515 " |
1516 'foo' = 'Foo' |
1516 'foo' = 'Foo' |
1517 'foo' = 'bar' |
1517 'foo' = 'bar' |
1518 'foo' = 'foo' |
1518 'foo' = 'foo' |
1519 'foo' = 'foo' asText |
1519 'foo' = 'foo' asText |
1520 'foo' asText = 'foo' |
1520 'foo' asText = 'foo' |
1521 'foo' asText = 'foo' asText |
1521 'foo' asText = 'foo' asText |
1522 " |
1522 " |
1523 |
1523 |
1524 "Modified: 22.4.1996 / 15:53:58 / cg" |
1524 "Modified: 22.4.1996 / 15:53:58 / cg" |
1525 ! |
1525 ! |
1526 |
1526 |
1527 > aString |
1527 > aString |
1528 "Compare the receiver with the argument and return true if the |
1528 "Compare the receiver with the argument and return true if the |
1529 receiver is greater than the argument. Otherwise return false. |
1529 receiver is greater than the argument. Otherwise return false. |
1530 This comparison is based on the elements ascii code - |
1530 This comparison is based on the elements ascii code - |
1531 i.e. upper/lowercase & upper/lowercase & national characters are NOT treated specially." |
1531 i.e. upper/lowercase & upper/lowercase & national characters are NOT treated specially." |
1532 |
1532 |
1533 |mySize "{ Class: SmallInteger }" |
1533 |mySize "{ Class: SmallInteger }" |
1534 otherSize "{ Class: SmallInteger }" |
1534 otherSize "{ Class: SmallInteger }" |
1535 n "{ Class: SmallInteger }" |
1535 n "{ Class: SmallInteger }" |
1536 c1 c2| |
1536 c1 c2| |
1537 |
1537 |
1538 mySize := self size. |
1538 mySize := self size. |
1539 otherSize := aString string size. |
1539 otherSize := aString string size. |
1540 n := mySize min:otherSize. |
1540 n := mySize min:otherSize. |
1541 |
1541 |
1542 1 to:n do:[:index | |
1542 1 to:n do:[:index | |
1543 c1 := self at:index. |
1543 c1 := self at:index. |
1544 c2 := aString at:index. |
1544 c2 := aString at:index. |
1545 (c1 == c2 or:[c1 = c2]) ifFalse:[^ c1 > c2]. |
1545 (c1 == c2 or:[c1 = c2]) ifFalse:[^ c1 > c2]. |
1546 ]. |
1546 ]. |
1547 ^ mySize > otherSize |
1547 ^ mySize > otherSize |
1548 |
1548 |
1549 "Modified: 22.4.1996 / 15:55:00 / cg" |
1549 "Modified: 22.4.1996 / 15:55:00 / cg" |
1550 ! |
1550 ! |
1551 |
1551 |
1552 compareCaselessWith:aString |
1552 compareCaselessWith:aString |
1553 "Compare the receiver against the argument, ignoreing case. |
1553 "Compare the receiver against the argument, ignoreing case. |
1554 Return 1 if the receiver is greater, 0 if equal and -1 if less than the argument. |
1554 Return 1 if the receiver is greater, 0 if equal and -1 if less than the argument. |
1555 |
1555 |
1556 This comparison is based on the elements ascii code - |
1556 This comparison is based on the elements ascii code - |
1557 i.e. national characters are NOT treated specially. |
1557 i.e. national characters are NOT treated specially. |
1558 'foo' compareWith: 'Foo' will return 0" |
1558 'foo' compareWith: 'Foo' will return 0" |
1559 |
1559 |
1560 |mySize "{ Class: SmallInteger }" |
1560 |mySize "{ Class: SmallInteger }" |
1561 otherSize "{ Class: SmallInteger }" |
1561 otherSize "{ Class: SmallInteger }" |
1562 n "{ Class: SmallInteger }" |
1562 n "{ Class: SmallInteger }" |
1563 c1 c2| |
1563 c1 c2| |
1564 |
1564 |
1565 mySize := self size. |
1565 mySize := self size. |
1566 otherSize := aString string size. |
1566 otherSize := aString string size. |
1567 n := mySize min:otherSize. |
1567 n := mySize min:otherSize. |
1568 |
1568 |
1569 1 to:n do:[:index | |
1569 1 to:n do:[:index | |
1570 c1 := (self at:index) asLowercase. |
1570 c1 := (self at:index) asLowercase. |
1571 c2 := (aString at:index) asLowercase. |
1571 c2 := (aString at:index) asLowercase. |
1572 c1 > c2 ifTrue:[^ 1]. |
1572 c1 > c2 ifTrue:[^ 1]. |
1573 c1 < c2 ifTrue:[^ -1]. |
1573 c1 < c2 ifTrue:[^ -1]. |
1574 ]. |
1574 ]. |
1575 mySize > otherSize ifTrue:[^ 1]. |
1575 mySize > otherSize ifTrue:[^ 1]. |
1576 mySize < otherSize ifTrue:[^ -1]. |
1576 mySize < otherSize ifTrue:[^ -1]. |
1577 ^ 0 |
1577 ^ 0 |
1578 |
1578 |
1579 "Modified: 22.4.1996 / 15:56:07 / cg" |
1579 "Modified: 22.4.1996 / 15:56:07 / cg" |
1580 ! |
1580 ! |
1581 |
1581 |
1582 compareWith:aString |
1582 compareWith:aString |
1583 "Compare the receiver with the argument and return 1 if the receiver is |
1583 "Compare the receiver with the argument and return 1 if the receiver is |
1584 greater, 0 if equal and -1 if less than the argument. |
1584 greater, 0 if equal and -1 if less than the argument. |
1585 This comparison is based on the elements ascii code - |
1585 This comparison is based on the elements ascii code - |
1586 i.e. upper/lowercase & national characters are NOT treated specially. |
1586 i.e. upper/lowercase & national characters are NOT treated specially. |
1587 'foo' compareWith: 'Foo' will return 1. |
1587 'foo' compareWith: 'Foo' will return 1. |
1588 while 'foo' sameAs:'Foo' will return true" |
1588 while 'foo' sameAs:'Foo' will return true" |
1589 |
1589 |
1590 |mySize "{ Class: SmallInteger }" |
1590 |mySize "{ Class: SmallInteger }" |
1591 otherSize "{ Class: SmallInteger }" |
1591 otherSize "{ Class: SmallInteger }" |
1592 n "{ Class: SmallInteger }" |
1592 n "{ Class: SmallInteger }" |
1593 c1 c2| |
1593 c1 c2| |
1594 |
1594 |
1595 mySize := self size. |
1595 mySize := self size. |
1596 otherSize := aString string size. |
1596 otherSize := aString string size. |
1597 n := mySize min:otherSize. |
1597 n := mySize min:otherSize. |
1598 |
1598 |
1599 1 to:n do:[:index | |
1599 1 to:n do:[:index | |
1600 c1 := self at:index. |
1600 c1 := self at:index. |
1601 c2 := aString at:index. |
1601 c2 := aString at:index. |
1602 c1 > c2 ifTrue:[^ 1]. |
1602 c1 > c2 ifTrue:[^ 1]. |
1603 c1 < c2 ifTrue:[^ -1]. |
1603 c1 < c2 ifTrue:[^ -1]. |
1604 ]. |
1604 ]. |
1605 mySize > otherSize ifTrue:[^ 1]. |
1605 mySize > otherSize ifTrue:[^ 1]. |
1606 mySize < otherSize ifTrue:[^ -1]. |
1606 mySize < otherSize ifTrue:[^ -1]. |
1607 ^ 0 |
1607 ^ 0 |
1608 |
1608 |
1619 int l; |
1619 int l; |
1620 |
1620 |
1621 cp = __stringVal(self); |
1621 cp = __stringVal(self); |
1622 l = __stringSize(self); |
1622 l = __stringSize(self); |
1623 if (__qClass(self) != @global(String)) { |
1623 if (__qClass(self) != @global(String)) { |
1624 int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars)); |
1624 int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars)); |
1625 |
1625 |
1626 cp += n; |
1626 cp += n; |
1627 l -= n; |
1627 l -= n; |
1628 } |
1628 } |
1629 |
1629 |
1630 /* |
1630 /* |
1631 * this is the dragon-book algorithm |
1631 * this is the dragon-book algorithm |
1632 */ |
1632 */ |
1633 |
1633 |
1634 val = 0; |
1634 val = 0; |
1635 switch (l) { |
1635 switch (l) { |
1636 default: |
1636 default: |
1637 for (cp0 = cp, cp += l - 1; cp >= cp0; cp--) { |
1637 for (cp0 = cp, cp += l - 1; cp >= cp0; cp--) { |
1638 val = (val << 4) + *cp; |
1638 val = (val << 4) + *cp; |
1639 if (g = (val & 0xF0000000)) { |
1639 if (g = (val & 0xF0000000)) { |
1640 val ^= g >> 24; |
1640 val ^= g >> 24; |
1641 val ^= g; |
1641 val ^= g; |
1642 } |
1642 } |
1643 } |
1643 } |
1644 break; |
1644 break; |
1645 case 7: |
1645 case 7: |
1646 val = cp[6] << 4; |
1646 val = cp[6] << 4; |
1647 case 6: |
1647 case 6: |
1648 val = (val + cp[5]) << 4; |
1648 val = (val + cp[5]) << 4; |
1649 case 5: |
1649 case 5: |
1650 val = (val + cp[4]) << 4; |
1650 val = (val + cp[4]) << 4; |
1651 case 4: |
1651 case 4: |
1652 val = (val + cp[3]) << 4; |
1652 val = (val + cp[3]) << 4; |
1653 case 3: |
1653 case 3: |
1654 val = (val + cp[2]) << 4; |
1654 val = (val + cp[2]) << 4; |
1655 case 2: |
1655 case 2: |
1656 val = (val + cp[1]) << 4; |
1656 val = (val + cp[1]) << 4; |
1657 case 1: |
1657 case 1: |
1658 val = val + cp[0]; |
1658 val = val + cp[0]; |
1659 case 0: |
1659 case 0: |
1660 break; |
1660 break; |
1661 } |
1661 } |
1662 |
1662 |
1663 /* |
1663 /* |
1664 * multiply by large prime to spread values |
1664 * multiply by large prime to spread values |
1665 * This speeds up Set and Dictionary by a factor of 10! |
1665 * This speeds up Set and Dictionary by a factor of 10! |
1669 %} |
1669 %} |
1670 |
1670 |
1671 ! |
1671 ! |
1672 |
1672 |
1673 sameAs:aString |
1673 sameAs:aString |
1674 "Compare the receiver with the argument like =, but ignore case differences. |
1674 "Compare the receiver with the argument like =, but ignore case differences. |
1675 Return true or false." |
1675 Return true or false." |
1676 |
1676 |
1677 |mySize "{ Class: SmallInteger }" |
1677 |mySize "{ Class: SmallInteger }" |
1678 otherSize c1 c2| |
1678 otherSize c1 c2| |
1679 |
1679 |
1682 mySize := self size. |
1682 mySize := self size. |
1683 otherSize := aString string size. |
1683 otherSize := aString string size. |
1684 mySize == otherSize ifFalse:[^ false]. |
1684 mySize == otherSize ifFalse:[^ false]. |
1685 |
1685 |
1686 1 to:mySize do:[:index | |
1686 1 to:mySize do:[:index | |
1687 c1 := self at:index. |
1687 c1 := self at:index. |
1688 c2 := aString at:index. |
1688 c2 := aString at:index. |
1689 c1 == c2 ifFalse:[ |
1689 c1 == c2 ifFalse:[ |
1690 (c1 sameAs:c2) ifFalse:[^ false]. |
1690 (c1 sameAs:c2) ifFalse:[^ false]. |
1691 ] |
1691 ] |
1692 ]. |
1692 ]. |
1693 ^ true |
1693 ^ true |
1694 |
1694 |
1695 " |
1695 " |
1696 'foo' sameAs: 'Foo' |
1696 'foo' sameAs: 'Foo' |
1697 'foo' sameAs: 'bar' |
1697 'foo' sameAs: 'bar' |
1698 'foo' sameAs: 'foo' |
1698 'foo' sameAs: 'foo' |
1699 " |
1699 " |
1700 |
1700 |
1701 "Modified: 22.4.1996 / 15:56:17 / cg" |
1701 "Modified: 22.4.1996 / 15:56:17 / cg" |
1702 ! |
1702 ! |
1703 |
1703 |
1705 "Compare the receiver with the argument. |
1705 "Compare the receiver with the argument. |
1706 If ignoreCase is true, this is the same as #sameAs:, |
1706 If ignoreCase is true, this is the same as #sameAs:, |
1707 if false, this is the same as #=." |
1707 if false, this is the same as #=." |
1708 |
1708 |
1709 ignoreCase ifTrue:[ |
1709 ignoreCase ifTrue:[ |
1710 ^ self sameAs:aString |
1710 ^ self sameAs:aString |
1711 ]. |
1711 ]. |
1712 ^ self = aString |
1712 ^ self = aString |
1713 |
1713 |
1714 " |
1714 " |
1715 'foo' sameAs:'Foo' ignoreCase:false |
1715 'foo' sameAs:'Foo' ignoreCase:false |
1716 'foo' sameAs:'foo' ignoreCase:true |
1716 'foo' sameAs:'foo' ignoreCase:true |
1717 " |
1717 " |
1718 |
1718 |
1719 ! |
1719 ! |
1720 |
1720 |
1721 sameCharacters:aString |
1721 sameCharacters:aString |
1728 n := self size. |
1728 n := self size. |
1729 n := n min:(aString string size). |
1729 n := n min:(aString string size). |
1730 |
1730 |
1731 cnt := 0. |
1731 cnt := 0. |
1732 1 to:n do:[:index | |
1732 1 to:n do:[:index | |
1733 c1 := self at:index. |
1733 c1 := self at:index. |
1734 c2 := aString at:index. |
1734 c2 := aString at:index. |
1735 ((c1 == c2) |
1735 ((c1 == c2) |
1736 or:[c1 asLowercase = c2 asLowercase]) ifTrue:[ |
1736 or:[c1 asLowercase = c2 asLowercase]) ifTrue:[ |
1737 cnt := cnt + 1 |
1737 cnt := cnt + 1 |
1738 ] |
1738 ] |
1739 ]. |
1739 ]. |
1740 ^ cnt |
1740 ^ cnt |
1741 |
1741 |
1742 " |
1742 " |
1743 'foobarbaz' sameCharacters: 'foo' |
1743 'foobarbaz' sameCharacters: 'foo' |
1744 'foobarbaz' sameCharacters: 'Foo' |
1744 'foobarbaz' sameCharacters: 'Foo' |
1745 'foobarbaz' sameCharacters: 'baz' |
1745 'foobarbaz' sameCharacters: 'baz' |
1746 " |
1746 " |
1747 ! |
1747 ! |
1748 |
1748 |
1749 sameEmphasisAs:aStringOrText |
1749 sameEmphasisAs:aStringOrText |
1750 "compare the receivers and the arguments emphasis" |
1750 "compare the receivers and the arguments emphasis" |
1751 |
1751 |
1752 ^ self emphasis = aStringOrText emphasis |
1752 ^ self emphasis = aStringOrText emphasis |
1753 |
1753 |
1754 " |
1754 " |
1755 'hello' asText sameEmphasisAs: 'hello' |
1755 'hello' asText sameEmphasisAs: 'hello' |
1756 'hello' asText sameEmphasisAs: 'hello' asText |
1756 'hello' asText sameEmphasisAs: 'hello' asText |
1757 'hello' asText allBold sameEmphasisAs: 'hello' |
1757 'hello' asText allBold sameEmphasisAs: 'hello' |
1758 'hello' asText allBold sameEmphasisAs: 'fooba' asText allBold |
1758 'hello' asText allBold sameEmphasisAs: 'fooba' asText allBold |
1759 'hello' asText allBold sameEmphasisAs: 'fooba' asText allItalic |
1759 'hello' asText allBold sameEmphasisAs: 'fooba' asText allItalic |
1760 " |
1760 " |
1761 |
1761 |
1762 |
1762 |
1763 ! |
1763 ! |
1764 |
1764 |
1769 (self string = aStringOrText string) ifFalse:[^ false]. |
1769 (self string = aStringOrText string) ifFalse:[^ false]. |
1770 self hasChangeOfEmphasis = aStringOrText hasChangeOfEmphasis ifFalse:[^ false]. |
1770 self hasChangeOfEmphasis = aStringOrText hasChangeOfEmphasis ifFalse:[^ false]. |
1771 ^ self emphasis = aStringOrText emphasis |
1771 ^ self emphasis = aStringOrText emphasis |
1772 |
1772 |
1773 " |
1773 " |
1774 'hello' asText sameEmphasisAs: 'hello' |
1774 'hello' asText sameEmphasisAs: 'hello' |
1775 'hello' asText sameEmphasisAs: 'hello' asText |
1775 'hello' asText sameEmphasisAs: 'hello' asText |
1776 'hello' asText allBold sameEmphasisAs: 'hello' |
1776 'hello' asText allBold sameEmphasisAs: 'hello' |
1777 'hello' asText allBold sameEmphasisAs: 'fooba' asText allBold |
1777 'hello' asText allBold sameEmphasisAs: 'fooba' asText allBold |
1778 'hello' asText allBold sameEmphasisAs: 'fooba' asText allItalic |
1778 'hello' asText allBold sameEmphasisAs: 'fooba' asText allItalic |
1779 |
1779 |
1780 'hello' sameEmphasisAs: 'hello' asText |
1780 'hello' sameEmphasisAs: 'hello' asText |
1781 'hello' sameEmphasisAs: 'hello' asText allBold |
1781 'hello' sameEmphasisAs: 'hello' asText allBold |
1782 'hello' sameEmphasisAs: 'fooba' |
1782 'hello' sameEmphasisAs: 'fooba' |
1783 'hello' sameEmphasisAs: 'fooba' asText |
1783 'hello' sameEmphasisAs: 'fooba' asText |
1784 'hello' sameEmphasisAs: 'fooba' asText allBold |
1784 'hello' sameEmphasisAs: 'fooba' asText allBold |
1785 'hello' sameEmphasisAs: 'fooba' asText allItalic |
1785 'hello' sameEmphasisAs: 'fooba' asText allItalic |
1786 |
1786 |
1787 'hello' asText sameStringAndEmphasisAs: 'hello' |
1787 'hello' asText sameStringAndEmphasisAs: 'hello' |
1788 'hello' asText sameStringAndEmphasisAs: 'hello' asText |
1788 'hello' asText sameStringAndEmphasisAs: 'hello' asText |
1789 'hello' asText allBold sameStringAndEmphasisAs: 'hello' |
1789 'hello' asText allBold sameStringAndEmphasisAs: 'hello' |
1790 'hello' asText allBold sameStringAndEmphasisAs: 'fooba' asText allBold |
1790 'hello' asText allBold sameStringAndEmphasisAs: 'fooba' asText allBold |
1791 'hello' asText allBold sameStringAndEmphasisAs: 'fooba' asText allItalic |
1791 'hello' asText allBold sameStringAndEmphasisAs: 'fooba' asText allItalic |
1792 |
1792 |
1793 'hello' sameStringAndEmphasisAs: 'hello' asText |
1793 'hello' sameStringAndEmphasisAs: 'hello' asText |
1794 'hello' sameStringAndEmphasisAs: 'hello' asText allBold |
1794 'hello' sameStringAndEmphasisAs: 'hello' asText allBold |
1795 'hello' sameStringAndEmphasisAs: 'fooba' |
1795 'hello' sameStringAndEmphasisAs: 'fooba' |
1796 'hello' sameStringAndEmphasisAs: 'fooba' asText |
1796 'hello' sameStringAndEmphasisAs: 'fooba' asText |
1797 'hello' sameStringAndEmphasisAs: 'fooba' asText allBold |
1797 'hello' sameStringAndEmphasisAs: 'fooba' asText allBold |
1798 'hello' sameStringAndEmphasisAs: 'fooba' asText allItalic |
1798 'hello' sameStringAndEmphasisAs: 'fooba' asText allItalic |
1799 " |
1799 " |
1800 ! ! |
1800 ! ! |
1801 |
1801 |
1802 !CharacterArray methodsFor:'converting'! |
1802 !CharacterArray methodsFor:'converting'! |
1803 |
1803 |
1808 asCollectionOfWords." |
1808 asCollectionOfWords." |
1809 |
1809 |
1810 ^ self asCollectionOfWords asArray |
1810 ^ self asCollectionOfWords asArray |
1811 |
1811 |
1812 " |
1812 " |
1813 '1 one two three four 5 five' asArrayOfSubstrings |
1813 '1 one two three four 5 five' asArrayOfSubstrings |
1814 '1 |
1814 '1 |
1815 one |
1815 one |
1816 two three four 5 five' asArrayOfSubstrings |
1816 two three four 5 five' asArrayOfSubstrings |
1817 " |
1817 " |
1818 ! |
1818 ! |
1819 |
1819 |
1820 asCollectionOfLines |
1820 asCollectionOfLines |
1821 "return a collection containing the lines (separated by cr) |
1821 "return a collection containing the lines (separated by cr) |
1822 of the receiver. If multiple cr's occur in a row, the result will |
1822 of the receiver. If multiple cr's occur in a row, the result will |
1823 contain empty strings." |
1823 contain empty strings." |
1824 |
1824 |
1825 ^ self asCollectionOfSubstringsSeparatedBy:Character cr |
1825 ^ self asCollectionOfSubstringsSeparatedBy:Character cr |
1826 |
1826 |
1827 " |
1827 " |
1828 '1 one\2 two\3 three\4 four\5 five' withCRs asCollectionOfLines |
1828 '1 one\2 two\3 three\4 four\5 five' withCRs asCollectionOfLines |
1829 '1 one\\\\2 two\3 three' withCRs asCollectionOfLines |
1829 '1 one\\\\2 two\3 three' withCRs asCollectionOfLines |
1830 " |
1830 " |
1831 ! |
1831 ! |
1832 |
1832 |
1833 asCollectionOfSubstringsSeparatedBy:aCharacter |
1833 asCollectionOfSubstringsSeparatedBy:aCharacter |
1834 "return a collection containing the lines (separated by aCharacter) |
1834 "return a collection containing the lines (separated by aCharacter) |
1835 of the receiver. If aCharacter occurs multiple times in a row, |
1835 of the receiver. If aCharacter occurs multiple times in a row, |
1836 the result will contain empty strings." |
1836 the result will contain empty strings." |
1837 |
1837 |
1838 ^ self asCollectionOfSubCollectionsSeparatedBy:aCharacter |
1838 ^ self asCollectionOfSubCollectionsSeparatedBy:aCharacter |
1839 |
1839 |
1840 " |
1840 " |
1841 '1 one:2 two:3 three:4 four:5 five' withCRs asCollectionOfSubstringsSeparatedBy:$: |
1841 '1 one:2 two:3 three:4 four:5 five' withCRs asCollectionOfSubstringsSeparatedBy:$: |
1842 '1 one 2 two 3 three 4 four 5 five' withCRs asCollectionOfSubstringsSeparatedBy:Character space |
1842 '1 one 2 two 3 three 4 four 5 five' withCRs asCollectionOfSubstringsSeparatedBy:Character space |
1843 " |
1843 " |
1844 ! |
1844 ! |
1845 |
1845 |
1846 asCollectionOfSubstringsSeparatedByAll:aSeparatorString |
1846 asCollectionOfSubstringsSeparatedByAll:aSeparatorString |
1847 "return a collection containing the lines (separated by aSeparatorString) |
1847 "return a collection containing the lines (separated by aSeparatorString) |
1848 of the receiver. If aSeparatorString occurs multiple times in a row, |
1848 of the receiver. If aSeparatorString occurs multiple times in a row, |
1849 the result will contain empty strings." |
1849 the result will contain empty strings." |
1850 |
1850 |
1851 ^ self asCollectionOfSubCollectionsSeparatedByAll:aSeparatorString |
1851 ^ self asCollectionOfSubCollectionsSeparatedByAll:aSeparatorString |
1852 |
1852 |
1853 " |
1853 " |
1854 '1::2::3::4::5::' asCollectionOfSubstringsSeparatedByAll:'::' |
1854 '1::2::3::4::5::' asCollectionOfSubstringsSeparatedByAll:'::' |
1855 " |
1855 " |
1856 ! |
1856 ! |
1857 |
1857 |
1858 asCollectionOfSubstringsSeparatedByAny:aCollectionOfSeparators |
1858 asCollectionOfSubstringsSeparatedByAny:aCollectionOfSeparators |
1859 "return a collection containing the words (separated by any character |
1859 "return a collection containing the words (separated by any character |
1862 |
1862 |
1863 ^ self asCollectionOfSubCollectionsSeparatedByAny:aCollectionOfSeparators |
1863 ^ self asCollectionOfSubCollectionsSeparatedByAny:aCollectionOfSeparators |
1864 |
1864 |
1865 " |
1865 " |
1866 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:#($:) |
1866 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:#($:) |
1867 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:':' |
1867 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:':' |
1868 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:(Array with:$: with:Character space) |
1868 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:(Array with:$: with:Character space) |
1869 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:': ' |
1869 'hello:world:isnt:this nice' asCollectionOfSubstringsSeparatedByAny:': ' |
1870 'h1e2l3l4o' asCollectionOfSubstringsSeparatedByAny:($1 to: $9) |
1870 'h1e2l3l4o' asCollectionOfSubstringsSeparatedByAny:($1 to: $9) |
1871 " |
1871 " |
1872 ! |
1872 ! |
1873 |
1873 |
1874 asCollectionOfWords |
1874 asCollectionOfWords |
1875 "return a collection containing the words (separated by whitespace) |
1875 "return a collection containing the words (separated by whitespace) |
1876 of the receiver. Multiple occurences of whitespace characters will |
1876 of the receiver. Multiple occurrences of whitespace characters will |
1877 be treated like one - i.e. whitespace is skipped." |
1877 be treated like one - i.e. whitespace is skipped." |
1878 |
1878 |
1879 |words| |
1879 |words| |
1880 |
1880 |
1881 words := OrderedCollection new. |
1881 words := OrderedCollection new. |
1890 ' ' asCollectionOfWords |
1890 ' ' asCollectionOfWords |
1891 " |
1891 " |
1892 ! |
1892 ! |
1893 |
1893 |
1894 asCollectionOfWordsDo:aBlock |
1894 asCollectionOfWordsDo:aBlock |
1895 "evaluate aBlock for each word (separated by whitespace) of the receiver. |
1895 "evaluate aBlock for each word (separated by whitespace) of the receiver. |
1896 Multiple occurences of whitespace characters will be treated like one |
1896 Multiple occurrences of whitespace characters will be treated like one |
1897 - i.e. whitespace is skipped. |
1897 - i.e. whitespace is skipped. |
1898 Returns the number of words (i.e. the number of invocations of aBlock)." |
1898 Returns the number of words (i.e. the number of invocations of aBlock)." |
1899 |
1899 |
1900 |count "{ Class:SmallInteger }" |
1900 |count "{ Class:SmallInteger }" |
1901 start "{ Class:SmallInteger }" |
1901 start "{ Class:SmallInteger }" |
1902 stop "{ Class:SmallInteger }" |
1902 stop "{ Class:SmallInteger }" |
1903 mySize "{ Class:SmallInteger }"| |
1903 mySize "{ Class:SmallInteger }"| |
1904 |
1904 |
1905 count := 0. |
1905 count := 0. |
1906 start := 1. |
1906 start := 1. |
1907 mySize := self size. |
1907 mySize := self size. |
1908 [start <= mySize] whileTrue:[ |
1908 [start <= mySize] whileTrue:[ |
1909 start := self indexOfNonSeparatorStartingAt:start. |
1909 start := self indexOfNonSeparatorStartingAt:start. |
1910 start == 0 ifTrue:[ |
1910 start == 0 ifTrue:[ |
1911 ^ count |
1911 ^ count |
1912 ]. |
1912 ]. |
1913 stop := self indexOfSeparatorStartingAt:start. |
1913 stop := self indexOfSeparatorStartingAt:start. |
1914 stop == 0 ifTrue:[ |
1914 stop == 0 ifTrue:[ |
1915 aBlock value:(self copyFrom:start to:mySize). |
1915 aBlock value:(self copyFrom:start to:mySize). |
1916 ^ count + 1 |
1916 ^ count + 1 |
1917 ]. |
1917 ]. |
1918 aBlock value:(self copyFrom:start to:(stop - 1)). |
1918 aBlock value:(self copyFrom:start to:(stop - 1)). |
1919 start := stop. |
1919 start := stop. |
1920 count := count + 1 |
1920 count := count + 1 |
1921 ]. |
1921 ]. |
1922 ^ count |
1922 ^ count |
1923 |
1923 |
1924 " |
1924 " |
1925 'hello world isnt this nice' asCollectionOfWordsDo:[:w | Transcript showCR:w] |
1925 'hello world isnt this nice' asCollectionOfWordsDo:[:w | Transcript showCR:w] |
1929 ' ' asCollectionOfWordsDo:[:w | Transcript showCR:w] |
1929 ' ' asCollectionOfWordsDo:[:w | Transcript showCR:w] |
1930 " |
1930 " |
1931 ! |
1931 ! |
1932 |
1932 |
1933 asComposedText |
1933 asComposedText |
1934 "ST-80 compatibility |
1934 "ST-80 compatibility |
1935 - ST/X does not (as today) support composedTexts." |
1935 - ST/X does not (as today) support composedTexts." |
1936 |
1936 |
1937 ^ ComposedText fromString:self string |
1937 ^ ComposedText fromString:self string |
1938 |
1938 |
1939 "Modified: 27.4.1996 / 13:30:30 / cg" |
1939 "Modified: 27.4.1996 / 13:30:30 / cg" |
1947 "Modified: 20.5.1996 / 09:38:15 / cg" |
1947 "Modified: 20.5.1996 / 09:38:15 / cg" |
1948 ! |
1948 ! |
1949 |
1949 |
1950 asFixedPoint |
1950 asFixedPoint |
1951 "read a fixedPoint number from the receiver. |
1951 "read a fixedPoint number from the receiver. |
1952 Notice, that errors may occur during the read, |
1952 Notice, that errors may occur during the read, |
1953 so you better setup some signal handler when using this method." |
1953 so you better setup some signal handler when using this method." |
1954 |
1954 |
1955 ^ FixedPoint readFromString:self |
1955 ^ FixedPoint readFromString:self |
1956 |
1956 |
1957 " |
1957 " |
1958 '0.123' asFixedPoint |
1958 '0.123' asFixedPoint |
1959 '12345' asFixedPoint |
1959 '12345' asFixedPoint |
1960 '(1/5)' asFixedPoint |
1960 '(1/5)' asFixedPoint |
1961 'foo' asFixedPoint |
1961 'foo' asFixedPoint |
1962 Object errorSignal handle:[:ex | ex return:0] do:['foo' asFixedPoint] |
1962 Object errorSignal handle:[:ex | ex return:0] do:['foo' asFixedPoint] |
1963 " |
1963 " |
1964 |
1964 |
1965 "Modified: / 25.10.1997 / 15:19:00 / cg" |
1965 "Modified: / 25.10.1997 / 15:19:00 / cg" |
1966 ! |
1966 ! |
1967 |
1967 |
1968 asFixedPoint:scale |
1968 asFixedPoint:scale |
1969 "read a fixedPoint number with scale number of post-decimal digits |
1969 "read a fixedPoint number with scale number of post-decimal digits |
1970 from the receiver. Scale controls the number of displayed digits, |
1970 from the receiver. Scale controls the number of displayed digits, |
1971 not the number of actually valid digits. |
1971 not the number of actually valid digits. |
1972 Notice, that errors may occur during the read, |
1972 Notice, that errors may occur during the read, |
1973 so you better setup some signal handler when using this method." |
1973 so you better setup some signal handler when using this method." |
1974 |
1974 |
1975 ^ (FixedPoint readFromString:self) scale:scale |
1975 ^ (FixedPoint readFromString:self) scale:scale |
1976 |
1976 |
1977 " |
1977 " |
1978 '0.123' asFixedPoint:2 |
1978 '0.123' asFixedPoint:2 |
1979 '123456' asFixedPoint:2 |
1979 '123456' asFixedPoint:2 |
1980 ('3.14157' asFixedPoint:1) asFixedPoint:5 |
1980 ('3.14157' asFixedPoint:1) asFixedPoint:5 |
1981 '3.14157' asFixedPoint:2 |
1981 '3.14157' asFixedPoint:2 |
1982 'foo' asFixedPoint:2 |
1982 'foo' asFixedPoint:2 |
1983 " |
1983 " |
1984 |
1984 |
1985 "Modified: / 25.10.1997 / 15:21:57 / cg" |
1985 "Modified: / 25.10.1997 / 15:21:57 / cg" |
1986 ! |
1986 ! |
1987 |
1987 |
1988 asFloat |
1988 asFloat |
1989 "read a float number from the receiver. |
1989 "read a float number from the receiver. |
1990 Notice, that errors may occur during the read, |
1990 Notice, that errors may occur during the read, |
1991 so you better setup some exception handler when using this method." |
1991 so you better setup some exception handler when using this method." |
1992 |
1992 |
1993 ^ (Number readFromString:self) asFloat |
1993 ^ (Number readFromString:self) asFloat |
1994 |
1994 |
1995 " |
1995 " |
1996 '0.123' asFloat |
1996 '0.123' asFloat |
1997 '12345' asFloat |
1997 '12345' asFloat |
1998 '(1/5)' asFloat |
1998 '(1/5)' asFloat |
1999 Object errorSignal handle:[:ex | ex return:0] do:['foo' asFloat] |
1999 Object errorSignal handle:[:ex | ex return:0] do:['foo' asFloat] |
2000 " |
2000 " |
2001 ! |
2001 ! |
2002 |
2002 |
2003 asInteger |
2003 asInteger |
2004 "read an integer from the receiver. |
2004 "read an integer from the receiver. |
2005 Notice, that errors may occur during the read, |
2005 Notice, that errors may occur during the read, |
2006 so you better setup some exception handler when using this method." |
2006 so you better setup some exception handler when using this method." |
2007 |
2007 |
2008 ^ Integer readFromString:self |
2008 ^ Integer readFromString:self |
2009 |
2009 |
2010 " |
2010 " |
2011 '12345678901234567890' asInteger |
2011 '12345678901234567890' asInteger |
2012 '-1234' asInteger |
2012 '-1234' asInteger |
2013 '0.123' asInteger <- reader stops at ., returning 0 here |
2013 '0.123' asInteger <- reader stops at ., returning 0 here |
2014 '0.123' asNumber <- returns what you expect |
2014 '0.123' asNumber <- returns what you expect |
2015 Object errorSignal handle:[:ex | ex return:0] do:['foo' asInteger] |
2015 Object errorSignal handle:[:ex | ex return:0] do:['foo' asInteger] |
2016 " |
2016 " |
2017 ! |
2017 ! |
2018 |
2018 |
2019 asLowercase |
2019 asLowercase |
2020 "return a copy of myself in lowercase letters" |
2020 "return a copy of myself in lowercase letters" |
2025 mySize := self size. |
2025 mySize := self size. |
2026 newStr := self species new:mySize. |
2026 newStr := self species new:mySize. |
2027 bitsPerCharacter := newStr bitsPerCharacter. |
2027 bitsPerCharacter := newStr bitsPerCharacter. |
2028 |
2028 |
2029 1 to:mySize do:[:i | |
2029 1 to:mySize do:[:i | |
2030 c := (self at:i) asLowercase. |
2030 c := (self at:i) asLowercase. |
2031 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2031 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2032 newStr := c stringSpecies fromString:newStr. |
2032 newStr := c stringSpecies fromString:newStr. |
2033 ]. |
2033 ]. |
2034 newStr at:i put:c |
2034 newStr at:i put:c |
2035 ]. |
2035 ]. |
2036 ^ newStr |
2036 ^ newStr |
2037 |
2037 |
2038 " |
2038 " |
2039 'HelloWorld' asLowercase |
2039 'HelloWorld' asLowercase |
2040 'HelloWorld' asLowercaseFirst |
2040 'HelloWorld' asLowercaseFirst |
2041 " |
2041 " |
2042 ! |
2042 ! |
2043 |
2043 |
2044 asLowercaseFirst |
2044 asLowercaseFirst |
2045 "return a copy of myself where the first character is converted to lowercase." |
2045 "return a copy of myself where the first character is converted to lowercase." |
2049 firstChar := (self at:1). |
2049 firstChar := (self at:1). |
2050 firstCharAsLowercase := firstChar asLowercase. |
2050 firstCharAsLowercase := firstChar asLowercase. |
2051 firstChar == firstCharAsLowercase ifTrue:[ ^ self]. |
2051 firstChar == firstCharAsLowercase ifTrue:[ ^ self]. |
2052 |
2052 |
2053 firstCharAsLowercase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2053 firstCharAsLowercase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2054 newString := firstCharAsLowercase stringSpecies fromString:self. |
2054 newString := firstCharAsLowercase stringSpecies fromString:self. |
2055 ] ifFalse:[ |
2055 ] ifFalse:[ |
2056 newString := self stringSpecies fromString:self. |
2056 newString := self stringSpecies fromString:self. |
2057 ]. |
2057 ]. |
2058 newString at:1 put:firstCharAsLowercase. |
2058 newString at:1 put:firstCharAsLowercase. |
2059 ^ newString |
2059 ^ newString |
2060 |
2060 |
2061 " |
2061 " |
2062 'HelloWorld' asLowercase |
2062 'HelloWorld' asLowercase |
2063 'HelloWorld' asLowercaseFirst |
2063 'HelloWorld' asLowercaseFirst |
2064 " |
2064 " |
2065 ! |
2065 ! |
2066 |
2066 |
2067 asNumber |
2067 asNumber |
2068 "read a number from the receiver. |
2068 "read a number from the receiver. |
2069 Notice, that (in contrast to ST-80) errors may occur during the read, |
2069 Notice, that (in contrast to ST-80) errors may occur during the read, |
2070 so you better setup some signal handler when using this method. |
2070 so you better setup some signal handler when using this method. |
2071 This may change if ANSI specifies it." |
2071 This may change if ANSI specifies it." |
2072 |
2072 |
2073 "/ ST-80 behavior: |
2073 "/ ST-80 behavior: |
2074 "/ ^ Number readFromString:self onError:0 |
2074 "/ ^ Number readFromString:self onError:0 |
2078 " |
2078 " |
2079 '123' asNumber |
2079 '123' asNumber |
2080 '123.567' asNumber |
2080 '123.567' asNumber |
2081 '(5/6)' asNumber |
2081 '(5/6)' asNumber |
2082 'foo' asNumber |
2082 'foo' asNumber |
2083 Object errorSignal handle:[:ex | ex returnWith:0] do:['foo' asNumber] |
2083 Object errorSignal handle:[:ex | ex returnWith:0] do:['foo' asNumber] |
2084 " |
2084 " |
2085 ! |
2085 ! |
2086 |
2086 |
2087 asNumberFromFormatString:ignored |
2087 asNumberFromFormatString:ignored |
2088 "read a number from the receiver, ignoring any nonDigit characters. |
2088 "read a number from the receiver, ignoring any nonDigit characters. |
2141 |
2141 |
2142 |newString| |
2142 |newString| |
2143 |
2143 |
2144 newString := String new:(self size). |
2144 newString := String new:(self size). |
2145 1 to:self size do:[:idx | |
2145 1 to:self size do:[:idx | |
2146 |char| |
2146 |char| |
2147 |
2147 |
2148 char := self at:idx. |
2148 char := self at:idx. |
2149 char codePoint <= 16rFF ifTrue:[ |
2149 char codePoint <= 16rFF ifTrue:[ |
2150 newString at:idx put:char |
2150 newString at:idx put:char |
2151 ] ifFalse:[ |
2151 ] ifFalse:[ |
2152 newString at:idx put:replacementCharacter |
2152 newString at:idx put:replacementCharacter |
2153 ]. |
2153 ]. |
2154 ]. |
2154 ]. |
2155 ^ newString |
2155 ^ newString |
2156 |
2156 |
2157 "Created: 30.6.1997 / 13:02:14 / cg" |
2157 "Created: 30.6.1997 / 13:02:14 / cg" |
2158 ! |
2158 ! |
2167 |s d ch last lch n codes sc| |
2167 |s d ch last lch n codes sc| |
2168 |
2168 |
2169 s := self readStream. |
2169 s := self readStream. |
2170 s skipSeparators. |
2170 s skipSeparators. |
2171 s atEnd ifTrue:[ |
2171 s atEnd ifTrue:[ |
2172 ^ nil |
2172 ^ nil |
2173 ]. |
2173 ]. |
2174 ch := s next. |
2174 ch := s next. |
2175 ch isLetter ifFalse:[ |
2175 ch isLetter ifFalse:[ |
2176 ^ nil |
2176 ^ nil |
2177 ]. |
2177 ]. |
2178 n := 0. |
2178 n := 0. |
2179 |
2179 |
2180 codes := Dictionary new. |
2180 codes := Dictionary new. |
2181 codes atAll:'bpfv' put:$1. |
2181 codes atAll:'bpfv' put:$1. |
2184 codes at:$l put:$4. |
2184 codes at:$l put:$4. |
2185 codes atAll:'nm' put:$5. |
2185 codes atAll:'nm' put:$5. |
2186 codes at:$r put:$6. |
2186 codes at:$r put:$6. |
2187 |
2187 |
2188 d := String writeStream. |
2188 d := String writeStream. |
2189 d nextPut:(ch asUppercase). |
2189 d nextPut:(ch asUppercase). |
2190 |
2190 |
2191 [s atEnd] whileFalse:[ |
2191 [s atEnd] whileFalse:[ |
2192 ch := s next. |
2192 ch := s next. |
2193 lch := ch asLowercase. |
2193 lch := ch asLowercase. |
2194 lch = last ifFalse:[ |
2194 lch = last ifFalse:[ |
2195 last := lch. |
2195 last := lch. |
2196 |
2196 |
2197 sc := codes at:ch ifAbsent:nil. |
2197 sc := codes at:ch ifAbsent:nil. |
2198 sc notNil ifTrue:[ |
2198 sc notNil ifTrue:[ |
2199 n < 3 ifTrue:[ |
2199 n < 3 ifTrue:[ |
2200 d nextPut:sc. |
2200 d nextPut:sc. |
2201 n := n + 1. |
2201 n := n + 1. |
2202 ] |
2202 ] |
2203 ] ifFalse:[ |
2203 ] ifFalse:[ |
2204 "/ ch isLetter ifFalse:[ |
2204 "/ ch isLetter ifFalse:[ |
2205 "/ "/ something else - ignore it |
2205 "/ "/ something else - ignore it |
2206 "/ ] ifTrue:[ |
2206 "/ ] ifTrue:[ |
2207 "/ "/ else its a vowel and we ignore it |
2207 "/ "/ else its a vowel and we ignore it |
2208 "/ ] |
2208 "/ ] |
2209 ]. |
2209 ]. |
2210 ] |
2210 ] |
2211 ]. |
2211 ]. |
2212 [ n < 3 ] whileTrue:[ |
2212 [ n < 3 ] whileTrue:[ |
2213 d nextPut:$0. |
2213 d nextPut:$0. |
2214 n := n + 1. |
2214 n := n + 1. |
2215 ]. |
2215 ]. |
2216 |
2216 |
2217 ^ d contents |
2217 ^ d contents |
2218 |
2218 |
2219 " |
2219 " |
2220 'claus' asSoundexCode |
2220 'claus' asSoundexCode |
2221 'clause' asSoundexCode |
2221 'clause' asSoundexCode |
2222 'close' asSoundexCode |
2222 'close' asSoundexCode |
2223 'smalltalk' asSoundexCode |
2223 'smalltalk' asSoundexCode |
2224 'smaltalk' asSoundexCode |
2224 'smaltalk' asSoundexCode |
2225 'smaltak' asSoundexCode |
2225 'smaltak' asSoundexCode |
2226 'smaltok' asSoundexCode |
2226 'smaltok' asSoundexCode |
2227 'smoltok' asSoundexCode |
2227 'smoltok' asSoundexCode |
2228 'aa' asSoundexCode |
2228 'aa' asSoundexCode |
2229 'by' asSoundexCode |
2229 'by' asSoundexCode |
2230 'bab' asSoundexCode |
2230 'bab' asSoundexCode |
2231 'bob' asSoundexCode |
2231 'bob' asSoundexCode |
2232 'bop' asSoundexCode |
2232 'bop' asSoundexCode |
2233 " |
2233 " |
2234 ! |
2234 ! |
2235 |
2235 |
2236 asString |
2236 asString |
2237 "return myself - I am a string" |
2237 "return myself - I am a string" |
2261 |
2261 |
2262 asSymbolIfInterned |
2262 asSymbolIfInterned |
2263 "if a symbol with the receivers characters is already known, return it. |
2263 "if a symbol with the receivers characters is already known, return it. |
2264 Otherwise, return nil. This can be used to query for an existing |
2264 Otherwise, return nil. This can be used to query for an existing |
2265 symbol and is the same as |
2265 symbol and is the same as |
2266 self knownAsSymbol ifTrue:[self asSymbol] ifFalse:[nil] |
2266 self knownAsSymbol ifTrue:[self asSymbol] ifFalse:[nil] |
2267 but slightly faster, since the symbol lookup operation is only performed once. |
2267 but slightly faster, since the symbol lookup operation is only performed once. |
2268 The receiver must be a singleByte-String. |
2268 The receiver must be a singleByte-String. |
2269 TwoByte- and FourByteSymbols are (currently ?) not allowed." |
2269 TwoByte- and FourByteSymbols are (currently ?) not allowed." |
2270 |
2270 |
2271 |s| |
2271 |s| |
2281 ! |
2281 ! |
2282 |
2282 |
2283 asText |
2283 asText |
2284 "return a Text-object (collection of lines) from myself." |
2284 "return a Text-object (collection of lines) from myself." |
2285 |
2285 |
2286 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2286 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2287 Text isNil ifTrue:[^ self]. |
2287 Text isNil ifTrue:[^ self]. |
2288 ^ Text fromString:self |
2288 ^ Text fromString:self |
2289 |
2289 |
2290 "Created: 12.5.1996 / 10:41:14 / cg" |
2290 "Created: 12.5.1996 / 10:41:14 / cg" |
2291 ! |
2291 ! |
2301 mySize := self size. |
2301 mySize := self size. |
2302 newStr := self species new:mySize. |
2302 newStr := self species new:mySize. |
2303 bitsPerCharacter := newStr bitsPerCharacter. |
2303 bitsPerCharacter := newStr bitsPerCharacter. |
2304 |
2304 |
2305 1 to:mySize do:[:i | |
2305 1 to:mySize do:[:i | |
2306 i == 1 ifTrue:[ |
2306 i == 1 ifTrue:[ |
2307 c := (self at:i) asTitlecase. |
2307 c := (self at:i) asTitlecase. |
2308 ] ifFalse:[ |
2308 ] ifFalse:[ |
2309 c := (self at:i) asLowercase. |
2309 c := (self at:i) asLowercase. |
2310 ]. |
2310 ]. |
2311 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2311 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2312 newStr := c stringSpecies fromString:newStr. |
2312 newStr := c stringSpecies fromString:newStr. |
2313 ]. |
2313 ]. |
2314 newStr at:i put:c |
2314 newStr at:i put:c |
2315 ]. |
2315 ]. |
2316 ^ newStr |
2316 ^ newStr |
2317 |
2317 |
2318 " |
2318 " |
2319 'helloWorld' asTitlecase |
2319 'helloWorld' asTitlecase |
2320 'HelloWorld' asTitlecase |
2320 'HelloWorld' asTitlecase |
2321 'HELLOWORLD' asTitlecase |
2321 'HELLOWORLD' asTitlecase |
2322 'helloworld' asTitlecase |
2322 'helloworld' asTitlecase |
2323 " |
2323 " |
2324 ! |
2324 ! |
2325 |
2325 |
2326 asTitlecaseFirst |
2326 asTitlecaseFirst |
2327 "return a version of the receiver, where the first character is converted to titlecase. |
2327 "return a version of the receiver, where the first character is converted to titlecase. |
2329 (2-character glyphs), which consist of an upper- and lower-case characters. |
2329 (2-character glyphs), which consist of an upper- and lower-case characters. |
2330 If the first character is already titlecase, or there is no titlecasepercase for it, return the |
2330 If the first character is already titlecase, or there is no titlecasepercase for it, return the |
2331 receiver." |
2331 receiver." |
2332 |
2332 |
2333 " |
2333 " |
2334 For example, in Unicode, character U+01F3 is LATIN SMALL LETTER DZ. |
2334 For example, in Unicode, character U+01F3 is LATIN SMALL LETTER DZ. |
2335 (Let us write this compound character using ASCII as 'dz'.) |
2335 (Let us write this compound character using ASCII as 'dz'.) |
2336 This character uppercases to character U+01F1, LATIN CAPITAL LETTER DZ. |
2336 This character uppercases to character U+01F1, LATIN CAPITAL LETTER DZ. |
2337 (Which is basically 'DZ'.) |
2337 (Which is basically 'DZ'.) |
2338 But it titlecases to to character U+01F2, LATIN CAPITAL LETTER D WITH SMALL LETTER Z. |
2338 But it titlecases to to character U+01F2, LATIN CAPITAL LETTER D WITH SMALL LETTER Z. |
2339 (Which we can write 'Dz'.) |
2339 (Which we can write 'Dz'.) |
2340 |
2340 |
2341 character uppercase titlecase |
2341 character uppercase titlecase |
2342 --------- --------- --------- |
2342 --------- --------- --------- |
2343 dz DZ Dz |
2343 dz DZ Dz |
2348 firstChar := (self at:1). |
2348 firstChar := (self at:1). |
2349 firstCharAsTitlecase := firstChar asTitlecase. |
2349 firstCharAsTitlecase := firstChar asTitlecase. |
2350 firstChar == firstCharAsTitlecase ifTrue:[ ^ self]. |
2350 firstChar == firstCharAsTitlecase ifTrue:[ ^ self]. |
2351 |
2351 |
2352 firstCharAsTitlecase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2352 firstCharAsTitlecase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2353 newString := firstCharAsTitlecase stringSpecies fromString:self. |
2353 newString := firstCharAsTitlecase stringSpecies fromString:self. |
2354 ] ifFalse:[ |
2354 ] ifFalse:[ |
2355 newString := self stringSpecies fromString:self. |
2355 newString := self stringSpecies fromString:self. |
2356 ]. |
2356 ]. |
2357 newString at:1 put:firstCharAsTitlecase. |
2357 newString at:1 put:firstCharAsTitlecase. |
2358 ^ newString |
2358 ^ newString |
2359 |
2359 |
2360 " |
2360 " |
2361 'helloWorld' asTitlecaseFirst |
2361 'helloWorld' asTitlecaseFirst |
2362 'HelloWorld' asTitlecaseFirst |
2362 'HelloWorld' asTitlecaseFirst |
2363 " |
2363 " |
2364 ! |
2364 ! |
2365 |
2365 |
2366 asTwoByteString |
2366 asTwoByteString |
2367 "return the receiver converted to a two-byte string. |
2367 "return the receiver converted to a two-byte string. |
2371 ! |
2371 ! |
2372 |
2372 |
2373 asURI |
2373 asURI |
2374 "return an URI with string taken from the receiver" |
2374 "return an URI with string taken from the receiver" |
2375 |
2375 |
2376 ^ URI fromString:self |
2376 ^ URI fromString:self |
2377 ! |
2377 ! |
2378 |
2378 |
2379 asURL |
2379 asURL |
2380 "return an URL-object from myself." |
2380 "return an URL-object from myself." |
2381 |
2381 |
2382 ^ URL fromString:self |
2382 ^ URL fromString:self |
2383 |
2383 |
2384 " |
2384 " |
2385 'http://www.exept.de:80/index.html' asURL host |
2385 'http://www.exept.de:80/index.html' asURL host |
2386 'http://www.exept.de:80/index.html' asURL port |
2386 'http://www.exept.de:80/index.html' asURL port |
2387 'http://www.exept.de:80/index.html' asURL method |
2387 'http://www.exept.de:80/index.html' asURL method |
2388 'http://www.exept.de:80/index.html' asURL path |
2388 'http://www.exept.de:80/index.html' asURL path |
2389 " |
2389 " |
2390 ! |
2390 ! |
2391 |
2391 |
2392 asUnicode16String |
2392 asUnicode16String |
2393 "thats not really true - characters above ascii 16r7F may need special treatment" |
2393 "thats not really true - characters above ascii 16r7F may need special treatment" |
2416 mySize := self size. |
2416 mySize := self size. |
2417 newStr := self species new:mySize. |
2417 newStr := self species new:mySize. |
2418 bitsPerCharacter := newStr bitsPerCharacter. |
2418 bitsPerCharacter := newStr bitsPerCharacter. |
2419 |
2419 |
2420 1 to:mySize do:[:i | |
2420 1 to:mySize do:[:i | |
2421 c := (self at:i) asUppercase. |
2421 c := (self at:i) asUppercase. |
2422 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2422 c bitsPerCharacter > bitsPerCharacter ifTrue:[ |
2423 newStr := c stringSpecies fromString:newStr. |
2423 newStr := c stringSpecies fromString:newStr. |
2424 ]. |
2424 ]. |
2425 newStr at:i put:c |
2425 newStr at:i put:c |
2426 ]. |
2426 ]. |
2427 ^ newStr |
2427 ^ newStr |
2428 |
2428 |
2429 " |
2429 " |
2430 'helloWorld' asUppercase |
2430 'helloWorld' asUppercase |
2431 'helloWorld' asUppercaseFirst |
2431 'helloWorld' asUppercaseFirst |
2432 (Character value:16rB5) asString asUppercase -- needs 16 bits !! |
2432 (Character value:16rB5) asString asUppercase -- needs 16 bits !! |
2433 " |
2433 " |
2434 ! |
2434 ! |
2435 |
2435 |
2436 asUppercaseFirst |
2436 asUppercaseFirst |
2443 firstChar := (self at:1). |
2443 firstChar := (self at:1). |
2444 firstCharAsUppercase := firstChar asUppercase. |
2444 firstCharAsUppercase := firstChar asUppercase. |
2445 firstChar == firstCharAsUppercase ifTrue:[ ^ self]. |
2445 firstChar == firstCharAsUppercase ifTrue:[ ^ self]. |
2446 |
2446 |
2447 firstCharAsUppercase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2447 firstCharAsUppercase bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2448 newString := firstCharAsUppercase stringSpecies fromString:self. |
2448 newString := firstCharAsUppercase stringSpecies fromString:self. |
2449 ] ifFalse:[ |
2449 ] ifFalse:[ |
2450 newString := self stringSpecies fromString:self. |
2450 newString := self stringSpecies fromString:self. |
2451 ]. |
2451 ]. |
2452 newString at:1 put:firstCharAsUppercase. |
2452 newString at:1 put:firstCharAsUppercase. |
2453 ^ newString |
2453 ^ newString |
2454 |
2454 |
2455 " |
2455 " |
2456 'helloWorld' asUppercase |
2456 'helloWorld' asUppercase |
2457 'helloWorld' asUppercaseFirst |
2457 'helloWorld' asUppercaseFirst |
2458 'HelloWorld' asUppercaseFirst |
2458 'HelloWorld' asUppercaseFirst |
2459 " |
2459 " |
2460 ! |
2460 ! |
2461 |
2461 |
2462 string |
2462 string |
2463 "return the receiver - for ST-80 compatibility" |
2463 "return the receiver - for ST-80 compatibility" |
2487 This is nonStandard, but convenient" |
2487 This is nonStandard, but convenient" |
2488 |
2488 |
2489 |myWidth otherWidth| |
2489 |myWidth otherWidth| |
2490 |
2490 |
2491 aStringOrCharacter isCharacter ifTrue:[ |
2491 aStringOrCharacter isCharacter ifTrue:[ |
2492 ^ self copyWith:aStringOrCharacter |
2492 ^ self copyWith:aStringOrCharacter |
2493 ]. |
2493 ]. |
2494 aStringOrCharacter isText ifTrue:[ |
2494 aStringOrCharacter isText ifTrue:[ |
2495 ^ aStringOrCharacter concatenateFromString:self |
2495 ^ aStringOrCharacter concatenateFromString:self |
2496 ]. |
2496 ]. |
2497 aStringOrCharacter isString ifTrue:[ |
2497 aStringOrCharacter isString ifTrue:[ |
2498 (otherWidth := aStringOrCharacter bitsPerCharacter) ~~ (myWidth := self bitsPerCharacter) ifTrue:[ |
2498 (otherWidth := aStringOrCharacter bitsPerCharacter) ~~ (myWidth := self bitsPerCharacter) ifTrue:[ |
2499 otherWidth > myWidth ifTrue:[ |
2499 otherWidth > myWidth ifTrue:[ |
2500 ^ (aStringOrCharacter species fromString:self) , aStringOrCharacter |
2500 ^ (aStringOrCharacter species fromString:self) , aStringOrCharacter |
2501 ]. |
2501 ]. |
2502 ^ self , (self species fromString:aStringOrCharacter) |
2502 ^ self , (self species fromString:aStringOrCharacter) |
2503 ]. |
2503 ]. |
2504 ]. |
2504 ]. |
2505 ^ super , aStringOrCharacter |
2505 ^ super , aStringOrCharacter |
2506 |
2506 |
2507 " |
2507 " |
2508 'hello' , $1 |
2508 'hello' , $1 |
2509 'hello' , '1' |
2509 'hello' , '1' |
2510 'hello' , (' world' asText allBold) |
2510 'hello' , (' world' asText allBold) |
2511 'hello' , (JISEncodedString fromString:' world') |
2511 'hello' , (JISEncodedString fromString:' world') |
2512 (JISEncodedString fromString:'hello') , ' world' |
2512 (JISEncodedString fromString:'hello') , ' world' |
2513 |
2513 |
2514 Transcript showCR: |
2514 Transcript showCR: |
2515 (Text string:'hello' emphasis:#italic) , (Text string:' world' emphasis:#bold) |
2515 (Text string:'hello' emphasis:#italic) , (Text string:' world' emphasis:#bold) |
2516 " |
2516 " |
2517 |
2517 |
2518 "Modified: 28.6.1997 / 00:13:17 / cg" |
2518 "Modified: 28.6.1997 / 00:13:17 / cg" |
2519 ! |
2519 ! |
2520 |
2520 |
2554 |tmpStream idx idx1| |
2554 |tmpStream idx idx1| |
2555 |
2555 |
2556 tmpStream := WriteStream on:(self class new). |
2556 tmpStream := WriteStream on:(self class new). |
2557 idx := 1. |
2557 idx := 1. |
2558 [idx ~~ 0] whileTrue:[ |
2558 [idx ~~ 0] whileTrue:[ |
2559 idx1 := idx. |
2559 idx1 := idx. |
2560 idx := self indexOfSubCollection:subString startingAt:idx. |
2560 idx := self indexOfSubCollection:subString startingAt:idx. |
2561 idx ~~ 0 ifTrue:[ |
2561 idx ~~ 0 ifTrue:[ |
2562 tmpStream nextPutAll:(self copyFrom:idx1 to:idx-1). |
2562 tmpStream nextPutAll:(self copyFrom:idx1 to:idx-1). |
2563 tmpStream nextPutAll:newString. |
2563 tmpStream nextPutAll:newString. |
2564 idx := idx + subString size |
2564 idx := idx + subString size |
2565 ] |
2565 ] |
2566 ]. |
2566 ]. |
2567 tmpStream nextPutAll:(self copyFrom:idx1). |
2567 tmpStream nextPutAll:(self copyFrom:idx1). |
2568 ^ tmpStream contents |
2568 ^ tmpStream contents |
2569 |
2569 |
2570 " |
2570 " |
2571 '12345678901234567890' replString:'123' withString:'OneTwoThree' |
2571 '12345678901234567890' replString:'123' withString:'OneTwoThree' |
2572 '12345678901234567890' replString:'123' withString:'*' |
2572 '12345678901234567890' replString:'123' withString:'*' |
2573 '12345678901234567890' replString:'234' withString:'foo' |
2573 '12345678901234567890' replString:'234' withString:'foo' |
2574 |
2574 |
2575 ('a string with spaces' replChar:$ withString:' foo ') |
2575 ('a string with spaces' replChar:$ withString:' foo ') |
2576 replString:'foo' withString:'bar' |
2576 replString:'foo' withString:'bar' |
2577 " |
2577 " |
2578 |
2578 |
2579 "Modified: / 31-05-1999 / 12:33:59 / cg" |
2579 "Modified: / 31-05-1999 / 12:33:59 / cg" |
2580 "Created: / 12-05-2004 / 12:00:00 / cg" |
2580 "Created: / 12-05-2004 / 12:00:00 / cg" |
2581 ! |
2581 ! |
2582 |
2582 |
2583 copyWith:aCharacter |
2583 copyWith:aCharacter |
2584 "return a new string containing the receivers characters |
2584 "return a new string containing the receivers characters |
2585 and the single new character, aCharacter. |
2585 and the single new character, aCharacter. |
2586 This is different from concatentation, which expects another string |
2586 This is different from concatentation, which expects another string |
2587 as argument, but equivalent to copy-and-addLast. |
2587 as argument, but equivalent to copy-and-addLast. |
2588 The code below cares for different width characters |
2588 The code below cares for different width characters |
2589 (i.e. when appending a 16bit char to an 8bit string)" |
2589 (i.e. when appending a 16bit char to an 8bit string)" |
2590 |
2590 |
2591 |sz newString| |
2591 |sz newString| |
2592 |
2592 |
2593 aCharacter bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2593 aCharacter bitsPerCharacter > self bitsPerCharacter ifTrue:[ |
2594 sz := self size. |
2594 sz := self size. |
2595 newString := aCharacter stringSpecies new:sz + 1. |
2595 newString := aCharacter stringSpecies new:sz + 1. |
2596 newString replaceFrom:1 to:sz with:self startingAt:1. |
2596 newString replaceFrom:1 to:sz with:self startingAt:1. |
2597 newString at:sz+1 put:aCharacter. |
2597 newString at:sz+1 put:aCharacter. |
2598 ^ newString. |
2598 ^ newString. |
2599 ]. |
2599 ]. |
2600 ^ super copyWith:aCharacter |
2600 ^ super copyWith:aCharacter |
2601 ! ! |
2601 ! ! |
2602 |
2602 |
2603 !CharacterArray methodsFor:'displaying'! |
2603 !CharacterArray methodsFor:'displaying'! |
2618 |
2618 |
2619 |s| |
2619 |s| |
2620 |
2620 |
2621 s := self string. |
2621 s := self string. |
2622 opaque ifTrue:[ |
2622 opaque ifTrue:[ |
2623 aGc displayOpaqueString:s x:x y:y. |
2623 aGc displayOpaqueString:s x:x y:y. |
2624 ] ifFalse:[ |
2624 ] ifFalse:[ |
2625 aGc displayString:s x:x y:y. |
2625 aGc displayString:s x:x y:y. |
2626 ]. |
2626 ]. |
2627 |
2627 |
2628 "Modified: 11.5.1996 / 14:42:48 / cg" |
2628 "Modified: 11.5.1996 / 14:42:48 / cg" |
2629 ! |
2629 ! |
2630 |
2630 |
2642 !CharacterArray methodsFor:'emphasis'! |
2642 !CharacterArray methodsFor:'emphasis'! |
2643 |
2643 |
2644 allBold |
2644 allBold |
2645 "return a test object representing the receiver, but all boldified" |
2645 "return a test object representing the receiver, but all boldified" |
2646 |
2646 |
2647 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2647 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2648 Text isNil ifTrue:[^ self]. |
2648 Text isNil ifTrue:[^ self]. |
2649 ^ self asText allBold |
2649 ^ self asText allBold |
2650 |
2650 |
2651 " |
2651 " |
2652 Transcript showCR:'hello' asText allBold |
2652 Transcript showCR:'hello' asText allBold |
2655 ! |
2655 ! |
2656 |
2656 |
2657 allItalic |
2657 allItalic |
2658 "return a test object representing the receiver, but all in italic" |
2658 "return a test object representing the receiver, but all in italic" |
2659 |
2659 |
2660 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2660 "this test allows for small non-gui apps to be built without libbasic2 (where Text is)" |
2661 Text isNil ifTrue:[^ self]. |
2661 Text isNil ifTrue:[^ self]. |
2662 ^ self asText allItalic |
2662 ^ self asText allItalic |
2663 |
2663 |
2664 " |
2664 " |
2665 Transcript showCR:'hello' asText allItalic |
2665 Transcript showCR:'hello' asText allItalic |
2745 ! ! |
2745 ! ! |
2746 |
2746 |
2747 !CharacterArray methodsFor:'encoding & decoding'! |
2747 !CharacterArray methodsFor:'encoding & decoding'! |
2748 |
2748 |
2749 decodeFrom:encodingSymbol |
2749 decodeFrom:encodingSymbol |
2750 "given the receiver encoded as described by encodingSymbol, |
2750 "given the receiver encoded as described by encodingSymbol, |
2751 convert it into internal ST/X (unicode) encoding and return a corresponding CharacterArray." |
2751 convert it into internal ST/X (unicode) encoding and return a corresponding CharacterArray." |
2752 |
2752 |
2753 |myEncoding encoder| |
2753 |myEncoding encoder| |
2754 |
2754 |
2755 encodingSymbol isNil ifTrue:[^ self]. |
2755 encodingSymbol isNil ifTrue:[^ self]. |
2764 encodeFrom:oldEncoding into:newEncoding |
2764 encodeFrom:oldEncoding into:newEncoding |
2765 ^ CharacterEncoder encodeString:self from:oldEncoding into:newEncoding |
2765 ^ CharacterEncoder encodeString:self from:oldEncoding into:newEncoding |
2766 ! |
2766 ! |
2767 |
2767 |
2768 rot13 |
2768 rot13 |
2769 "Usenet: from `rotate alphabet 13 places'] |
2769 "Usenet: from `rotate alphabet 13 places'] |
2770 The simple Caesar-cypher encryption that replaces each English |
2770 The simple Caesar-cypher encryption that replaces each English |
2771 letter with the one 13 places forward or back along the alphabet, |
2771 letter with the one 13 places forward or back along the alphabet, |
2772 so that 'The butler did it!!' becomes 'Gur ohgyre qvq vg!!' |
2772 so that 'The butler did it!!' becomes 'Gur ohgyre qvq vg!!' |
2773 Most Usenet news reading and posting programs include a rot13 feature. |
2773 Most Usenet news reading and posting programs include a rot13 feature. |
2774 It is used to enclose the text in a sealed wrapper that the reader must choose |
2774 It is used to enclose the text in a sealed wrapper that the reader must choose |
2775 to open -- e.g., for posting things that might offend some readers, or spoilers. |
2775 to open -- e.g., for posting things that might offend some readers, or spoilers. |
2776 A major advantage of rot13 over rot(N) for other N is that it |
2776 A major advantage of rot13 over rot(N) for other N is that it |
2777 is self-inverse, so the same code can be used for encoding and decoding." |
2777 is self-inverse, so the same code can be used for encoding and decoding." |
2778 |
2778 |
2779 ^ self species |
2779 ^ self species |
2780 streamContents:[:aStream | |
2780 streamContents:[:aStream | |
2781 self do:[:char | |
2781 self do:[:char | |
2782 aStream nextPut:char rot13 ]] |
2782 aStream nextPut:char rot13 ]] |
2783 |
2783 |
2784 " |
2784 " |
2785 'hello world' rot13 |
2785 'hello world' rot13 |
2786 'hello world' rot13 rot13 |
2786 'hello world' rot13 rot13 |
2787 " |
2787 " |
2788 ! |
2788 ! |
2789 |
2789 |
2790 utf8Decoded |
2790 utf8Decoded |
2791 "Interpreting myself as an UTF-8 representation, decode and return the decoded string." |
2791 "Interpreting myself as an UTF-8 representation, decode and return the decoded string." |
2794 |
2794 |
2795 is16Bit := false. |
2795 is16Bit := false. |
2796 out := WriteStream on:(String uninitializedNew:self size). |
2796 out := WriteStream on:(String uninitializedNew:self size). |
2797 in := self readStream. |
2797 in := self readStream. |
2798 [in atEnd] whileFalse:[ |
2798 [in atEnd] whileFalse:[ |
2799 c := Character utf8DecodeFrom:in. |
2799 c := Character utf8DecodeFrom:in. |
2800 is16Bit ifFalse:[ |
2800 is16Bit ifFalse:[ |
2801 c codePoint > 16rFF ifTrue:[ |
2801 c codePoint > 16rFF ifTrue:[ |
2802 out := WriteStream with:(UnicodeString fromString:out contents). |
2802 out := WriteStream with:(UnicodeString fromString:out contents). |
2803 is16Bit := true. |
2803 is16Bit := true. |
2804 ]. |
2804 ]. |
2805 ]. |
2805 ]. |
2806 out nextPut:c. |
2806 out nextPut:c. |
2807 ]. |
2807 ]. |
2808 ^ out contents |
2808 ^ out contents |
2809 |
2809 |
2810 " |
2810 " |
2811 #[16rC8 16rA0] asString utf8Decoded |
2811 #[16rC8 16rA0] asString utf8Decoded |
2812 (Character value:16r220) utf8Encoded |
2812 (Character value:16r220) utf8Encoded |
2813 (Character value:16r220) utf8Encoded utf8Decoded |
2813 (Character value:16r220) utf8Encoded utf8Decoded |
2814 |
2814 |
2815 (Character value:16r800) utf8Encoded |
2815 (Character value:16r800) utf8Encoded |
2816 (Character value:16r220) utf8Encoded utf8Decoded |
2816 (Character value:16r220) utf8Encoded utf8Decoded |
2817 " |
2817 " |
2818 |
2818 |
2819 "test: |
2819 "test: |
2820 |
2820 |
2821 |utf8Encoding original readBack| |
2821 |utf8Encoding original readBack| |
2822 |
2822 |
2823 1 to:16rFFFF do:[:ascii | |
2823 1 to:16rFFFF do:[:ascii | |
2824 original := (Character value:ascii) asString. |
2824 original := (Character value:ascii) asString. |
2825 utf8Encoding := original utf8Encoded. |
2825 utf8Encoding := original utf8Encoded. |
2826 readBack := utf8Encoding utf8Decoded. |
2826 readBack := utf8Encoding utf8Decoded. |
2827 readBack = original ifFalse:[ |
2827 readBack = original ifFalse:[ |
2828 self halt |
2828 self halt |
2829 ] |
2829 ] |
2830 ] |
2830 ] |
2831 " |
2831 " |
2832 ! |
2832 ! |
2833 |
2833 |
2834 utf8DecodedWithTwoByteCharactersReplacedBy:replacementCharacter |
2834 utf8DecodedWithTwoByteCharactersReplacedBy:replacementCharacter |
2839 |in out c| |
2839 |in out c| |
2840 |
2840 |
2841 out := WriteStream on:(String uninitializedNew:self size). |
2841 out := WriteStream on:(String uninitializedNew:self size). |
2842 in := self readStream. |
2842 in := self readStream. |
2843 [in atEnd] whileFalse:[ |
2843 [in atEnd] whileFalse:[ |
2844 c := Character utf8DecodeFrom:in. |
2844 c := Character utf8DecodeFrom:in. |
2845 c codePoint > 16rFF ifTrue:[ |
2845 c codePoint > 16rFF ifTrue:[ |
2846 c := replacementCharacter |
2846 c := replacementCharacter |
2847 ]. |
2847 ]. |
2848 out nextPut:c. |
2848 out nextPut:c. |
2849 ]. |
2849 ]. |
2850 ^ out contents |
2850 ^ out contents |
2851 |
2851 |
2852 " |
2852 " |
2853 (Character value:16r220) utf8Encoded |
2853 (Character value:16r220) utf8Encoded |
2854 utf8DecodedWithTwoByteCharactersReplacedBy:(Character space) |
2854 utf8DecodedWithTwoByteCharactersReplacedBy:(Character space) |
2855 " |
2855 " |
2856 ! |
2856 ! |
2857 |
2857 |
2858 utf8Encoded |
2858 utf8Encoded |
2859 "Return my UTF-8 representation as a new String" |
2859 "Return my UTF-8 representation as a new String" |
2868 utf8EncodedOn:aStream |
2868 utf8EncodedOn:aStream |
2869 "append my UTF-8 representation to the argument, aStream." |
2869 "append my UTF-8 representation to the argument, aStream." |
2870 |
2870 |
2871 |
2871 |
2872 self do:[:c| |
2872 self do:[:c| |
2873 c utf8EncodedOn:aStream. |
2873 c utf8EncodedOn:aStream. |
2874 ]. |
2874 ]. |
2875 ! ! |
2875 ! ! |
2876 |
2876 |
2877 !CharacterArray methodsFor:'padded copying'! |
2877 !CharacterArray methodsFor:'padded copying'! |
2878 |
2878 |
2879 centerPaddedTo:newSize |
2879 centerPaddedTo:newSize |
2880 "return a new string consisting of the receivers characters, |
2880 "return a new string consisting of the receivers characters, |
2881 plus spaces up to length and center the receivers characters in |
2881 plus spaces up to length and center the receivers characters in |
2882 the resulting string. |
2882 the resulting string. |
2883 If the receivers size is equal or greater than the length argument, |
2883 If the receivers size is equal or greater than the length argument, |
2884 the original receiver is returned unchanged." |
2884 the original receiver is returned unchanged." |
2885 |
2885 |
2886 ^ self centerPaddedTo:newSize with:(Character space) |
2886 ^ self centerPaddedTo:newSize with:(Character space) |
2887 |
2887 |
2888 " |
2888 " |
2889 'foo' centerPaddedTo:10 |
2889 'foo' centerPaddedTo:10 |
2890 123 printString centerPaddedTo:10 |
2890 123 printString centerPaddedTo:10 |
2891 " |
2891 " |
2892 |
2892 |
2893 "Created: 25.11.1995 / 10:53:57 / cg" |
2893 "Created: 25.11.1995 / 10:53:57 / cg" |
2894 ! |
2894 ! |
2895 |
2895 |
2896 centerPaddedTo:size with:padCharacter |
2896 centerPaddedTo:size with:padCharacter |
2897 "return a new string of length size, which contains the receiver |
2897 "return a new string of length size, which contains the receiver |
2898 centered (i.e. padded on both sides). |
2898 centered (i.e. padded on both sides). |
2899 Characters are filled with padCharacter. |
2899 Characters are filled with padCharacter. |
2900 If the receivers size is equal or greater than the length argument, |
2900 If the receivers size is equal or greater than the length argument, |
2901 the original receiver is returned unchanged." |
2901 the original receiver is returned unchanged." |
2902 |
2902 |
2903 |len s| |
2903 |len s| |
2904 |
2904 |
2905 len := self size. |
2905 len := self size. |
2908 s replaceFrom:(size - len) // 2 + 1 with:self. |
2908 s replaceFrom:(size - len) // 2 + 1 with:self. |
2909 ^ s |
2909 ^ s |
2910 ] |
2910 ] |
2911 |
2911 |
2912 " |
2912 " |
2913 'foo' centerPaddedTo:11 with:$. |
2913 'foo' centerPaddedTo:11 with:$. |
2914 'fooBar' centerPaddedTo:5 with:$. |
2914 'fooBar' centerPaddedTo:5 with:$. |
2915 123 printString centerPaddedTo:10 with:$. |
2915 123 printString centerPaddedTo:10 with:$. |
2916 (' ' , 123 printString) centerPaddedTo:10 with:$. |
2916 (' ' , 123 printString) centerPaddedTo:10 with:$. |
2917 (Float pi printString) centerPaddedTo:15 with:(Character space) |
2917 (Float pi printString) centerPaddedTo:15 with:(Character space) |
2918 (Float pi printString) centerPaddedTo:15 with:$- |
2918 (Float pi printString) centerPaddedTo:15 with:$- |
2919 (' ' , Float pi class name) centerPaddedTo:15 with:$. |
2919 (' ' , Float pi class name) centerPaddedTo:15 with:$. |
2920 " |
2920 " |
2921 ! |
2921 ! |
2922 |
2922 |
2923 decimalPaddedTo:size and:afterPeriod at:decimalCharacter |
2923 decimalPaddedTo:size and:afterPeriod at:decimalCharacter |
2924 "return a new string of overall length size, which contains the receiver |
2924 "return a new string of overall length size, which contains the receiver |
2925 aligned at the decimal-period column and afterPeriod characters to the right |
2925 aligned at the decimal-period column and afterPeriod characters to the right |
2926 of the period. The periodCharacter is passed as arguments (allowing for US and European formats |
2926 of the period. The periodCharacter is passed as arguments (allowing for US and European formats |
2927 to be padded). |
2927 to be padded). |
2928 If the receivers size is equal or greater than the length argument, |
2928 If the receivers size is equal or greater than the length argument, |
2929 the original receiver is returned unchanged. |
2929 the original receiver is returned unchanged. |
2930 (sounds complicated ? -> see examples below)." |
2930 (sounds complicated ? -> see examples below)." |
2931 |
2931 |
2932 ^ self |
2932 ^ self |
2933 decimalPaddedTo:size |
2933 decimalPaddedTo:size |
2934 and:afterPeriod |
2934 and:afterPeriod |
2935 at:decimalCharacter |
2935 at:decimalCharacter |
2936 withLeft:(Character space) |
2936 withLeft:(Character space) |
2937 right:$0 |
2937 right:$0 |
2938 |
2938 |
2939 " |
2939 " |
2940 '123' decimalPaddedTo:10 and:3 at:$. -> ' 123 ' |
2940 '123' decimalPaddedTo:10 and:3 at:$. -> ' 123 ' |
2941 '123' decimalPaddedTo:10 and:3 at:$. -> ' 123.000' |
2941 '123' decimalPaddedTo:10 and:3 at:$. -> ' 123.000' |
2942 '123.' decimalPaddedTo:10 and:3 at:$. -> ' 123.000' |
2942 '123.' decimalPaddedTo:10 and:3 at:$. -> ' 123.000' |
2943 '123.1' decimalPaddedTo:10 and:3 at:$. -> ' 123.100' |
2943 '123.1' decimalPaddedTo:10 and:3 at:$. -> ' 123.100' |
2944 '123.1' decimalPaddedTo:10 and:3 at:$. -> ' 123.1 ' |
2944 '123.1' decimalPaddedTo:10 and:3 at:$. -> ' 123.1 ' |
2945 '123.123' decimalPaddedTo:10 and:3 at:$. -> ' 123.123' |
2945 '123.123' decimalPaddedTo:10 and:3 at:$. -> ' 123.123' |
2946 " |
2946 " |
2947 |
2947 |
2948 "Created: 23.12.1995 / 13:11:52 / cg" |
2948 "Created: 23.12.1995 / 13:11:52 / cg" |
2949 ! |
2949 ! |
2953 aligned at the decimal-period column and afterPeriod characters to the right |
2953 aligned at the decimal-period column and afterPeriod characters to the right |
2954 of the period. |
2954 of the period. |
2955 Characters on the left are filled with leftPadChar. |
2955 Characters on the left are filled with leftPadChar. |
2956 If rightPadChar is nil, characters on the right are filled with leftPadCharacter too; |
2956 If rightPadChar is nil, characters on the right are filled with leftPadCharacter too; |
2957 otherwise, if missing, a decimal point is added and right characters filled with this. |
2957 otherwise, if missing, a decimal point is added and right characters filled with this. |
2958 If the receivers size is equal or greater than the length argument, |
2958 If the receivers size is equal or greater than the length argument, |
2959 the original receiver is returned unchanged. |
2959 the original receiver is returned unchanged. |
2960 (sounds complicated ? -> see examples below)." |
2960 (sounds complicated ? -> see examples below)." |
2961 |
2961 |
2962 |s idx n rest| |
2962 |s idx n rest| |
2963 |
2963 |
2964 idx := self indexOf:decimalCharacter. |
2964 idx := self indexOf:decimalCharacter. |
2965 idx == 0 ifTrue:[ |
2965 idx == 0 ifTrue:[ |
2966 "/ |
2966 "/ |
2967 "/ no decimal point found; adjust string to the left of the period column |
2967 "/ no decimal point found; adjust string to the left of the period column |
2968 "/ |
2968 "/ |
2969 rightPadChar isNil ifTrue:[ |
2969 rightPadChar isNil ifTrue:[ |
2970 s := self , (self species new:afterPeriod + 1 withAll:leftPadChar) |
2970 s := self , (self species new:afterPeriod + 1 withAll:leftPadChar) |
2971 ] ifFalse:[ |
2971 ] ifFalse:[ |
2972 s:= self , decimalCharacter asString , (self species new:afterPeriod withAll:rightPadChar). |
2972 s:= self , decimalCharacter asString , (self species new:afterPeriod withAll:rightPadChar). |
2973 ]. |
2973 ]. |
2974 ] ifFalse:[ |
2974 ] ifFalse:[ |
2975 |
2975 |
2976 "/ the number of after-decimalPoint characters |
2976 "/ the number of after-decimalPoint characters |
2977 n := self size - idx. |
2977 n := self size - idx. |
2978 rest := afterPeriod - n. |
2978 rest := afterPeriod - n. |
2979 rest > 0 ifTrue:[ |
2979 rest > 0 ifTrue:[ |
2980 s := (self species new:rest withAll:(rightPadChar ? leftPadChar)). |
2980 s := (self species new:rest withAll:(rightPadChar ? leftPadChar)). |
2981 ] ifFalse:[ |
2981 ] ifFalse:[ |
2982 s := '' |
2982 s := '' |
2983 ]. |
2983 ]. |
2984 s := self , s. |
2984 s := self , s. |
2985 ]. |
2985 ]. |
2986 |
2986 |
2987 ^ s leftPaddedTo:size with:leftPadChar |
2987 ^ s leftPaddedTo:size with:leftPadChar |
2988 |
2988 |
2989 " |
2989 " |
2990 '123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:nil -> ' 123 ' |
2990 '123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:nil -> ' 123 ' |
2991 '123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.000' |
2991 '123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.000' |
2992 '123.' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.000' |
2992 '123.' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.000' |
2993 '123.1' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.100' |
2993 '123.1' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.100' |
2994 '123.1' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:nil -> ' 123.1 ' |
2994 '123.1' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:nil -> ' 123.1 ' |
2995 '123.123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.123' |
2995 '123.123' decimalPaddedTo:10 and:3 at:$. withLeft:(Character space) right:$0 -> ' 123.123' |
2996 " |
2996 " |
2997 |
2997 |
2998 "Modified: 23.12.1995 / 13:08:18 / cg" |
2998 "Modified: 23.12.1995 / 13:08:18 / cg" |
2999 ! |
2999 ! |
3000 |
3000 |
3001 leftPaddedTo:size |
3001 leftPaddedTo:size |
3002 "return a new string of length size, which contains the receiver |
3002 "return a new string of length size, which contains the receiver |
3003 right-adjusted (i.e. padded on the left). |
3003 right-adjusted (i.e. padded on the left). |
3004 Characters on the left are filled with spaces. |
3004 Characters on the left are filled with spaces. |
3005 If the receivers size is equal or greater than the length argument, |
3005 If the receivers size is equal or greater than the length argument, |
3006 the original receiver is returned unchanged." |
3006 the original receiver is returned unchanged." |
3007 |
3007 |
3008 ^ self leftPaddedTo:size with:(Character space) |
3008 ^ self leftPaddedTo:size with:(Character space) |
3009 |
3009 |
3010 " |
3010 " |
3011 'foo' leftPaddedTo:10 |
3011 'foo' leftPaddedTo:10 |
3012 'fooBar' leftPaddedTo:5 |
3012 'fooBar' leftPaddedTo:5 |
3013 123 printString leftPaddedTo:10 |
3013 123 printString leftPaddedTo:10 |
3014 " |
3014 " |
3015 ! |
3015 ! |
3016 |
3016 |
3017 paddedTo:newSize |
3017 paddedTo:newSize |
3018 "return a new string consisting of the receivers characters, |
3018 "return a new string consisting of the receivers characters, |
3019 plus spaces up to length. |
3019 plus spaces up to length. |
3020 If the receivers size is equal or greater than the length argument, |
3020 If the receivers size is equal or greater than the length argument, |
3021 the original receiver is returned unchanged." |
3021 the original receiver is returned unchanged." |
3022 |
3022 |
3023 ^ self paddedTo:newSize with:(Character space) |
3023 ^ self paddedTo:newSize with:(Character space) |
3024 |
3024 |
3025 " |
3025 " |
3026 'foo' paddedTo:10 |
3026 'foo' paddedTo:10 |
3027 123 printString paddedTo:10 |
3027 123 printString paddedTo:10 |
3028 " |
3028 " |
3029 ! ! |
3029 ! ! |
3030 |
3030 |
3031 !CharacterArray methodsFor:'pattern matching'! |
3031 !CharacterArray methodsFor:'pattern matching'! |
3032 |
3032 |
3036 This is usable with fileName pattern fields." |
3036 This is usable with fileName pattern fields." |
3037 |
3037 |
3038 ^self compoundMatch:aString ignoreCase:false |
3038 ^self compoundMatch:aString ignoreCase:false |
3039 |
3039 |
3040 " |
3040 " |
3041 'f*' match:'foo' |
3041 'f*' match:'foo' |
3042 'b*' match:'foo' |
3042 'b*' match:'foo' |
3043 'f*;b*' match:'foo' |
3043 'f*;b*' match:'foo' |
3044 'f*;b*' match:'bar' |
3044 'f*;b*' match:'bar' |
3045 'f*;b*' compoundMatch:'foo' |
3045 'f*;b*' compoundMatch:'foo' |
3046 'f*;b*' compoundMatch:'bar' |
3046 'f*;b*' compoundMatch:'bar' |
3047 " |
3047 " |
3048 |
3048 |
3049 "Modified: / 30.1.1998 / 11:40:18 / stefan" |
3049 "Modified: / 30.1.1998 / 11:40:18 / stefan" |
3050 "Modified: / 16.12.1999 / 01:22:08 / cg" |
3050 "Modified: / 16.12.1999 / 01:22:08 / cg" |
3051 ! |
3051 ! |
3057 |
3057 |
3058 |matchers| |
3058 |matchers| |
3059 |
3059 |
3060 matchers := self asCollectionOfSubstringsSeparatedBy:$;. |
3060 matchers := self asCollectionOfSubstringsSeparatedBy:$;. |
3061 matchers do:[:aPattern | |
3061 matchers do:[:aPattern | |
3062 (aPattern match:aString ignoreCase:ignoreCase) ifTrue:[^ true]. |
3062 (aPattern match:aString ignoreCase:ignoreCase) ifTrue:[^ true]. |
3063 ]. |
3063 ]. |
3064 ^ false. |
3064 ^ false. |
3065 |
3065 |
3066 " |
3066 " |
3067 'f*' match:'foo' |
3067 'f*' match:'foo' |
3068 'b*' match:'foo' |
3068 'b*' match:'foo' |
3069 'f*;b*' match:'foo' |
3069 'f*;b*' match:'foo' |
3070 'f*;b*' match:'bar' |
3070 'f*;b*' match:'bar' |
3071 'f*;b*' compoundMatch:'foo' |
3071 'f*;b*' compoundMatch:'foo' |
3072 'f*;b*' compoundMatch:'bar' |
3072 'f*;b*' compoundMatch:'bar' |
3073 'f*;b*' compoundMatch:'Foo' ignoreCase:true |
3073 'f*;b*' compoundMatch:'Foo' ignoreCase:true |
3074 " |
3074 " |
3075 |
3075 |
3076 "Modified: / 15.4.1997 / 15:50:33 / cg" |
3076 "Modified: / 15.4.1997 / 15:50:33 / cg" |
3077 "Modified: / 30.1.1998 / 11:40:18 / stefan" |
3077 "Modified: / 30.1.1998 / 11:40:18 / stefan" |
3078 "Created: / 16.12.1999 / 01:21:35 / cg" |
3078 "Created: / 16.12.1999 / 01:21:35 / cg" |
3081 findMatchString:matchString |
3081 findMatchString:matchString |
3082 "like findString/indexOfSubCollection, but allowing match patterns. |
3082 "like findString/indexOfSubCollection, but allowing match patterns. |
3083 find matchstring; if found, return the index; |
3083 find matchstring; if found, return the index; |
3084 if not found, return 0." |
3084 if not found, return 0." |
3085 |
3085 |
3086 ^ self findMatchString:matchString startingAt:1 ignoreCase:false ifAbsent:0 |
3086 ^ self findMatchString:matchString startingAt:1 ignoreCase:false ifAbsent:0 |
3087 ! |
3087 ! |
3088 |
3088 |
3089 findMatchString:matchString startingAt:index |
3089 findMatchString:matchString startingAt:index |
3090 "like findString, but allowing match patterns. |
3090 "like findString, but allowing match patterns. |
3091 find matchstring, starting at index. if found, return the index; |
3091 find matchstring, starting at index. if found, return the index; |
3092 if not found, return 0." |
3092 if not found, return 0." |
3093 |
3093 |
3094 ^ self findMatchString:matchString startingAt:index ignoreCase:false ifAbsent:0 |
3094 ^ self findMatchString:matchString startingAt:index ignoreCase:false ifAbsent:0 |
3095 ! |
3095 ! |
3096 |
3096 |
3097 findMatchString:matchString startingAt:index ignoreCase:ignoreCase ifAbsent:exceptionBlock |
3097 findMatchString:matchString startingAt:index ignoreCase:ignoreCase ifAbsent:exceptionBlock |
3098 "like findString, but allowing match patterns. |
3098 "like findString, but allowing match patterns. |
3099 find matchstring, starting at index. if found, return the index; |
3099 find matchstring, starting at index. if found, return the index; |
3109 matchSize := matchString size. |
3109 matchSize := matchString size. |
3110 matchSize == 0 ifTrue:[^ index]. "empty string matches" |
3110 matchSize == 0 ifTrue:[^ index]. "empty string matches" |
3111 |
3111 |
3112 realMatchString := matchString. |
3112 realMatchString := matchString. |
3113 (realMatchString endsWith:$*) ifFalse:[ |
3113 (realMatchString endsWith:$*) ifFalse:[ |
3114 realMatchString := realMatchString , '*'. |
3114 realMatchString := realMatchString , '*'. |
3115 matchSize := matchSize + 1 |
3115 matchSize := matchSize + 1 |
3116 ]. |
3116 ]. |
3117 |
3117 |
3118 mySize := self size. |
3118 mySize := self size. |
3119 firstChar := realMatchString at:1. |
3119 firstChar := realMatchString at:1. |
3120 firstChar == self class matchEscapeCharacter ifTrue:[ |
3120 firstChar == self class matchEscapeCharacter ifTrue:[ |
3121 firstChar := realMatchString at:2. |
3121 firstChar := realMatchString at:2. |
3122 ]. |
3122 ]. |
3123 |
3123 |
3124 firstChar asString includesMatchCharacters ifTrue:[ |
3124 firstChar asString includesMatchCharacters ifTrue:[ |
3125 index to:mySize do:[:col | |
3125 index to:mySize do:[:col | |
3126 (realMatchString match:self from:col to:mySize ignoreCase:ignoreCase) |
3126 (realMatchString match:self from:col to:mySize ignoreCase:ignoreCase) |
3127 ifTrue:[^ col] |
3127 ifTrue:[^ col] |
3128 ]. |
3128 ]. |
3129 ^ exceptionBlock value. |
3129 ^ exceptionBlock value. |
3130 ]. |
3130 ]. |
3131 |
3131 |
3132 lcChar := firstChar asLowercase. |
3132 lcChar := firstChar asLowercase. |
3133 ucChar := firstChar asUppercase. |
3133 ucChar := firstChar asUppercase. |
3134 (ignoreCase and:[ lcChar ~= ucChar]) ifTrue:[ |
3134 (ignoreCase and:[ lcChar ~= ucChar]) ifTrue:[ |
3135 firstSet := Array with:ucChar with:lcChar. |
3135 firstSet := Array with:ucChar with:lcChar. |
3136 startIndex := self indexOfAny:firstSet startingAt:index. |
3136 startIndex := self indexOfAny:firstSet startingAt:index. |
3137 ] ifFalse:[ |
3137 ] ifFalse:[ |
3138 startIndex := self indexOf:firstChar startingAt:index. |
3138 startIndex := self indexOf:firstChar startingAt:index. |
3139 ]. |
3139 ]. |
3140 [startIndex == 0] whileFalse:[ |
3140 [startIndex == 0] whileFalse:[ |
3141 (realMatchString match:self from:startIndex to:mySize ignoreCase:ignoreCase) |
3141 (realMatchString match:self from:startIndex to:mySize ignoreCase:ignoreCase) |
3142 ifTrue:[^ startIndex]. |
3142 ifTrue:[^ startIndex]. |
3143 firstSet notNil ifTrue:[ |
3143 firstSet notNil ifTrue:[ |
3144 startIndex := self indexOfAny:firstSet startingAt:(startIndex + 1). |
3144 startIndex := self indexOfAny:firstSet startingAt:(startIndex + 1). |
3145 ] ifFalse:[ |
3145 ] ifFalse:[ |
3146 startIndex := self indexOf:firstChar startingAt:(startIndex + 1). |
3146 startIndex := self indexOf:firstChar startingAt:(startIndex + 1). |
3147 ]. |
3147 ]. |
3148 ]. |
3148 ]. |
3149 ^ exceptionBlock value |
3149 ^ exceptionBlock value |
3150 |
3150 |
3151 " |
3151 " |
3152 'one two three four' findMatchString:'o[nu]' |
3152 'one two three four' findMatchString:'o[nu]' |
3153 'one two three four' findMatchString:'o[nu]' startingAt:3 |
3153 'one two three four' findMatchString:'o[nu]' startingAt:3 |
3154 'one two three four one' findMatchString:'ONE' startingAt:3 ignoreCase:true ifAbsent:0 |
3154 'one two three four one' findMatchString:'ONE' startingAt:3 ignoreCase:true ifAbsent:0 |
3155 " |
3155 " |
3156 |
3156 |
3157 "Modified: 13.9.1997 / 06:31:22 / cg" |
3157 "Modified: 13.9.1997 / 06:31:22 / cg" |
3158 ! |
3158 ! |
3159 |
3159 |
3163 |
3163 |
3164 ^ (self findMatchString:matchString) ~~ 0 |
3164 ^ (self findMatchString:matchString) ~~ 0 |
3165 |
3165 |
3166 " |
3166 " |
3167 'hello world' includesMatchString:'h*' |
3167 'hello world' includesMatchString:'h*' |
3168 'hello world' includesMatchString:'h[aeiou]llo' |
3168 'hello world' includesMatchString:'h[aeiou]llo' |
3169 'hello world' includesMatchString:'wor*' |
3169 'hello world' includesMatchString:'wor*' |
3170 'hello world' includesMatchString:'woR*' |
3170 'hello world' includesMatchString:'woR*' |
3171 " |
3171 " |
3172 ! |
3172 ! |
3173 |
3173 |
3174 match:aString |
3174 match:aString |
3175 "return true if aString matches self, where self may contain meta-match |
3175 "return true if aString matches self, where self may contain meta-match |
3176 characters $* (to match any string) or $# (to match any character). |
3176 characters $* (to match any string) or $# (to match any character). |
3177 or [...] to match a set of characters. |
3177 or [...] to match a set of characters. |
3178 Lower/uppercase are considered different. |
3178 Lower/uppercase are considered different. |
3179 NOTICE: match-meta character interpretation is like in unix-matching, |
3179 NOTICE: match-meta character interpretation is like in unix-matching, |
3180 NOT the ST-80 meaning." |
3180 NOT the ST-80 meaning." |
3181 |
3181 |
3182 ^ self match:aString from:1 to:aString size ignoreCase:false |
3182 ^ self match:aString from:1 to:aString size ignoreCase:false |
3183 |
3183 |
3184 " |
3184 " |
3185 '\*f*' match:'f' |
3185 '\*f*' match:'f' |
3186 '\*f*' match:'*f' |
3186 '\*f*' match:'*f' |
3187 '*\*f*' match:'*f' |
3187 '*\*f*' match:'*f' |
3188 '*f*' match:'*f' |
3188 '*f*' match:'*f' |
3189 '*ute*' match:'computer' |
3189 '*ute*' match:'computer' |
3190 '*uter' match:'computer' |
3190 '*uter' match:'computer' |
3191 'uter*' match:'computer' |
3191 'uter*' match:'computer' |
3192 '*ute*' match:'' |
3192 '*ute*' match:'' |
3193 '[abcd]*' match:'computer' |
3193 '[abcd]*' match:'computer' |
3194 '[abcd]*' match:'komputer' |
3194 '[abcd]*' match:'komputer' |
3195 '*some*compl*ern*' match:'this is some more complicated pattern match' |
3195 '*some*compl*ern*' match:'this is some more complicated pattern match' |
3196 '*some*compl*ern*' match:'this is another complicated pattern match' |
3196 '*some*compl*ern*' match:'this is another complicated pattern match' |
3197 '*-hh' match:'anton-h' |
3197 '*-hh' match:'anton-h' |
3198 " |
3198 " |
3199 |
3199 |
3200 "Modified: / 9.6.1998 / 18:50:00 / cg" |
3200 "Modified: / 9.6.1998 / 18:50:00 / cg" |
3201 ! |
3201 ! |
3202 |
3202 |
3203 match:aString from:start to:stop ignoreCase:ignoreCase |
3203 match:aString from:start to:stop ignoreCase:ignoreCase |
3204 "return true if part of aString matches myself, |
3204 "return true if part of aString matches myself, |
3205 where self may contain meta-match |
3205 where self may contain meta-match |
3206 characters $* (to match any string) or $# (to match any character) |
3206 characters $* (to match any string) or $# (to match any character) |
3207 or [...] to match a set of characters. |
3207 or [...] to match a set of characters. |
3208 If ignoreCase is true, lower/uppercase are considered the same. |
3208 If ignoreCase is true, lower/uppercase are considered the same. |
3209 NOTICE: match-meta character interpretation is like in unix-matching, |
3209 NOTICE: match-meta character interpretation is like in unix-matching, |
3210 NOT the ST-80 meaning." |
3210 NOT the ST-80 meaning." |
3211 |
3211 |
3212 |matchScanArray| |
3212 |matchScanArray| |
3213 |
3213 |
3214 " |
3214 " |
3215 keep the matchScanArray from the most recent match - |
3215 keep the matchScanArray from the most recent match - |
3216 avoids parsing the pattern over-and over if multiple searches |
3216 avoids parsing the pattern over-and over if multiple searches |
3217 are done with the same pattern. |
3217 are done with the same pattern. |
3218 " |
3218 " |
3219 (PreviousMatch notNil |
3219 (PreviousMatch notNil |
3220 and:[PreviousMatch key = self]) ifTrue:[ |
3220 and:[PreviousMatch key = self]) ifTrue:[ |
3221 matchScanArray := PreviousMatch value |
3221 matchScanArray := PreviousMatch value |
3222 ] ifFalse:[ |
3222 ] ifFalse:[ |
3223 matchScanArray := self class matchScanArrayFrom:self. |
3223 matchScanArray := self class matchScanArrayFrom:self. |
3224 matchScanArray isNil ifTrue:[ |
3224 matchScanArray isNil ifTrue:[ |
3225 'CharacterArray [info]: invalid matchpattern:''' infoPrint. self infoPrint. ''' comparing for equality.' infoPrintCR. |
3225 'CharacterArray [info]: invalid matchpattern:''' infoPrint. self infoPrint. ''' comparing for equality.' infoPrintCR. |
3226 ^ self = aString |
3226 ^ self = aString |
3227 "/ ^ false |
3227 "/ ^ false |
3228 ]. |
3228 ]. |
3229 PreviousMatch := self -> matchScanArray. |
3229 PreviousMatch := self -> matchScanArray. |
3230 ]. |
3230 ]. |
3231 |
3231 |
3232 ^ self class |
3232 ^ self class |
3233 matchScan:matchScanArray |
3233 matchScan:matchScanArray |
3234 from:1 to:matchScanArray size |
3234 from:1 to:matchScanArray size |
3235 with:aString |
3235 with:aString |
3236 from:start to:stop |
3236 from:start to:stop |
3237 ignoreCase:ignoreCase |
3237 ignoreCase:ignoreCase |
3238 |
3238 |
3239 " |
3239 " |
3240 '*ute*' match:'12345COMPUTER' from:1 to:5 ignoreCase:true |
3240 '*ute*' match:'12345COMPUTER' from:1 to:5 ignoreCase:true |
3241 '*ute*' match:'12345COMPUTER' from:6 to:13 ignoreCase:true |
3241 '*ute*' match:'12345COMPUTER' from:6 to:13 ignoreCase:true |
3242 " |
3242 " |
3243 |
3243 |
3244 "Modified: / 10.11.1998 / 21:43:46 / cg" |
3244 "Modified: / 10.11.1998 / 21:43:46 / cg" |
3245 ! |
3245 ! |
3246 |
3246 |
3247 match:aString ignoreCase:ignoreCase |
3247 match:aString ignoreCase:ignoreCase |
3248 "return true if aString matches self, where self may contain meta-match |
3248 "return true if aString matches self, where self may contain meta-match |
3249 characters $* (to match any string) or $# (to match any character) |
3249 characters $* (to match any string) or $# (to match any character) |
3250 or [...] to match a set of characters. |
3250 or [...] to match a set of characters. |
3251 If ignoreCase is true, lower/uppercase are considered the same. |
3251 If ignoreCase is true, lower/uppercase are considered the same. |
3252 NOTICE: match-meta character interpretation is like in unix-matching, |
3252 NOTICE: match-meta character interpretation is like in unix-matching, |
3253 NOT the ST-80 meaning." |
3253 NOT the ST-80 meaning." |
3254 |
3254 |
3255 ^ self match:aString from:1 to:aString size ignoreCase:ignoreCase |
3255 ^ self match:aString from:1 to:aString size ignoreCase:ignoreCase |
3256 |
3256 |
3257 " |
3257 " |
3258 '*ute*' match:'COMPUTER' ignoreCase:true |
3258 '*ute*' match:'COMPUTER' ignoreCase:true |
3259 '*uter' match:'COMPUTER' ignoreCase:false |
3259 '*uter' match:'COMPUTER' ignoreCase:false |
3260 '[abcd]*' match:'computer' ignoreCase:false |
3260 '[abcd]*' match:'computer' ignoreCase:false |
3261 '[abcd]*' match:'Computer' ignoreCase:false |
3261 '[abcd]*' match:'Computer' ignoreCase:false |
3262 '[a-k]*' match:'komputer' ignoreCase:false |
3262 '[a-k]*' match:'komputer' ignoreCase:false |
3263 '[a-k]*' match:'zomputer' ignoreCase:false |
3263 '[a-k]*' match:'zomputer' ignoreCase:false |
3264 '[a-k]*' match:'Komputer' ignoreCase:false |
3264 '[a-k]*' match:'Komputer' ignoreCase:false |
3265 '[a-k]*' match:'Komputer' ignoreCase:true |
3265 '[a-k]*' match:'Komputer' ignoreCase:true |
3266 '*some*compl*ern*' match:'this is some more complicated pattern match' ignoreCase:true |
3266 '*some*compl*ern*' match:'this is some more complicated pattern match' ignoreCase:true |
3267 '*some*compl*ern*' match:'this is another complicated pattern match' ignoreCase:true |
3267 '*some*compl*ern*' match:'this is another complicated pattern match' ignoreCase:true |
3268 |
3268 |
3269 Time millisecondsToRun:[ |
3269 Time millisecondsToRun:[ |
3270 Symbol allInstancesDo:[:sym | |
3270 Symbol allInstancesDo:[:sym | |
3271 '[ab]*' match:sym ignoreCase:false |
3271 '[ab]*' match:sym ignoreCase:false |
3272 ] |
3272 ] |
3273 ]. |
3273 ]. |
3274 Time millisecondsToRun:[ |
3274 Time millisecondsToRun:[ |
3275 Symbol allInstancesDo:[:sym | |
3275 Symbol allInstancesDo:[:sym | |
3276 '*at:*' match:sym ignoreCase:false |
3276 '*at:*' match:sym ignoreCase:false |
3277 ] |
3277 ] |
3278 ]. |
3278 ]. |
3279 " |
3279 " |
3280 |
3280 |
3281 "Modified: 2.4.1997 / 17:28:58 / cg" |
3281 "Modified: 2.4.1997 / 17:28:58 / cg" |
3282 ! |
3282 ! |
3283 |
3283 |
3284 matches:aPatternString |
3284 matches:aPatternString |
3285 "return true if the receiver matches aString, where aPatternString may contain meta-match |
3285 "return true if the receiver matches aString, where aPatternString may contain meta-match |
3286 characters $* (to match any string) or $# (to match any character). |
3286 characters $* (to match any string) or $# (to match any character). |
3287 or [...] to match a set of characters. |
3287 or [...] to match a set of characters. |
3288 Lower/uppercase are considered different. |
3288 Lower/uppercase are considered different. |
3289 NOTICE: match-meta character interpretation is like in unix-matching, |
3289 NOTICE: match-meta character interpretation is like in unix-matching, |
3290 NOT the ST-80 meaning." |
3290 NOT the ST-80 meaning." |
3291 |
3291 |
3292 ^ aPatternString match:self |
3292 ^ aPatternString match:self |
3293 |
3293 |
3294 |
3294 |
3295 ! ! |
3295 ! ! |
3299 article |
3299 article |
3300 "return an article string for the receiver." |
3300 "return an article string for the receiver." |
3301 |
3301 |
3302 |firstChar| |
3302 |firstChar| |
3303 |
3303 |
3304 firstChar := (self at:1) asLowercase. |
3304 firstChar := (self at:1) asLowercase. |
3305 ((firstChar isVowel and:[firstChar ~~ $u]) or:[firstChar == $x]) ifTrue:[ |
3305 ((firstChar isVowel and:[firstChar ~~ $u]) or:[firstChar == $x]) ifTrue:[ |
3306 ^ 'an' |
3306 ^ 'an' |
3307 ]. |
3307 ]. |
3308 ^ 'a' |
3308 ^ 'a' |
3309 |
3309 |
3310 " |
3310 " |
3311 'uboot' article. |
3311 'uboot' article. |
3312 'xmas' article. |
3312 'xmas' article. |
3313 'alarm' article. |
3313 'alarm' article. |
3314 'baby' article. |
3314 'baby' article. |
3315 " |
3315 " |
3316 ! |
3316 ! |
3317 |
3317 |
3318 basicStoreString |
3318 basicStoreString |
3319 "return a String for storing myself" |
3319 "return a String for storing myself" |
3320 |
3320 |
3321 |s n index| |
3321 |s n index| |
3322 |
3322 |
3323 n := self occurrencesOf:$'. |
3323 n := self occurrencesOf:$'. |
3324 n == 0 ifFalse:[ |
3324 n == 0 ifFalse:[ |
3325 s := String new:(n + 2 + self size). |
3325 s := String new:(n + 2 + self size). |
3326 s at:1 put:$'. |
3326 s at:1 put:$'. |
3327 index := 2. |
3327 index := 2. |
3328 self do:[:thisChar | |
3328 self do:[:thisChar | |
3329 (thisChar == $') ifTrue:[ |
3329 (thisChar == $') ifTrue:[ |
3330 s at:index put:thisChar. |
3330 s at:index put:thisChar. |
3331 index := index + 1. |
3331 index := index + 1. |
3332 ]. |
3332 ]. |
3333 s at:index put:thisChar. |
3333 s at:index put:thisChar. |
3334 index := index + 1. |
3334 index := index + 1. |
3335 ]. |
3335 ]. |
3336 s at:index put:$'. |
3336 s at:index put:$'. |
3337 ^ s |
3337 ^ s |
3338 ]. |
3338 ]. |
3339 ^ '''' , self , '''' |
3339 ^ '''' , self , '''' |
3340 ! |
3340 ! |
3341 |
3341 |
3342 displayString |
3342 displayString |
3359 |
3359 |
3360 printWithQuotesDoubledOn:aStream |
3360 printWithQuotesDoubledOn:aStream |
3361 "put the raw storeString of myself on aStream" |
3361 "put the raw storeString of myself on aStream" |
3362 |
3362 |
3363 self do:[:thisChar | |
3363 self do:[:thisChar | |
3364 (thisChar == $') ifTrue:[aStream nextPut:thisChar]. |
3364 (thisChar == $') ifTrue:[aStream nextPut:thisChar]. |
3365 aStream nextPut:thisChar |
3365 aStream nextPut:thisChar |
3366 ] |
3366 ] |
3367 |
3367 |
3368 "Modified: / 15.6.1998 / 17:21:17 / cg" |
3368 "Modified: / 15.6.1998 / 17:21:17 / cg" |
3369 "Created: / 15.6.1998 / 17:22:13 / cg" |
3369 "Created: / 15.6.1998 / 17:22:13 / cg" |
3370 ! ! |
3370 ! ! |
3371 |
3371 |
3372 !CharacterArray methodsFor:'public'! |
3372 !CharacterArray methodsFor:'public'! |
3373 |
3373 |
3374 isUnarySelector |
3374 isUnarySelector |
3375 "Answer true if the receiver contains only chars in an ANSI unary method selector, false otherwise." |
3375 "Answer true if the receiver contains only chars in an ANSI unary method selector, false otherwise." |
3376 |
3376 |
3377 ^ (self first isLetter or:[ self first = $_ ]) |
3377 ^ (self first isLetter or:[ self first = $_ ]) |
3378 and:[ self allSatisfy: [ :chr | chr isLetterOrDigit ]] |
3378 and:[ self allSatisfy: [ :chr | chr isLetterOrDigit ]] |
3379 |
3379 |
3381 ! ! |
3381 ! ! |
3382 |
3382 |
3383 !CharacterArray methodsFor:'queries'! |
3383 !CharacterArray methodsFor:'queries'! |
3384 |
3384 |
3385 bitsPerCharacter |
3385 bitsPerCharacter |
3386 "return the underlying strings bitsPerCharacter |
3386 "return the underlying strings bitsPerCharacter |
3387 (i.e. is it a regular String or a TwoByteString)" |
3387 (i.e. is it a regular String or a TwoByteString)" |
3388 |
3388 |
3389 |string max| |
3389 |string max| |
3390 |
3390 |
3391 (string := self string) ~~ self ifTrue:[ |
3391 (string := self string) ~~ self ifTrue:[ |
3392 ^ string bitsPerCharacter |
3392 ^ string bitsPerCharacter |
3393 ]. |
3393 ]. |
3394 |
3394 |
3395 max := 8. |
3395 max := 8. |
3396 self do:[:eachCharacter | |
3396 self do:[:eachCharacter | |
3397 max := max max:(eachCharacter bitsPerCharacter) |
3397 max := max max:(eachCharacter bitsPerCharacter) |
3398 ]. |
3398 ]. |
3399 ^ max |
3399 ^ max |
3400 |
3400 |
3401 " |
3401 " |
3402 'hello' bitsPerCharacter |
3402 'hello' bitsPerCharacter |
3403 'hello' asText allBold bitsPerCharacter |
3403 'hello' asText allBold bitsPerCharacter |
3404 " |
3404 " |
3405 ! |
3405 ! |
3406 |
3406 |
3407 contains8BitCharacters |
3407 contains8BitCharacters |
3408 "return true, if the underlying string contains 8BitCharacters (or widers) |
3408 "return true, if the underlying string contains 8BitCharacters (or widers) |
3409 (i.e. if it is non-ascii)" |
3409 (i.e. if it is non-ascii)" |
3410 |
3410 |
3411 |string| |
3411 |string| |
3412 |
3412 |
3413 (string := self string) ~~ self ifTrue:[ |
3413 (string := self string) ~~ self ifTrue:[ |
3414 ^ string contains8BitCharacters |
3414 ^ string contains8BitCharacters |
3415 ]. |
3415 ]. |
3416 self do:[:eachCharacter | |
3416 self do:[:eachCharacter | |
3417 (eachCharacter codePoint > 16r7F) ifTrue:[ |
3417 (eachCharacter codePoint > 16r7F) ifTrue:[ |
3418 ^ true |
3418 ^ true |
3419 ]. |
3419 ]. |
3420 ]. |
3420 ]. |
3421 ^ false |
3421 ^ false |
3422 |
3422 |
3423 " |
3423 " |
3424 'hello' contains8BitCharacters |
3424 'hello' contains8BitCharacters |
3425 'hello' asText allBold contains8BitCharacters |
3425 'hello' asText allBold contains8BitCharacters |
3426 " |
3426 " |
3427 ! |
3427 ! |
3428 |
3428 |
3429 encoding |
3429 encoding |
3430 "return the strings encoding, as a symbol. |
3430 "return the strings encoding, as a symbol. |
3431 Here, by default, we assume unicode-encoding. |
3431 Here, by default, we assume unicode-encoding. |
3432 Notice, that iso8859-1 is a true subset of unicode, |
3432 Notice, that iso8859-1 is a true subset of unicode, |
3433 and that singleByteStrings are therefore both unicode AND |
3433 and that singleByteStrings are therefore both unicode AND |
3434 8859-1 encoded." |
3434 8859-1 encoded." |
3435 |
3435 |
3436 ^ #'unicode' |
3436 ^ #'unicode' |
3437 ! |
3437 ! |
3438 |
3438 |
3458 "return the size of the recevier in device units if displayed on aGC" |
3458 "return the size of the recevier in device units if displayed on aGC" |
3459 |
3459 |
3460 ^ (aGC font onDevice:aGC device) heightOf:self |
3460 ^ (aGC font onDevice:aGC device) heightOf:self |
3461 |
3461 |
3462 " |
3462 " |
3463 'hello world' heightOn:(View new) |
3463 'hello world' heightOn:(View new) |
3464 " |
3464 " |
3465 |
3465 |
3466 "Created: 12.5.1996 / 20:09:29 / cg" |
3466 "Created: 12.5.1996 / 20:09:29 / cg" |
3467 "Modified: 12.5.1996 / 20:32:05 / cg" |
3467 "Modified: 12.5.1996 / 20:32:05 / cg" |
3468 ! |
3468 ! |
3481 |
3481 |
3482 scanner := Compiler new. |
3482 scanner := Compiler new. |
3483 scanner source:(self readStream). |
3483 scanner source:(self readStream). |
3484 tok := scanner nextToken. |
3484 tok := scanner nextToken. |
3485 tok ~~ #Identifier ifTrue:[ |
3485 tok ~~ #Identifier ifTrue:[ |
3486 ^ false |
3486 ^ false |
3487 ]. |
3487 ]. |
3488 scanner tokenPosition == 1 ifFalse:[^ false]. |
3488 scanner tokenPosition == 1 ifFalse:[^ false]. |
3489 ^ scanner sourceStream atEnd. |
3489 ^ scanner sourceStream atEnd. |
3490 |
3490 |
3491 " |
3491 " |
3492 'foo' isValidSmalltalkIdentifier |
3492 'foo' isValidSmalltalkIdentifier |
3493 '1foo' isValidSmalltalkIdentifier |
3493 '1foo' isValidSmalltalkIdentifier |
3494 '_foo' isValidSmalltalkIdentifier |
3494 '_foo' isValidSmalltalkIdentifier |
3495 '_foo_bar_' isValidSmalltalkIdentifier |
3495 '_foo_bar_' isValidSmalltalkIdentifier |
3496 'foo ' isValidSmalltalkIdentifier |
3496 'foo ' isValidSmalltalkIdentifier |
3497 ' foo' isValidSmalltalkIdentifier |
3497 ' foo' isValidSmalltalkIdentifier |
3498 " |
3498 " |
3499 ! |
3499 ! |
3500 |
3500 |
3501 leftIndent |
3501 leftIndent |
3502 "if the receiver starts with spaces, return the number of spaces |
3502 "if the receiver starts with spaces, return the number of spaces |
3507 end "{Class: SmallInteger }"| |
3507 end "{Class: SmallInteger }"| |
3508 |
3508 |
3509 index := 1. |
3509 index := 1. |
3510 end := self size. |
3510 end := self size. |
3511 [index <= end] whileTrue:[ |
3511 [index <= end] whileTrue:[ |
3512 (self at:index) isSeparator ifFalse:[^ index - 1]. |
3512 (self at:index) isSeparator ifFalse:[^ index - 1]. |
3513 index := index + 1 |
3513 index := index + 1 |
3514 ]. |
3514 ]. |
3515 ^ end |
3515 ^ end |
3516 |
3516 |
3517 " |
3517 " |
3518 ' hello' leftIndent |
3518 ' hello' leftIndent |
3519 'foo ' leftIndent |
3519 'foo ' leftIndent |
3520 ' ' leftIndent |
3520 ' ' leftIndent |
3521 " |
3521 " |
3522 |
3522 |
3523 "Modified: 20.4.1996 / 19:28:43 / cg" |
3523 "Modified: 20.4.1996 / 19:28:43 / cg" |
3524 ! |
3524 ! |
3525 |
3525 |
3526 stringSpecies |
3526 stringSpecies |
3527 "return the underlying strings bitsPerCharacter |
3527 "return the underlying strings bitsPerCharacter |
3528 (i.e. is it a regular String or a TwoByteString)" |
3528 (i.e. is it a regular String or a TwoByteString)" |
3529 |
3529 |
3530 |string| |
3530 |string| |
3531 |
3531 |
3532 (string := self string) == self ifTrue:[^ self class]. |
3532 (string := self string) == self ifTrue:[^ self class]. |
3533 ^ string stringSpecies |
3533 ^ string stringSpecies |
3534 |
3534 |
3535 " |
3535 " |
3536 'hello' stringSpecies |
3536 'hello' stringSpecies |
3537 'hello' asText allBold stringSpecies |
3537 'hello' asText allBold stringSpecies |
3538 " |
3538 " |
3539 ! |
3539 ! |
3540 |
3540 |
3541 widthFrom:startIndex to:endIndex on:aGC |
3541 widthFrom:startIndex to:endIndex on:aGC |
3542 "return ths size of part of the recevier in device units if displayed on aGC" |
3542 "return ths size of part of the recevier in device units if displayed on aGC" |
3543 |
3543 |
3544 ^ (aGC font onDevice:aGC device) widthOf:self from:startIndex to:endIndex |
3544 ^ (aGC font onDevice:aGC device) widthOf:self from:startIndex to:endIndex |
3545 |
3545 |
3546 " |
3546 " |
3547 'hello world' widthFrom:1 to:5 on:(View new) |
3547 'hello world' widthFrom:1 to:5 on:(View new) |
3548 'hello' widthOn:(View new) |
3548 'hello' widthOn:(View new) |
3549 " |
3549 " |
3550 ! |
3550 ! |
3551 |
3551 |
3552 widthOn:aGC |
3552 widthOn:aGC |
3553 "return ths size of the recevier in device units if displayed on aGC" |
3553 "return ths size of the recevier in device units if displayed on aGC" |
3554 |
3554 |
3555 ^ (aGC font onDevice:aGC device) widthOf:self |
3555 ^ (aGC font onDevice:aGC device) widthOf:self |
3556 |
3556 |
3557 " |
3557 " |
3558 'hello world' widthOn:(View new) |
3558 'hello world' widthOn:(View new) |
3559 " |
3559 " |
3560 |
3560 |
3561 "Created: 12.5.1996 / 20:09:29 / cg" |
3561 "Created: 12.5.1996 / 20:09:29 / cg" |
3562 "Modified: 17.4.1997 / 12:50:23 / cg" |
3562 "Modified: 17.4.1997 / 12:50:23 / cg" |
3563 ! ! |
3563 ! ! |
3568 "return a collection of substrings in the receiver, which match the regular expression in rxString" |
3568 "return a collection of substrings in the receiver, which match the regular expression in rxString" |
3569 |
3569 |
3570 ^ rxString asRegex matchesIn: self |
3570 ^ rxString asRegex matchesIn: self |
3571 |
3571 |
3572 " |
3572 " |
3573 '1234 abcd 3456 defg' allRegexMatches:'[0-9]+' |
3573 '1234 abcd 3456 defg' allRegexMatches:'[0-9]+' |
3574 |
3574 |
3575 '[0-9]+' asRegex matchesIn:'1234 abcd 3456 defg' |
3575 '[0-9]+' asRegex matchesIn:'1234 abcd 3456 defg' |
3576 " |
3576 " |
3577 ! |
3577 ! |
3578 |
3578 |
3579 asRegex |
3579 asRegex |
3580 "Compile the receiver as a regex matcher. |
3580 "Compile the receiver as a regex matcher. |
3581 May raise RxParser>>syntaxErrorSignal or RxParser>>compilationErrorSignal. |
3581 May raise RxParser>>syntaxErrorSignal or RxParser>>compilationErrorSignal. |
3582 This is a part of the Regular Expression Matcher package, |
3582 This is a part of the Regular Expression Matcher package, |
3583 (c) 1996, 1999 Vassili Bykov. |
3583 (c) 1996, 1999 Vassili Bykov. |
3584 Refer to `documentation' protocol of RxParser class for details." |
3584 Refer to `documentation' protocol of RxParser class for details." |
3585 |
3585 |
3586 ^ Regex::RxParser preferredMatcherClass |
3586 ^ Regex::RxParser preferredMatcherClass |
3587 for: (Regex::RxParser new parse: self) |
3587 for: (Regex::RxParser new parse: self) |
3588 ! |
3588 ! |
3589 |
3589 |
3590 asRegexIgnoringCase |
3590 asRegexIgnoringCase |
3591 "Compile the receiver as a regex matcher. |
3591 "Compile the receiver as a regex matcher. |
3592 May raise RxParser>>syntaxErrorSignal or RxParser>>compilationErrorSignal. |
3592 May raise RxParser>>syntaxErrorSignal or RxParser>>compilationErrorSignal. |
3593 This is a part of the Regular Expression Matcher package, |
3593 This is a part of the Regular Expression Matcher package, |
3594 (c) 1996, 1999 Vassili Bykov. |
3594 (c) 1996, 1999 Vassili Bykov. |
3595 Refer to `documentation' protocol of RxParser class for details." |
3595 Refer to `documentation' protocol of RxParser class for details." |
3596 |
3596 |
3597 ^ Regex::RxParser preferredMatcherClass |
3597 ^ Regex::RxParser preferredMatcherClass |
3598 for: (Regex::RxParser new parse: self) |
3598 for: (Regex::RxParser new parse: self) |
3599 ignoreCase: true |
3599 ignoreCase: true |
3600 ! |
3600 ! |
3601 |
3601 |
3602 copyWithRegex: rxString matchesReplacedWith: aString |
3602 copyWithRegex: rxString matchesReplacedWith: aString |
3603 ^ rxString asRegex copy: self replacingMatchesWith: aString |
3603 ^ rxString asRegex copy: self replacingMatchesWith: aString |
3604 ! |
3604 ! |
3606 copyWithRegex: rxString matchesTranslatedUsing: aBlock |
3606 copyWithRegex: rxString matchesTranslatedUsing: aBlock |
3607 ^ rxString asRegex copy: self translatingMatchesUsing: aBlock |
3607 ^ rxString asRegex copy: self translatingMatchesUsing: aBlock |
3608 ! |
3608 ! |
3609 |
3609 |
3610 matchesRegex: regexString |
3610 matchesRegex: regexString |
3611 "Test if the receiver matches a regex. |
3611 "Test if the receiver matches a regex. |
3612 May raise RxParser>>regexErrorSignal or child signals. |
3612 May raise RxParser>>regexErrorSignal or child signals. |
3613 This is a part of the Regular Expression Matcher package, |
3613 This is a part of the Regular Expression Matcher package, |
3614 (c) 1996, 1999 Vassili Bykov. |
3614 (c) 1996, 1999 Vassili Bykov. |
3615 Refer to `documentation' protocol of RxParser class for details." |
3615 Refer to `documentation' protocol of RxParser class for details." |
3616 |
3616 |
3617 ^regexString asRegex matches: self |
3617 ^regexString asRegex matches: self |
3618 |
3618 |
3619 " |
3619 " |
3620 'hello world' matchesRegex:'h.*d'. |
3620 'hello world' matchesRegex:'h.*d'. |
3621 " |
3621 " |
3622 ! |
3622 ! |
3623 |
3623 |
3624 matchesRegexIgnoringCase: regexString |
3624 matchesRegexIgnoringCase: regexString |
3625 "Test if the receiver matches a regex. |
3625 "Test if the receiver matches a regex. |
3626 May raise RxParser>>regexErrorSignal or child signals. |
3626 May raise RxParser>>regexErrorSignal or child signals. |
3627 This is a part of the Regular Expression Matcher package, |
3627 This is a part of the Regular Expression Matcher package, |
3628 (c) 1996, 1999 Vassili Bykov. |
3628 (c) 1996, 1999 Vassili Bykov. |
3629 Refer to `documentation' protocol of RxParser class for details." |
3629 Refer to `documentation' protocol of RxParser class for details." |
3630 |
3630 |
3631 ^regexString asRegexIgnoringCase matches: self |
3631 ^regexString asRegexIgnoringCase matches: self |
3632 |
3632 |
3633 " |
3633 " |
3634 'hElLo wOrld' matchesRegexIgnoringCase:'h.*d'. |
3634 'hElLo wOrld' matchesRegexIgnoringCase:'h.*d'. |
3635 " |
3635 " |
3636 ! |
3636 ! |
3637 |
3637 |
3638 prefixMatchesRegex: regexString |
3638 prefixMatchesRegex: regexString |
3639 "Test if the receiver's prefix matches a regex. |
3639 "Test if the receiver's prefix matches a regex. |
3640 May raise RxParser class>>regexErrorSignal or child signals. |
3640 May raise RxParser class>>regexErrorSignal or child signals. |
3641 This is a part of the Regular Expression Matcher package, |
3641 This is a part of the Regular Expression Matcher package, |
3642 (c) 1996, 1999 Vassili Bykov. |
3642 (c) 1996, 1999 Vassili Bykov. |
3643 Refer to `documentation' protocol of RxParser class for details." |
3643 Refer to `documentation' protocol of RxParser class for details." |
3644 |
3644 |
3645 ^regexString asRegex matchesPrefix: self |
3645 ^regexString asRegex matchesPrefix: self |
3646 ! |
3646 ! |
3647 |
3647 |
3648 prefixMatchesRegexIgnoringCase: regexString |
3648 prefixMatchesRegexIgnoringCase: regexString |
3649 "Test if the receiver's prefix matches a regex. |
3649 "Test if the receiver's prefix matches a regex. |
3650 May raise RxParser class>>regexErrorSignal or child signals. |
3650 May raise RxParser class>>regexErrorSignal or child signals. |
3651 This is a part of the Regular Expression Matcher package, |
3651 This is a part of the Regular Expression Matcher package, |
3652 (c) 1996, 1999 Vassili Bykov. |
3652 (c) 1996, 1999 Vassili Bykov. |
3653 Refer to `documentation' protocol of RxParser class for details." |
3653 Refer to `documentation' protocol of RxParser class for details." |
3654 |
3654 |
3655 ^regexString asRegexIgnoringCase matchesPrefix: self |
3655 ^regexString asRegexIgnoringCase matchesPrefix: self |
3656 ! |
3656 ! |
3657 |
3657 |
3660 and collect the returned values." |
3660 and collect the returned values." |
3661 |
3661 |
3662 ^ rxString asRegex matchesIn: self collect: aBlock |
3662 ^ rxString asRegex matchesIn: self collect: aBlock |
3663 |
3663 |
3664 " |
3664 " |
3665 'hello world' regex:'\w+' matchesCollect:[:each | each asUppercase ]. |
3665 'hello world' regex:'\w+' matchesCollect:[:each | each asUppercase ]. |
3666 '1234 hello 456 world' regex:'\d+' matchesCollect:[:each | Number readFrom:each ]. |
3666 '1234 hello 456 world' regex:'\d+' matchesCollect:[:each | Number readFrom:each ]. |
3667 " |
3667 " |
3668 ! |
3668 ! |
3669 |
3669 |
3670 regex:rxString matchesDo: aBlock |
3670 regex:rxString matchesDo: aBlock |
3671 "for all substrings in the receiver which match the regular expression in rxString, evaluate aBlock" |
3671 "for all substrings in the receiver which match the regular expression in rxString, evaluate aBlock" |
3679 |
3679 |
3680 !CharacterArray methodsFor:'special string converting'! |
3680 !CharacterArray methodsFor:'special string converting'! |
3681 |
3681 |
3682 chopTo:maxLen |
3682 chopTo:maxLen |
3683 "if the receivers size is less or equal to maxLen, return it. |
3683 "if the receivers size is less or equal to maxLen, return it. |
3684 Otherwise, return a copy of the receiver, where some characters |
3684 Otherwise, return a copy of the receiver, where some characters |
3685 in the middle have been removed for a total string length |
3685 in the middle have been removed for a total string length |
3686 of maxLen." |
3686 of maxLen." |
3687 |
3687 |
3688 |sz n1 n2| |
3688 |sz n1 n2| |
3689 |
3689 |
3694 ]. |
3694 ]. |
3695 ^ (self copyFrom:1 to:n1) , (self copyFrom:sz - n2 + 1) |
3695 ^ (self copyFrom:1 to:n1) , (self copyFrom:sz - n2 + 1) |
3696 ] |
3696 ] |
3697 |
3697 |
3698 " |
3698 " |
3699 '12345678901234' chopTo:15 |
3699 '12345678901234' chopTo:15 |
3700 '123456789012345' chopTo:15 |
3700 '123456789012345' chopTo:15 |
3701 '1234567890123456' chopTo:15 |
3701 '1234567890123456' chopTo:15 |
3702 'aShortString' chopTo:15 |
3702 'aShortString' chopTo:15 |
3703 'aVeryLongNameForAStringThatShouldBeShortened' chopTo:15 |
3703 'aVeryLongNameForAStringThatShouldBeShortened' chopTo:15 |
3704 " |
3704 " |
3705 ! |
3705 ! |
3706 |
3706 |
3707 contractAtBeginningTo:maxLen |
3707 contractAtBeginningTo:maxLen |
3708 "if the receivers size is less or equal to maxLen, return it. |
3708 "if the receivers size is less or equal to maxLen, return it. |
3709 Otherwise, return a copy of the receiver, where some characters |
3709 Otherwise, return a copy of the receiver, where some characters |
3710 at the beginning have been replaced by '...' for a total string length |
3710 at the beginning have been replaced by '...' for a total string length |
3711 of maxLen. Can be used to abbreviate long entries in tables." |
3711 of maxLen. Can be used to abbreviate long entries in tables." |
3712 |
3712 |
3713 |sz| |
3713 |sz| |
3714 |
3714 |
3715 (sz := self size) > maxLen ifTrue:[ |
3715 (sz := self size) > maxLen ifTrue:[ |
3716 ^ '...' , (self copyFrom:(sz - (maxLen - 4))) |
3716 ^ '...' , (self copyFrom:(sz - (maxLen - 4))) |
3717 ] |
3717 ] |
3718 |
3718 |
3719 " |
3719 " |
3720 '12345678901234' contractAtBeginningTo:15 |
3720 '12345678901234' contractAtBeginningTo:15 |
3721 '123456789012345' contractAtBeginningTo:15 |
3721 '123456789012345' contractAtBeginningTo:15 |
3722 '1234567890123456' contractAtBeginningTo:15 |
3722 '1234567890123456' contractAtBeginningTo:15 |
3723 'aShortString' contractAtBeginningTo:15 |
3723 'aShortString' contractAtBeginningTo:15 |
3724 'aVeryLongNameForAStringThatShouldBeShortened' contractAtBeginningTo:15 |
3724 'aVeryLongNameForAStringThatShouldBeShortened' contractAtBeginningTo:15 |
3725 " |
3725 " |
3726 ! |
3726 ! |
3727 |
3727 |
3728 contractAtEndTo:maxLen |
3728 contractAtEndTo:maxLen |
3729 "if the receivers size is less or equal to maxLen, return it. |
3729 "if the receivers size is less or equal to maxLen, return it. |
3730 Otherwise, return a copy of the receiver, where some characters |
3730 Otherwise, return a copy of the receiver, where some characters |
3731 at the end have been replaced by '...' for a total string length |
3731 at the end have been replaced by '...' for a total string length |
3732 of maxLen. Can be used to abbreviate long entries in tables." |
3732 of maxLen. Can be used to abbreviate long entries in tables." |
3733 |
3733 |
3734 |sz| |
3734 |sz| |
3735 |
3735 |
3737 ^ self copyReplaceFrom:maxLen - 3 |
3737 ^ self copyReplaceFrom:maxLen - 3 |
3738 with:'...' |
3738 with:'...' |
3739 ] |
3739 ] |
3740 |
3740 |
3741 " |
3741 " |
3742 '12345678901234' contractAtEndTo:15 |
3742 '12345678901234' contractAtEndTo:15 |
3743 '123456789012345' contractAtEndTo:15 |
3743 '123456789012345' contractAtEndTo:15 |
3744 '1234567890123456' contractAtEndTo:15 |
3744 '1234567890123456' contractAtEndTo:15 |
3745 'aShortString' contractAtEndTo:15 |
3745 'aShortString' contractAtEndTo:15 |
3746 'aVeryLongNameForAStringThatShouldBeShortened' contractAtEndTo:15 |
3746 'aVeryLongNameForAStringThatShouldBeShortened' contractAtEndTo:15 |
3747 " |
3747 " |
3748 ! |
3748 ! |
3749 |
3749 |
3750 contractTo:maxLen |
3750 contractTo:maxLen |
3751 "if the receivers size is less or equal to maxLen, return it. |
3751 "if the receivers size is less or equal to maxLen, return it. |
3752 Otherwise, return a copy of the receiver, where some characters |
3752 Otherwise, return a copy of the receiver, where some characters |
3753 in the middle have been replaced by '...' for a total string length |
3753 in the middle have been replaced by '...' for a total string length |
3754 of maxLen. Can be used to abbreviate long entries in tables." |
3754 of maxLen. Can be used to abbreviate long entries in tables." |
3755 |
3755 |
3756 |sz "{ SmallInteger }" |
3756 |sz "{ SmallInteger }" |
3757 halfSize "{ SmallInteger }"| |
3757 halfSize "{ SmallInteger }"| |
3762 to:sz - maxLen + halfSize + 1 |
3762 to:sz - maxLen + halfSize + 1 |
3763 with:'...' |
3763 with:'...' |
3764 ] |
3764 ] |
3765 |
3765 |
3766 " |
3766 " |
3767 '12345678901234' contractTo:15 |
3767 '12345678901234' contractTo:15 |
3768 '123456789012345' contractTo:15 |
3768 '123456789012345' contractTo:15 |
3769 '1234567890123456' contractTo:15 |
3769 '1234567890123456' contractTo:15 |
3770 'aShortString' contractTo:15 |
3770 'aShortString' contractTo:15 |
3771 'aVeryLongNameForAStringThatShouldBeShortened' contractTo:15 |
3771 'aVeryLongNameForAStringThatShouldBeShortened' contractTo:15 |
3772 " |
3772 " |
3773 ! |
3773 ! |
3774 |
3774 |
3775 expandPlaceholdersWith:argArrayOrDictionary |
3775 expandPlaceholdersWith:argArrayOrDictionary |
3776 "return a copy of the receiver, where all %i escapes are |
3776 "return a copy of the receiver, where all %i escapes are |
3794 |
3794 |
3795 expandedString := self species new:0. |
3795 expandedString := self species new:0. |
3796 stop := self size. |
3796 stop := self size. |
3797 start := 1. |
3797 start := 1. |
3798 [start <= stop] whileTrue:[ |
3798 [start <= stop] whileTrue:[ |
3799 idx := self indexOf:$% startingAt:start. |
3799 idx := self indexOf:$% startingAt:start. |
3800 (idx == 0 or:[idx == stop]) ifTrue:[ |
3800 (idx == 0 or:[idx == stop]) ifTrue:[ |
3801 ^ expandedString , (self copyFrom:start to:stop) |
3801 ^ expandedString , (self copyFrom:start to:stop) |
3802 ]. |
3802 ]. |
3803 "found a %" |
3803 "found a %" |
3804 expandedString := expandedString , (self copyFrom:start to:(idx - 1)). |
3804 expandedString := expandedString , (self copyFrom:start to:(idx - 1)). |
3805 next := self at:(idx + 1). |
3805 next := self at:(idx + 1). |
3806 (next == $%) ifTrue:[ |
3806 (next == $%) ifTrue:[ |
3807 expandedString := expandedString , '%' |
3807 expandedString := expandedString , '%' |
3808 ] ifFalse:[ |
3808 ] ifFalse:[ |
3809 (next between:$1 and:$9) ifTrue:[ |
3809 (next between:$1 and:$9) ifTrue:[ |
3810 v := argArrayOrDictionary at:(next digitValue) ifAbsent:nil |
3810 v := argArrayOrDictionary at:(next digitValue) ifAbsent:nil |
3811 ] ifFalse:[ |
3811 ] ifFalse:[ |
3812 next == $( ifTrue:[ |
3812 next == $( ifTrue:[ |
3813 idx2 := self indexOf:$) startingAt:idx+2. |
3813 idx2 := self indexOf:$) startingAt:idx+2. |
3814 key := self copyFrom:idx+2 to:idx2-1. |
3814 key := self copyFrom:idx+2 to:idx2-1. |
3815 idx := idx2 - 1. |
3815 idx := idx2 - 1. |
3816 keyAsSymbol := key asSymbolIfInterned. |
3816 keyAsSymbol := key asSymbolIfInterned. |
3817 (keyAsSymbol notNil and:[ argArrayOrDictionary includesKey:keyAsSymbol ]) ifTrue:[ |
3817 (keyAsSymbol notNil and:[ argArrayOrDictionary includesKey:keyAsSymbol ]) ifTrue:[ |
3818 v := argArrayOrDictionary at:keyAsSymbol |
3818 v := argArrayOrDictionary at:keyAsSymbol |
3819 ] ifFalse:[ |
3819 ] ifFalse:[ |
3820 (key conform:[:each | each isDigit]) ifTrue:[ |
3820 (key conform:[:each | each isDigit]) ifTrue:[ |
3821 key := Number readFrom:key onError:nil. |
3821 key := Number readFrom:key onError:nil. |
3822 ]. |
3822 ]. |
3823 v := argArrayOrDictionary at:key ifAbsent:nil |
3823 v := argArrayOrDictionary at:key ifAbsent:nil |
3824 ]. |
3824 ]. |
3825 ] ifFalse:[ |
3825 ] ifFalse:[ |
3826 v := argArrayOrDictionary at:next ifAbsent:nil. |
3826 v := argArrayOrDictionary at:next ifAbsent:nil. |
3827 v isNil ifTrue:[ |
3827 v isNil ifTrue:[ |
3828 (argArrayOrDictionary includesKey:next asString) ifTrue:[ |
3828 (argArrayOrDictionary includesKey:next asString) ifTrue:[ |
3829 v := argArrayOrDictionary at:next asString asSymbol ifAbsent:nil. |
3829 v := argArrayOrDictionary at:next asString asSymbol ifAbsent:nil. |
3830 ] ifFalse:[ |
3830 ] ifFalse:[ |
3831 v := String with:$% with:next. "/ next asString. |
3831 v := String with:$% with:next. "/ next asString. |
3832 ] |
3832 ] |
3833 ]. |
3833 ]. |
3834 ] |
3834 ] |
3835 ]. |
3835 ]. |
3836 v isNil |
3836 v isNil |
3837 ifTrue:[v := ''] |
3837 ifTrue:[v := ''] |
3838 ifFalse:[ |
3838 ifFalse:[ |
3839 v isBlock ifTrue:[ |
3839 v isBlock ifTrue:[ |
3840 v := v value |
3840 v := v value |
3841 ]]. |
3841 ]]. |
3842 expandedString := expandedString , v printString |
3842 expandedString := expandedString , v printString |
3843 ]. |
3843 ]. |
3844 start := idx + 2 |
3844 start := idx + 2 |
3845 ]. |
3845 ]. |
3846 ^ expandedString |
3846 ^ expandedString |
3847 |
3847 |
3848 " |
3848 " |
3849 'hello %1' expandPlaceholdersWith:#('world') |
3849 'hello %1' expandPlaceholdersWith:#('world') |
3850 'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') |
3850 'hello %1; how is %2' expandPlaceholdersWith:#('world' 'this') |
3851 'hello %2; how is %1' expandPlaceholdersWith:#('world' 'this') |
3851 'hello %2; how is %1' expandPlaceholdersWith:#('world' 'this') |
3852 '%1 plus %2 gives %3 ' expandPlaceholdersWith:#(4 5 9) |
3852 '%1 plus %2 gives %3 ' expandPlaceholdersWith:#(4 5 9) |
3853 '%%(1)0 gives %(1)0' expandPlaceholdersWith:#(123) |
3853 '%%(1)0 gives %(1)0' expandPlaceholdersWith:#(123) |
3854 '%%10 gives %10' expandPlaceholdersWith:#(123) |
3854 '%%10 gives %10' expandPlaceholdersWith:#(123) |
3855 '%%(10) gives %(10)' expandPlaceholdersWith:#(123) |
3855 '%%(10) gives %(10)' expandPlaceholdersWith:#(123) |
3856 " |
3856 " |
3857 |
3857 |
3858 " |
3858 " |
3859 |dict| |
3859 |dict| |
3860 |
3860 |
3861 dict := Dictionary new. |
3861 dict := Dictionary new. |
3862 dict at:1 put:'one'. |
3862 dict at:1 put:'one'. |
3863 dict at:$a put:'AAAAA'. |
3863 dict at:$a put:'AAAAA'. |
3864 dict at:$b put:[ Time now ]. |
3864 dict at:$b put:[ Time now ]. |
3865 'hello %1 %a %b' expandPlaceholdersWith:dict |
3865 'hello %1 %a %b' expandPlaceholdersWith:dict |
3866 " |
3866 " |
3867 |
3867 |
3868 "Modified: 1.7.1997 / 00:53:24 / cg" |
3868 "Modified: 1.7.1997 / 00:53:24 / cg" |
3869 ! |
3869 ! |
3870 |
3870 |
3884 withEscapes |
3884 withEscapes |
3885 "return a new string consisting of receivers characters |
3885 "return a new string consisting of receivers characters |
3886 with all \X-character escapes replaced by corresponding-characters. |
3886 with all \X-character escapes replaced by corresponding-characters. |
3887 (similar to the way C-language Strings are converted). |
3887 (similar to the way C-language Strings are converted). |
3888 The following escapes are supported: |
3888 The following escapes are supported: |
3889 \r return character |
3889 \r return character |
3890 \n newline character |
3890 \n newline character |
3891 \b backspace character |
3891 \b backspace character |
3892 \f formfeed character |
3892 \f formfeed character |
3893 \t tab character |
3893 \t tab character |
3894 \e escape character |
3894 \e escape character |
3895 \\ the \ character itself |
3895 \\ the \ character itself |
3896 \nnn three digit octal number defining the characters ascii value |
3896 \nnn three digit octal number defining the characters ascii value |
3897 \other other |
3897 \other other |
3898 |
3898 |
3899 Notice, that \' is NOT a valid escape, since the general syntax of |
3899 Notice, that \' is NOT a valid escape, since the general syntax of |
3900 string constants is not affected by this method. |
3900 string constants is not affected by this method. |
3901 |
3901 |
3902 Although easily implementable, this is NOT done automatically |
3902 Although easily implementable, this is NOT done automatically |
3910 |sz "{ SmallInteger }" |
3910 |sz "{ SmallInteger }" |
3911 newSize "{ SmallInteger }" |
3911 newSize "{ SmallInteger }" |
3912 srcIdx "{ SmallInteger }" |
3912 srcIdx "{ SmallInteger }" |
3913 dstIdx "{ SmallInteger }" |
3913 dstIdx "{ SmallInteger }" |
3914 val "{ SmallInteger }" |
3914 val "{ SmallInteger }" |
3915 newString next hasEmphasis e| |
3915 newString next hasEmphasis e| |
3916 |
3916 |
3917 " |
3917 " |
3918 first, count the number of escapes, to allow preallocation |
3918 first, count the number of escapes, to allow preallocation |
3919 of the new string ... |
3919 of the new string ... |
3920 (it is faster to scan the string twice than to reallocate it multiple |
3920 (it is faster to scan the string twice than to reallocate it multiple |
3921 times in a WriteStream) |
3921 times in a WriteStream) |
3922 " |
3922 " |
3923 sz := newSize := self size. |
3923 sz := newSize := self size. |
3924 srcIdx := 1. |
3924 srcIdx := 1. |
3925 [(srcIdx := self indexOf:$\ startingAt:srcIdx) ~~ 0] whileTrue:[ |
3925 [(srcIdx := self indexOf:$\ startingAt:srcIdx) ~~ 0] whileTrue:[ |
3926 srcIdx == sz ifFalse:[ |
3926 srcIdx == sz ifFalse:[ |
3927 newSize := newSize - 1. |
3927 newSize := newSize - 1. |
3928 srcIdx := srcIdx + 1. |
3928 srcIdx := srcIdx + 1. |
3929 next := self at:srcIdx. |
3929 next := self at:srcIdx. |
3930 next == $0 ifTrue:[ |
3930 next == $0 ifTrue:[ |
3931 [srcIdx < sz and:[next isDigit]] whileTrue:[ |
3931 [srcIdx < sz and:[next isDigit]] whileTrue:[ |
3932 newSize := newSize - 1. srcIdx := srcIdx + 1. next := self at:srcIdx. |
3932 newSize := newSize - 1. srcIdx := srcIdx + 1. next := self at:srcIdx. |
3933 ] |
3933 ] |
3934 ]. |
3934 ]. |
3935 ]. |
3935 ]. |
3936 srcIdx := srcIdx + 1. |
3936 srcIdx := srcIdx + 1. |
3937 ]. |
3937 ]. |
3938 |
3938 |
3939 newSize == sz ifTrue:[ |
3939 newSize == sz ifTrue:[ |
3940 ^ self |
3940 ^ self |
3941 ]. |
3941 ]. |
3942 |
3942 |
3943 newString := self species new:newSize. |
3943 newString := self species new:newSize. |
3944 |
3944 |
3945 hasEmphasis := self hasChangeOfEmphasis. |
3945 hasEmphasis := self hasChangeOfEmphasis. |
3947 " |
3947 " |
3948 copy over, replace escapes |
3948 copy over, replace escapes |
3949 " |
3949 " |
3950 srcIdx := dstIdx := 1. |
3950 srcIdx := dstIdx := 1. |
3951 [srcIdx <= sz] whileTrue:[ |
3951 [srcIdx <= sz] whileTrue:[ |
3952 next := self at:srcIdx. |
3952 next := self at:srcIdx. |
3953 hasEmphasis ifTrue:[ |
3953 hasEmphasis ifTrue:[ |
3954 e := self emphasisAt:srcIdx |
3954 e := self emphasisAt:srcIdx |
3955 ]. |
3955 ]. |
3956 srcIdx := srcIdx + 1. |
3956 srcIdx := srcIdx + 1. |
3957 next == $\ ifTrue:[ |
3957 next == $\ ifTrue:[ |
3958 srcIdx <= sz ifTrue:[ |
3958 srcIdx <= sz ifTrue:[ |
3959 next := self at:srcIdx. |
3959 next := self at:srcIdx. |
3960 srcIdx := srcIdx + 1. |
3960 srcIdx := srcIdx + 1. |
3961 next == $r ifTrue:[ |
3961 next == $r ifTrue:[ |
3962 next := Character return |
3962 next := Character return |
3963 ] ifFalse:[ |
3963 ] ifFalse:[ |
3964 next == $n ifTrue:[ |
3964 next == $n ifTrue:[ |
3965 next := Character nl |
3965 next := Character nl |
3966 ] ifFalse:[ |
3966 ] ifFalse:[ |
3967 next == $b ifTrue:[ |
3967 next == $b ifTrue:[ |
3968 next := Character backspace |
3968 next := Character backspace |
3969 ] ifFalse:[ |
3969 ] ifFalse:[ |
3970 next == $f ifTrue:[ |
3970 next == $f ifTrue:[ |
3971 next := Character newPage |
3971 next := Character newPage |
3972 ] ifFalse:[ |
3972 ] ifFalse:[ |
3973 next == $t ifTrue:[ |
3973 next == $t ifTrue:[ |
3974 next := Character tab |
3974 next := Character tab |
3975 ] ifFalse:[ |
3975 ] ifFalse:[ |
3976 next == $e ifTrue:[ |
3976 next == $e ifTrue:[ |
3977 next := Character esc |
3977 next := Character esc |
3978 ] ifFalse:[ |
3978 ] ifFalse:[ |
3979 next == $0 ifTrue:[ |
3979 next == $0 ifTrue:[ |
3980 val := 0. |
3980 val := 0. |
3981 [next notNil and:[next isDigit]] whileTrue:[ |
3981 [next notNil and:[next isDigit]] whileTrue:[ |
3982 val := val * 8 + next digitValue. |
3982 val := val * 8 + next digitValue. |
3983 srcIdx <= sz ifTrue:[ |
3983 srcIdx <= sz ifTrue:[ |
3984 next := self at:srcIdx. |
3984 next := self at:srcIdx. |
3985 srcIdx := srcIdx + 1. |
3985 srcIdx := srcIdx + 1. |
3986 ] ifFalse:[ |
3986 ] ifFalse:[ |
3987 next := nil |
3987 next := nil |
3988 ] |
3988 ] |
3989 ]. |
3989 ]. |
3990 next := Character value:val. |
3990 next := Character value:val. |
3991 ] |
3991 ] |
3992 ] |
3992 ] |
3993 ] |
3993 ] |
3994 ] |
3994 ] |
3995 ] |
3995 ] |
3996 ] |
3996 ] |
3997 ]. |
3997 ]. |
3998 ]. |
3998 ]. |
3999 ]. |
3999 ]. |
4000 newString at:dstIdx put:next. |
4000 newString at:dstIdx put:next. |
4001 hasEmphasis ifTrue:[ |
4001 hasEmphasis ifTrue:[ |
4002 newString emphasisAt:dstIdx put:e |
4002 newString emphasisAt:dstIdx put:e |
4003 ]. |
4003 ]. |
4004 dstIdx := dstIdx + 1. |
4004 dstIdx := dstIdx + 1. |
4005 ]. |
4005 ]. |
4006 ^ newString |
4006 ^ newString |
4007 |
4007 |
4008 " |
4008 " |
4009 'hello world' withEscapes |
4009 'hello world' withEscapes |
4010 'hello\world' withEscapes |
4010 'hello\world' withEscapes |
4011 'hello\world\' withEscapes |
4011 'hello\world\' withEscapes |
4012 'hello world\' withEscapes |
4012 'hello world\' withEscapes |
4013 'hello\tworld' withEscapes |
4013 'hello\tworld' withEscapes |
4014 'hello\nworld\na\n\tnice\n\t\tstring' withEscapes |
4014 'hello\nworld\na\n\tnice\n\t\tstring' withEscapes |
4015 'hello\tworld\n' withEscapes |
4015 'hello\tworld\n' withEscapes |
4016 'hello\010world' withEscapes |
4016 'hello\010world' withEscapes |
4017 'hello\r\nworld' withEscapes |
4017 'hello\r\nworld' withEscapes |
4018 " |
4018 " |
4019 |
4019 |
4020 "Modified: 12.5.1996 / 12:53:34 / cg" |
4020 "Modified: 12.5.1996 / 12:53:34 / cg" |
4021 ! |
4021 ! |
4022 |
4022 |
4030 escape := self class matchEscapeCharacter. |
4030 escape := self class matchEscapeCharacter. |
4031 |
4031 |
4032 in := self readStream. |
4032 in := self readStream. |
4033 out := WriteStream on:(self species new:self size). |
4033 out := WriteStream on:(self species new:self size). |
4034 [in atEnd] whileFalse:[ |
4034 [in atEnd] whileFalse:[ |
4035 c := in next. |
4035 c := in next. |
4036 (c == escape or:['*[#' includes:c]) ifTrue:[ |
4036 (c == escape or:['*[#' includes:c]) ifTrue:[ |
4037 out nextPut:$\. |
4037 out nextPut:$\. |
4038 ]. |
4038 ]. |
4039 out nextPut:c. |
4039 out nextPut:c. |
4040 ]. |
4040 ]. |
4041 ^ out contents. |
4041 ^ out contents. |
4042 |
4042 |
4043 " |
4043 " |
4044 '*foo' withMatchEscapes |
4044 '*foo' withMatchEscapes |
4045 '\*foo' withMatchEscapes |
4045 '\*foo' withMatchEscapes |
4046 '*foo' withMatchEscapes |
4046 '*foo' withMatchEscapes |
4047 '\\*foo' withMatchEscapes |
4047 '\\*foo' withMatchEscapes |
4048 'foo*' withMatchEscapes |
4048 'foo*' withMatchEscapes |
4049 'foo\*' withMatchEscapes |
4049 'foo\*' withMatchEscapes |
4050 'foo\' withMatchEscapes |
4050 'foo\' withMatchEscapes |
4051 'f*o*o' withMatchEscapes |
4051 'f*o*o' withMatchEscapes |
4052 " |
4052 " |
4053 |
4053 |
4054 "Modified: 2.4.1997 / 18:13:04 / cg" |
4054 "Modified: 2.4.1997 / 18:13:04 / cg" |
4055 ! |
4055 ! |
4056 |
4056 |
4057 withTabs |
4057 withTabs |
4058 "return a string consisting of the receivers characters |
4058 "return a string consisting of the receivers characters |
4059 where leading spaces are replaced by tabulator characters (assuming 8-col tabs). |
4059 where leading spaces are replaced by tabulator characters (assuming 8-col tabs). |
4060 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4060 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4061 otherwise a new string is returned. |
4061 otherwise a new string is returned. |
4062 Limitation: only the very first spaces are replaced |
4062 Limitation: only the very first spaces are replaced |
4063 (i.e. if the receiver contains newLine characters, |
4063 (i.e. if the receiver contains newLine characters, |
4064 no tabs are inserted after those lineBreaks)" |
4064 no tabs are inserted after those lineBreaks)" |
4065 |
4065 |
4066 |idx "{ SmallInteger }" |
4066 |idx "{ SmallInteger }" |
4067 nTabs "{ SmallInteger }" |
4067 nTabs "{ SmallInteger }" |
4068 newString| |
4068 newString| |
4069 |
4069 |
4070 idx := self findFirst:[:c | (c ~~ Character space)]. |
4070 idx := self findFirst:[:c | (c ~~ Character space)]. |
4071 nTabs := (idx-1) // 8. |
4071 nTabs := (idx-1) // 8. |
4072 nTabs <= 0 ifTrue:[^ self]. |
4072 nTabs <= 0 ifTrue:[^ self]. |
4076 newString atAll:(1 to:nTabs) put:(Character tab). |
4076 newString atAll:(1 to:nTabs) put:(Character tab). |
4077 newString replaceFrom:(nTabs + 1) with:self startingAt:(nTabs * 8 + 1). |
4077 newString replaceFrom:(nTabs + 1) with:self startingAt:(nTabs * 8 + 1). |
4078 ^ newString |
4078 ^ newString |
4079 |
4079 |
4080 " |
4080 " |
4081 '12345678901234567890' withTabs |
4081 '12345678901234567890' withTabs |
4082 ' 8901234567890' withTabs |
4082 ' 8901234567890' withTabs |
4083 ' 901234567890' withTabs |
4083 ' 901234567890' withTabs |
4084 ' 67890' withTabs |
4084 ' 67890' withTabs |
4085 ' 7890' withTabs |
4085 ' 7890' withTabs |
4086 ' 890' withTabs |
4086 ' 890' withTabs |
4087 " |
4087 " |
4088 ! |
4088 ! |
4089 |
4089 |
4090 withTabsExpanded |
4090 withTabsExpanded |
4091 "return a string consisting of the receivers characters, |
4091 "return a string consisting of the receivers characters, |
4092 where all tabulator characters are expanded into spaces (assuming 8-col tabs). |
4092 where all tabulator characters are expanded into spaces (assuming 8-col tabs). |
4093 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4093 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4094 otherwise a new string is returned. |
4094 otherwise a new string is returned. |
4095 This does handle multiline strings." |
4095 This does handle multiline strings." |
4096 |
4096 |
4097 ^ self withTabsExpanded:8 |
4097 ^ self withTabsExpanded:8 |
4098 |
4098 |
4099 " |
4099 " |
4100 ('1' , Character tab asString , 'x') withTabsExpanded |
4100 ('1' , Character tab asString , 'x') withTabsExpanded |
4101 ('12345' , Character tab asString , 'x') withTabsExpanded |
4101 ('12345' , Character tab asString , 'x') withTabsExpanded |
4102 ('123456' , Character tab asString , 'x') withTabsExpanded |
4102 ('123456' , Character tab asString , 'x') withTabsExpanded |
4103 ('1234567' , Character tab asString , 'x') withTabsExpanded |
4103 ('1234567' , Character tab asString , 'x') withTabsExpanded |
4104 ('12345678' , Character tab asString , 'x') withTabsExpanded |
4104 ('12345678' , Character tab asString , 'x') withTabsExpanded |
4105 ('123456789' , Character tab asString , 'x') withTabsExpanded |
4105 ('123456789' , Character tab asString , 'x') withTabsExpanded |
4106 |
4106 |
4107 (String with:Character tab |
4107 (String with:Character tab |
4108 with:Character tab |
4108 with:Character tab |
4109 with:$1) withTabsExpanded |
4109 with:$1) withTabsExpanded |
4110 |
4110 |
4111 (String with:Character tab |
4111 (String with:Character tab |
4112 with:$1 |
4112 with:$1 |
4113 with:Character tab |
4113 with:Character tab |
4114 with:$2) withTabsExpanded |
4114 with:$2) withTabsExpanded |
4115 |
4115 |
4116 (String with:Character tab |
4116 (String with:Character tab |
4117 with:$1 |
4117 with:$1 |
4118 with:Character cr |
4118 with:Character cr |
4119 with:Character tab |
4119 with:Character tab |
4120 with:$2) withTabsExpanded |
4120 with:$2) withTabsExpanded |
4121 " |
4121 " |
4122 |
4122 |
4123 "Modified: 12.5.1996 / 13:05:10 / cg" |
4123 "Modified: 12.5.1996 / 13:05:10 / cg" |
4124 ! |
4124 ! |
4125 |
4125 |
4126 withTabsExpanded:numSpaces |
4126 withTabsExpanded:numSpaces |
4127 "return a string consisting of the receivers characters, |
4127 "return a string consisting of the receivers characters, |
4128 where all tabulator characters are expanded into spaces (assuming numSpaces-col tabs). |
4128 where all tabulator characters are expanded into spaces (assuming numSpaces-col tabs). |
4129 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4129 Notice: if the receiver does not contain any tabs, it is returned unchanged; |
4130 otherwise a new string is returned. |
4130 otherwise a new string is returned. |
4131 This does handle multiline strings." |
4131 This does handle multiline strings." |
4132 |
4132 |
4133 |col "{ SmallInteger }" |
4133 |col "{ SmallInteger }" |
4134 str ch |
4134 str ch |
4135 dstIdx "{ SmallInteger }" |
4135 dstIdx "{ SmallInteger }" |
4136 newSz "{ SmallInteger }" |
4136 newSz "{ SmallInteger }" |
4137 sz "{ SmallInteger }" |
4137 sz "{ SmallInteger }" |
4138 hasEmphasis e| |
4138 hasEmphasis e| |
4144 "/ count the new size first, instead of |
4144 "/ count the new size first, instead of |
4145 "/ multiple resizing (better for large strings) |
4145 "/ multiple resizing (better for large strings) |
4146 |
4146 |
4147 col := 1. newSz := 0. |
4147 col := 1. newSz := 0. |
4148 1 to:sz do:[:srcIdx | |
4148 1 to:sz do:[:srcIdx | |
4149 ch := self at:srcIdx. |
4149 ch := self at:srcIdx. |
4150 ch == Character tab ifFalse:[ |
4150 ch == Character tab ifFalse:[ |
4151 col := col + 1. |
4151 col := col + 1. |
4152 newSz := newSz + 1. |
4152 newSz := newSz + 1. |
4153 ch == Character cr ifTrue:[ |
4153 ch == Character cr ifTrue:[ |
4154 col := 1 |
4154 col := 1 |
4155 ]. |
4155 ]. |
4156 ] ifTrue:[ |
4156 ] ifTrue:[ |
4157 (col \\ numSpaces) to:numSpaces do:[:ii | |
4157 (col \\ numSpaces) to:numSpaces do:[:ii | |
4158 newSz := newSz + 1. |
4158 newSz := newSz + 1. |
4159 col := col + 1 |
4159 col := col + 1 |
4160 ]. |
4160 ]. |
4161 ] |
4161 ] |
4162 ]. |
4162 ]. |
4163 |
4163 |
4164 str := self species new:newSz. |
4164 str := self species new:newSz. |
4165 |
4165 |
4166 hasEmphasis := self hasChangeOfEmphasis. |
4166 hasEmphasis := self hasChangeOfEmphasis. |
4167 |
4167 |
4168 col := 1. dstIdx := 1. |
4168 col := 1. dstIdx := 1. |
4169 1 to:sz do:[:srcIdx | |
4169 1 to:sz do:[:srcIdx | |
4170 ch := self at:srcIdx. |
4170 ch := self at:srcIdx. |
4171 |
4171 |
4172 ch == Character tab ifFalse:[ |
4172 ch == Character tab ifFalse:[ |
4173 col := col + 1. |
4173 col := col + 1. |
4174 ch == Character cr ifTrue:[ |
4174 ch == Character cr ifTrue:[ |
4175 col := 1 |
4175 col := 1 |
4176 ]. |
4176 ]. |
4177 hasEmphasis ifTrue:[ |
4177 hasEmphasis ifTrue:[ |
4178 e := self emphasisAt:srcIdx. |
4178 e := self emphasisAt:srcIdx. |
4179 str emphasisAt:dstIdx put:e |
4179 str emphasisAt:dstIdx put:e |
4180 ]. |
4180 ]. |
4181 str at:dstIdx put:ch. |
4181 str at:dstIdx put:ch. |
4182 dstIdx := dstIdx + 1 |
4182 dstIdx := dstIdx + 1 |
4183 ] ifTrue:[ |
4183 ] ifTrue:[ |
4184 (col \\ numSpaces) to:numSpaces do:[:ii | |
4184 (col \\ numSpaces) to:numSpaces do:[:ii | |
4185 str at:dstIdx put:Character space. |
4185 str at:dstIdx put:Character space. |
4186 dstIdx := dstIdx + 1. |
4186 dstIdx := dstIdx + 1. |
4187 col := col + 1 |
4187 col := col + 1 |
4188 ]. |
4188 ]. |
4189 ] |
4189 ] |
4190 ]. |
4190 ]. |
4191 ^ str |
4191 ^ str |
4192 |
4192 |
4193 " |
4193 " |
4194 ('1' , Character tab asString , 'x') withTabsExpanded |
4194 ('1' , Character tab asString , 'x') withTabsExpanded |
4195 ('1' , Character tab asString , 'x') withTabsExpanded:4 |
4195 ('1' , Character tab asString , 'x') withTabsExpanded:4 |
4196 ('12345' , Character tab asString , 'x') withTabsExpanded |
4196 ('12345' , Character tab asString , 'x') withTabsExpanded |
4197 ('123456' , Character tab asString , 'x') withTabsExpanded |
4197 ('123456' , Character tab asString , 'x') withTabsExpanded |
4198 ('1234567' , Character tab asString , 'x') withTabsExpanded |
4198 ('1234567' , Character tab asString , 'x') withTabsExpanded |
4199 ('12345678' , Character tab asString , 'x') withTabsExpanded |
4199 ('12345678' , Character tab asString , 'x') withTabsExpanded |
4200 ('123456789' , Character tab asString , 'x') withTabsExpanded |
4200 ('123456789' , Character tab asString , 'x') withTabsExpanded |
4201 |
4201 |
4202 (String with:Character tab |
4202 (String with:Character tab |
4203 with:Character tab |
4203 with:Character tab |
4204 with:$1) withTabsExpanded |
4204 with:$1) withTabsExpanded |
4205 |
4205 |
4206 (String with:Character tab |
4206 (String with:Character tab |
4207 with:$1 |
4207 with:$1 |
4208 with:Character tab |
4208 with:Character tab |
4209 with:$2) withTabsExpanded |
4209 with:$2) withTabsExpanded |
4210 |
4210 |
4211 (String with:Character tab |
4211 (String with:Character tab |
4212 with:$1 |
4212 with:$1 |
4213 with:Character cr |
4213 with:Character cr |
4214 with:Character tab |
4214 with:Character tab |
4215 with:$2) withTabsExpanded |
4215 with:$2) withTabsExpanded |
4216 " |
4216 " |
4217 |
4217 |
4218 "Modified: 12.5.1996 / 13:05:10 / cg" |
4218 "Modified: 12.5.1996 / 13:05:10 / cg" |
4219 ! |
4219 ! |
4220 |
4220 |
4247 ^ self copyFrom:index |
4247 ^ self copyFrom:index |
4248 ]. |
4248 ]. |
4249 ^ '' |
4249 ^ '' |
4250 |
4250 |
4251 " |
4251 " |
4252 ' foo ' withoutLeadingSeparators |
4252 ' foo ' withoutLeadingSeparators |
4253 'foo ' withoutLeadingSeparators |
4253 'foo ' withoutLeadingSeparators |
4254 ' foo' withoutLeadingSeparators |
4254 ' foo' withoutLeadingSeparators |
4255 ' ' withoutLeadingSeparators |
4255 ' ' withoutLeadingSeparators |
4256 'foo' withoutLeadingSeparators |
4256 'foo' withoutLeadingSeparators |
4257 (' ' , Character tab asString , ' foo ') withoutLeadingSeparators inspect |
4257 (' ' , Character tab asString , ' foo ') withoutLeadingSeparators inspect |
4258 " |
4258 " |
4259 ! |
4259 ! |
4260 |
4260 |
4261 withoutMatchEscapes |
4261 withoutMatchEscapes |
4262 "return a copy of the receiver with all $\ removed or |
4262 "return a copy of the receiver with all $\ removed or |
4267 escape := self class matchEscapeCharacter. |
4267 escape := self class matchEscapeCharacter. |
4268 |
4268 |
4269 in := self readStream. |
4269 in := self readStream. |
4270 out := self species writeStream. |
4270 out := self species writeStream. |
4271 [in atEnd] whileFalse:[ |
4271 [in atEnd] whileFalse:[ |
4272 c := in next. |
4272 c := in next. |
4273 c == escape ifTrue:[ |
4273 c == escape ifTrue:[ |
4274 in atEnd ifFalse:[ |
4274 in atEnd ifFalse:[ |
4275 c := in next. |
4275 c := in next. |
4276 ] |
4276 ] |
4277 ]. |
4277 ]. |
4278 out nextPut:c. |
4278 out nextPut:c. |
4279 ]. |
4279 ]. |
4280 ^ out contents. |
4280 ^ out contents. |
4281 |
4281 |
4282 " |
4282 " |
4283 '*foo' withoutMatchEscapes |
4283 '*foo' withoutMatchEscapes |
4284 '\*foo' withoutMatchEscapes |
4284 '\*foo' withoutMatchEscapes |
4285 '*foo' withoutMatchEscapes |
4285 '*foo' withoutMatchEscapes |
4286 '\\*foo' withoutMatchEscapes |
4286 '\\*foo' withoutMatchEscapes |
4287 'foo*' withoutMatchEscapes |
4287 'foo*' withoutMatchEscapes |
4288 'foo\*' withoutMatchEscapes |
4288 'foo\*' withoutMatchEscapes |
4289 'foo\' withoutMatchEscapes |
4289 'foo\' withoutMatchEscapes |
4290 'f\*o\*o' withoutMatchEscapes |
4290 'f\*o\*o' withoutMatchEscapes |
4291 " |
4291 " |
4292 |
4292 |
4293 "Modified: 30.6.1997 / 13:40:23 / cg" |
4293 "Modified: 30.6.1997 / 13:40:23 / cg" |
4294 ! |
4294 ! |
4295 |
4295 |
4296 withoutPrefix:aString |
4296 withoutPrefix:aString |
4297 "if the receiver startsWith aPrefix, return a copy without it. |
4297 "if the receiver startsWith aPrefix, return a copy without it. |
4298 Otherwise return the receiver" |
4298 Otherwise return the receiver" |
4299 |
4299 |
4300 (self startsWith:aString) ifTrue:[ |
4300 (self startsWith:aString) ifTrue:[ |
4301 ^ self copyFrom:aString size + 1 |
4301 ^ self copyFrom:aString size + 1 |
4302 ]. |
4302 ]. |
4303 ^ self |
4303 ^ self |
4304 |
4304 |
4305 " |
4305 " |
4306 'helloworld' withoutPrefix:'hello' |
4306 'helloworld' withoutPrefix:'hello' |
4313 (but whiteSpace in-between is preserved) |
4313 (but whiteSpace in-between is preserved) |
4314 Whitespace is space, tab, newline, formfeed. |
4314 Whitespace is space, tab, newline, formfeed. |
4315 Use withoutSpaces, if you want to remove spaces only." |
4315 Use withoutSpaces, if you want to remove spaces only." |
4316 |
4316 |
4317 |startIndex "{ Class: SmallInteger }" |
4317 |startIndex "{ Class: SmallInteger }" |
4318 endIndex "{ Class: SmallInteger }" |
4318 endIndex "{ Class: SmallInteger }" |
4319 sz| |
4319 sz| |
4320 |
4320 |
4321 sz := self size. |
4321 sz := self size. |
4322 startIndex := 1. |
4322 startIndex := 1. |
4323 endIndex := sz. |
4323 endIndex := sz. |
4324 |
4324 |
4325 [(startIndex < endIndex) and:[(self at:startIndex) isSeparator]] whileTrue:[ |
4325 [(startIndex < endIndex) and:[(self at:startIndex) isSeparator]] whileTrue:[ |
4326 startIndex := startIndex + 1 |
4326 startIndex := startIndex + 1 |
4327 ]. |
4327 ]. |
4328 [(endIndex > 1) and:[(self at:endIndex) isSeparator]] whileTrue:[ |
4328 [(endIndex > 1) and:[(self at:endIndex) isSeparator]] whileTrue:[ |
4329 endIndex := endIndex - 1 |
4329 endIndex := endIndex - 1 |
4330 ]. |
4330 ]. |
4331 startIndex > endIndex ifTrue:[ |
4331 startIndex > endIndex ifTrue:[ |
4332 ^ '' |
4332 ^ '' |
4333 ]. |
4333 ]. |
4334 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
4334 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
4335 ^ self |
4335 ^ self |
4336 ]. |
4336 ]. |
4337 ^ self copyFrom:startIndex to:endIndex |
4337 ^ self copyFrom:startIndex to:endIndex |
4338 |
4338 |
4339 " |
4339 " |
4340 ' foo ' withoutSeparators |
4340 ' foo ' withoutSeparators |
4341 ' foo' withoutSeparators |
4341 ' foo' withoutSeparators |
4342 'foo ' withoutSeparators |
4342 'foo ' withoutSeparators |
4343 ' ' withoutSeparators |
4343 ' ' withoutSeparators |
4344 (' foo' , Character tab asString , ' ') withoutSeparators inspect |
4344 (' foo' , Character tab asString , ' ') withoutSeparators inspect |
4345 " |
4345 " |
4346 ! |
4346 ! |
4347 |
4347 |
4348 withoutSpaces |
4348 withoutSpaces |
4349 "return a copy of myself without leading and trailing spaces. |
4349 "return a copy of myself without leading and trailing spaces. |
4350 (but spaces in-between are preserved) |
4350 (but spaces in-between are preserved) |
4351 Notice: this does NOT remove tabs, newline or any other whitespace. |
4351 Notice: this does NOT remove tabs, newline or any other whitespace. |
4352 Use withoutSeparators for this." |
4352 Use withoutSeparators for this." |
4353 |
4353 |
4354 |startIndex "{ Class: SmallInteger }" |
4354 |startIndex "{ Class: SmallInteger }" |
4355 endIndex "{ Class: SmallInteger }" |
4355 endIndex "{ Class: SmallInteger }" |
4356 sz| |
4356 sz| |
4357 |
4357 |
4358 sz := self size. |
4358 sz := self size. |
4359 startIndex := 1. |
4359 startIndex := 1. |
4360 endIndex := sz. |
4360 endIndex := sz. |
4361 |
4361 |
4362 [(startIndex < endIndex) and:[(self at:startIndex) == Character space]] whileTrue:[ |
4362 [(startIndex < endIndex) and:[(self at:startIndex) == Character space]] whileTrue:[ |
4363 startIndex := startIndex + 1 |
4363 startIndex := startIndex + 1 |
4364 ]. |
4364 ]. |
4365 [(endIndex > 1) and:[(self at:endIndex) == Character space]] whileTrue:[ |
4365 [(endIndex > 1) and:[(self at:endIndex) == Character space]] whileTrue:[ |
4366 endIndex := endIndex - 1 |
4366 endIndex := endIndex - 1 |
4367 ]. |
4367 ]. |
4368 startIndex > endIndex ifTrue:[ |
4368 startIndex > endIndex ifTrue:[ |
4369 ^ '' |
4369 ^ '' |
4370 ]. |
4370 ]. |
4371 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
4371 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
4372 ^ self |
4372 ^ self |
4373 ]. |
4373 ]. |
4374 ^ self copyFrom:startIndex to:endIndex |
4374 ^ self copyFrom:startIndex to:endIndex |
4375 |
4375 |
4376 " |
4376 " |
4377 ' foo ' withoutSpaces |
4377 ' foo ' withoutSpaces |
4378 'foo ' withoutSpaces |
4378 'foo ' withoutSpaces |
4379 ' foo' withoutSpaces |
4379 ' foo' withoutSpaces |
4380 ' ' withoutSpaces |
4380 ' ' withoutSpaces |
4381 'a b' withoutSpaces |
4381 'a b' withoutSpaces |
4382 (' foo' , Character tab asString , ' ') withoutSpaces inspect |
4382 (' foo' , Character tab asString , ' ') withoutSpaces inspect |
4383 " |
4383 " |
4384 ! |
4384 ! |
4385 |
4385 |
4386 withoutTrailingSeparators |
4386 withoutTrailingSeparators |
4387 "return a copy of myself without trailing separators. |
4387 "return a copy of myself without trailing separators. |
4398 index := index - 1 |
4398 index := index - 1 |
4399 ]. |
4399 ]. |
4400 ^ '' |
4400 ^ '' |
4401 |
4401 |
4402 " |
4402 " |
4403 ' foo ' withoutTrailingSeparators |
4403 ' foo ' withoutTrailingSeparators |
4404 'foo ' withoutTrailingSeparators |
4404 'foo ' withoutTrailingSeparators |
4405 ' foo' withoutTrailingSeparators |
4405 ' foo' withoutTrailingSeparators |
4406 ' ' withoutTrailingSeparators |
4406 ' ' withoutTrailingSeparators |
4407 'foo' withoutTrailingSeparators |
4407 'foo' withoutTrailingSeparators |
4408 (' ' , Character tab asString , ' foo ') withoutTrailingSeparators inspect |
4408 (' ' , Character tab asString , ' foo ') withoutTrailingSeparators inspect |
4409 (' foo' , Character tab asString) withoutTrailingSeparators inspect |
4409 (' foo' , Character tab asString) withoutTrailingSeparators inspect |
4410 " |
4410 " |
4411 ! ! |
4411 ! ! |
4412 |
4412 |
4413 !CharacterArray methodsFor:'substring searching'! |
4413 !CharacterArray methodsFor:'substring searching'! |
4414 |
4414 |
4417 if not found, return 0." |
4417 if not found, return 0." |
4418 |
4418 |
4419 ^ self indexOfSubCollection:subString startingAt:1 ifAbsent:0 |
4419 ^ self indexOfSubCollection:subString startingAt:1 ifAbsent:0 |
4420 |
4420 |
4421 " |
4421 " |
4422 'hello world' findString:'llo' |
4422 'hello world' findString:'llo' |
4423 'hello world' findString:'ole' |
4423 'hello world' findString:'ole' |
4424 " |
4424 " |
4425 ! |
4425 ! |
4426 |
4426 |
4427 findString:subString ifAbsent:exceptionBlock |
4427 findString:subString ifAbsent:exceptionBlock |
4428 "find a substring. If found, return the index; |
4428 "find a substring. If found, return the index; |
4436 if not found, return 0." |
4436 if not found, return 0." |
4437 |
4437 |
4438 ^ self indexOfSubCollection:subString startingAt:index ifAbsent:0 |
4438 ^ self indexOfSubCollection:subString startingAt:index ifAbsent:0 |
4439 |
4439 |
4440 " |
4440 " |
4441 'hello yello' findString:'llo' startingAt:1 |
4441 'hello yello' findString:'llo' startingAt:1 |
4442 'hello yello' findString:'llo' startingAt:5 |
4442 'hello yello' findString:'llo' startingAt:5 |
4443 'hello yello' findString:'llo' startingAt:15 |
4443 'hello yello' findString:'llo' startingAt:15 |
4444 " |
4444 " |
4445 ! |
4445 ! |
4446 |
4446 |
4447 findString:subString startingAt:index ifAbsent:exceptionBlock |
4447 findString:subString startingAt:index ifAbsent:exceptionBlock |
4448 "find a substring, starting at index. if found, return the index; |
4448 "find a substring, starting at index. if found, return the index; |
4455 "return true, if a substring is contained in the receiver" |
4455 "return true, if a substring is contained in the receiver" |
4456 |
4456 |
4457 ^ (self indexOfSubCollection:aString startingAt:1 ifAbsent:0) ~~ 0 |
4457 ^ (self indexOfSubCollection:aString startingAt:1 ifAbsent:0) ~~ 0 |
4458 |
4458 |
4459 " |
4459 " |
4460 'hello world' includesString:'hel' |
4460 'hello world' includesString:'hel' |
4461 'hello world' includesString:'rld' |
4461 'hello world' includesString:'rld' |
4462 'hello world' includesString:'llo' |
4462 'hello world' includesString:'llo' |
4463 'hello world' includesString:'LLO' |
4463 'hello world' includesString:'LLO' |
4464 " |
4464 " |
4465 ! |
4465 ! |
4466 |
4466 |
4467 indexOfSubCollection:subString startingAt:index ifAbsent:exceptionBlock |
4467 indexOfSubCollection:subString startingAt:index ifAbsent:exceptionBlock |
4468 "find a substring, starting at index. if found, return the index; |
4468 "find a substring, starting at index. if found, return the index; |
4475 mySize "{ Class: SmallInteger }" |
4475 mySize "{ Class: SmallInteger }" |
4476 runIdx "{ Class: SmallInteger }" | |
4476 runIdx "{ Class: SmallInteger }" | |
4477 |
4477 |
4478 subSize := subString size. |
4478 subSize := subString size. |
4479 subSize == 0 ifTrue:[ "empty string matches" |
4479 subSize == 0 ifTrue:[ "empty string matches" |
4480 subString isString ifFalse:[ |
4480 subString isString ifFalse:[ |
4481 self error:'non string argument' mayProceed:true. |
4481 self error:'non string argument' mayProceed:true. |
4482 ]. |
4482 ]. |
4483 ^ index |
4483 ^ index |
4484 ]. |
4484 ]. |
4485 mySize := self size. |
4485 mySize := self size. |
4486 firstChar := subString at:1. |
4486 firstChar := subString at:1. |
4487 startIndex := self indexOf:firstChar startingAt:index. |
4487 startIndex := self indexOf:firstChar startingAt:index. |
4488 [startIndex == 0] whileFalse:[ |
4488 [startIndex == 0] whileFalse:[ |
4489 runIdx := startIndex. |
4489 runIdx := startIndex. |
4490 found := true. |
4490 found := true. |
4491 1 to:subSize do:[:i | |
4491 1 to:subSize do:[:i | |
4492 runIdx > mySize ifTrue:[ |
4492 runIdx > mySize ifTrue:[ |
4493 found := false |
4493 found := false |
4494 ] ifFalse:[ |
4494 ] ifFalse:[ |
4495 (subString at:i) ~= (self at:runIdx) ifTrue:[ |
4495 (subString at:i) ~= (self at:runIdx) ifTrue:[ |
4496 found := false |
4496 found := false |
4497 ] |
4497 ] |
4498 ]. |
4498 ]. |
4499 runIdx := runIdx + 1 |
4499 runIdx := runIdx + 1 |
4500 ]. |
4500 ]. |
4501 found ifTrue:[ |
4501 found ifTrue:[ |
4502 ^ startIndex |
4502 ^ startIndex |
4503 ]. |
4503 ]. |
4504 startIndex := self indexOf:firstChar startingAt:(startIndex + 1) |
4504 startIndex := self indexOf:firstChar startingAt:(startIndex + 1) |
4505 ]. |
4505 ]. |
4506 ^ exceptionBlock value |
4506 ^ exceptionBlock value |
4507 |
4507 |
4508 "Modified: 23.2.1996 / 15:35:15 / cg" |
4508 "Modified: 23.2.1996 / 15:35:15 / cg" |
4509 ! |
4509 ! |
4510 |
4510 |
4511 restAfter:keyword withoutSeparators:strip |
4511 restAfter:keyword withoutSeparators:strip |
4512 "compare the left of the receiver with keyword, |
4512 "compare the left of the receiver with keyword, |
4513 if it matches return the right. |
4513 if it matches return the right. |
4514 Finally, if strip is true, remove whiteSpace. |
4514 Finally, if strip is true, remove whiteSpace. |
4515 This method is used to match and extract lines of the form: |
4515 This method is used to match and extract lines of the form: |
4516 something: rest |
4516 something: rest |
4517 where we are interested in rest, but only if the receiver string |
4517 where we are interested in rest, but only if the receiver string |
4518 begins with something. |
4518 begins with something. |
4519 |
4519 |
4520 You may wonder why such a specialized method exists here |
4520 You may wonder why such a specialized method exists here |
4521 - this is so common when processing mailboxes, |
4521 - this is so common when processing mailboxes, |
4522 rcs files, nntp/pop3 responses, that is was considered worth |
4522 rcs files, nntp/pop3 responses, that is was considered worth |
4523 a special method here to avoid having the code below a hundred |
4523 a special method here to avoid having the code below a hundred |
4533 ^ rest |
4533 ^ rest |
4534 ]. |
4534 ]. |
4535 ^ nil |
4535 ^ nil |
4536 |
4536 |
4537 " |
4537 " |
4538 'foo: hello world' restAfter:'foo:' withoutSeparators:true |
4538 'foo: hello world' restAfter:'foo:' withoutSeparators:true |
4539 'funny: something' restAfter:'foo:' withoutSeparators:true |
4539 'funny: something' restAfter:'foo:' withoutSeparators:true |
4540 |
4540 |
4541 'foo: hello world ' restAfter:'foo:' withoutSeparators:true |
4541 'foo: hello world ' restAfter:'foo:' withoutSeparators:true |
4542 'foo: hello world ' restAfter:'foo:' withoutSeparators:false |
4542 'foo: hello world ' restAfter:'foo:' withoutSeparators:false |
4543 " |
4543 " |
4544 |
4544 |
4545 "Created: 25.11.1995 / 11:04:18 / cg" |
4545 "Created: 25.11.1995 / 11:04:18 / cg" |
4546 ! ! |
4546 ! ! |
4547 |
4547 |
4556 |
4556 |
4557 sz := aString size. |
4557 sz := aString size. |
4558 idx := startIndex. |
4558 idx := startIndex. |
4559 |
4559 |
4560 1 to:sz do:[:i | |
4560 1 to:sz do:[:i | |
4561 (self at:idx) ~~ (aString at:i) ifTrue:[^ false]. |
4561 (self at:idx) ~~ (aString at:i) ifTrue:[^ false]. |
4562 idx := idx + 1 |
4562 idx := idx + 1 |
4563 ]. |
4563 ]. |
4564 ^ true |
4564 ^ true |
4565 |
4565 |
4566 " |
4566 " |
4567 'hello world' continuesWith:'world' startingAt:6 |
4567 'hello world' continuesWith:'world' startingAt:6 |
4568 'hello world' continuesWith:'world' startingAt:7 |
4568 'hello world' continuesWith:'world' startingAt:7 |
4569 " |
4569 " |
4570 |
4570 |
4571 "Created: 12.5.1996 / 15:46:40 / cg" |
4571 "Created: 12.5.1996 / 15:46:40 / cg" |
4572 "Modified: 26.7.1996 / 19:08:36 / cg" |
4572 "Modified: 26.7.1996 / 19:08:36 / cg" |
4573 ! |
4573 ! |
4607 "return true, if the receiver ends with something, aStringOrCharacter." |
4607 "return true, if the receiver ends with something, aStringOrCharacter." |
4608 |
4608 |
4609 |s| |
4609 |s| |
4610 |
4610 |
4611 (s := self string) ~~ self ifTrue:[ |
4611 (s := self string) ~~ self ifTrue:[ |
4612 ^ s endsWith:aStringOrCharacter |
4612 ^ s endsWith:aStringOrCharacter |
4613 ]. |
4613 ]. |
4614 aStringOrCharacter isCharacter ifTrue:[ |
4614 aStringOrCharacter isCharacter ifTrue:[ |
4615 ^ self last = aStringOrCharacter |
4615 ^ self last = aStringOrCharacter |
4616 ]. |
4616 ]. |
4617 ^ super endsWith:aStringOrCharacter |
4617 ^ super endsWith:aStringOrCharacter |
4618 |
4618 |
4619 " |
4619 " |
4620 'hello world' endsWith:'world' |
4620 'hello world' endsWith:'world' |
4621 'hello world' asText allBold endsWith:'world' |
4621 'hello world' asText allBold endsWith:'world' |
4622 " |
4622 " |
4623 |
4623 |
4624 "Modified: 12.5.1996 / 15:49:18 / cg" |
4624 "Modified: 12.5.1996 / 15:49:18 / cg" |
4625 ! |
4625 ! |
4626 |
4626 |
4637 char isLetterOrDigit ifFalse:[^ false]. |
4637 char isLetterOrDigit ifFalse:[^ false]. |
4638 ]. |
4638 ]. |
4639 ^ true |
4639 ^ true |
4640 |
4640 |
4641 " |
4641 " |
4642 'helloWorld' isAlphaNumeric |
4642 'helloWorld' isAlphaNumeric |
4643 'foo1234' isAlphaNumeric |
4643 'foo1234' isAlphaNumeric |
4644 'f1234' isAlphaNumeric |
4644 'f1234' isAlphaNumeric |
4645 '1234' isAlphaNumeric |
4645 '1234' isAlphaNumeric |
4646 '+' isAlphaNumeric |
4646 '+' isAlphaNumeric |
4647 " |
4647 " |
4648 ! |
4648 ! |
4649 |
4649 |
4650 isBinarySelector |
4650 isBinarySelector |
4651 "treating the receiver as a message selector, return true if its a binary selector" |
4651 "treating the receiver as a message selector, return true if its a binary selector" |
4656 |
4656 |
4657 binopChars := Scanner binarySelectorCharacters. |
4657 binopChars := Scanner binarySelectorCharacters. |
4658 ^ (self conform:[:char | (binopChars includes:char)]) |
4658 ^ (self conform:[:char | (binopChars includes:char)]) |
4659 |
4659 |
4660 " |
4660 " |
4661 'foo:bar:' isBinarySelector |
4661 'foo:bar:' isBinarySelector |
4662 #foo:bar: isBinarySelector |
4662 #foo:bar: isBinarySelector |
4663 'hello' isBinarySelector |
4663 'hello' isBinarySelector |
4664 '+' isBinarySelector |
4664 '+' isBinarySelector |
4665 '|' isBinarySelector |
4665 '|' isBinarySelector |
4666 '?' isBinarySelector |
4666 '?' isBinarySelector |
4667 ':' isBinarySelector |
4667 ':' isBinarySelector |
4668 'a:' isBinarySelector |
4668 'a:' isBinarySelector |
4669 '->' isBinarySelector |
4669 '->' isBinarySelector |
4670 '<->' isBinarySelector |
4670 '<->' isBinarySelector |
4671 '::' isBinarySelector |
4671 '::' isBinarySelector |
4672 " |
4672 " |
4673 |
4673 |
4674 "Modified: 4.1.1997 / 14:16:14 / cg" |
4674 "Modified: 4.1.1997 / 14:16:14 / cg" |
4675 ! |
4675 ! |
4676 |
4676 |
4686 isNumeric |
4686 isNumeric |
4687 "return true, if the receiver is some numeric word; |
4687 "return true, if the receiver is some numeric word; |
4688 i.e. consists only of digits." |
4688 i.e. consists only of digits." |
4689 |
4689 |
4690 self size == 0 ifTrue:[ |
4690 self size == 0 ifTrue:[ |
4691 ^ false |
4691 ^ false |
4692 ]. |
4692 ]. |
4693 self do:[:char | |
4693 self do:[:char | |
4694 char isDigit ifFalse:[^ false]. |
4694 char isDigit ifFalse:[^ false]. |
4695 ]. |
4695 ]. |
4696 ^ true |
4696 ^ true |
4697 |
4697 |
4698 " |
4698 " |
4699 'helloWorld' isNumeric |
4699 'helloWorld' isNumeric |
4700 'foo1234' isNumeric |
4700 'foo1234' isNumeric |
4701 'f1234' isNumeric |
4701 'f1234' isNumeric |
4702 '1234' isNumeric |
4702 '1234' isNumeric |
4703 '+' isNumeric |
4703 '+' isNumeric |
4704 " |
4704 " |
4705 ! |
4705 ! |
4706 |
4706 |
4707 levenshteinTo:aString |
4707 levenshteinTo:aString |
4708 "return the levenshtein distance to the argument, aString; |
4708 "return the levenshtein distance to the argument, aString; |
4722 " |
4722 " |
4723 |
4723 |
4724 ^ self levenshteinTo:aString s:4 k:2 c:1 i:2 d:6 |
4724 ^ self levenshteinTo:aString s:4 k:2 c:1 i:2 d:6 |
4725 |
4725 |
4726 " |
4726 " |
4727 'computer' levenshteinTo:'computer' |
4727 'computer' levenshteinTo:'computer' |
4728 'cOmputer' levenshteinTo:'computer' |
4728 'cOmputer' levenshteinTo:'computer' |
4729 'cOmpuTer' levenshteinTo:'computer' |
4729 'cOmpuTer' levenshteinTo:'computer' |
4730 'cimputer' levenshteinTo:'computer' |
4730 'cimputer' levenshteinTo:'computer' |
4731 'cumputer' levenshteinTo:'computer' |
4731 'cumputer' levenshteinTo:'computer' |
4732 |
4732 |
4733 'cmputer' levenshteinTo:'computer' |
4733 'cmputer' levenshteinTo:'computer' |
4734 'coomputer' levenshteinTo:'computer' |
4734 'coomputer' levenshteinTo:'computer' |
4735 |
4735 |
4736 'ocmprt' levenshteinTo:'computer' |
4736 'ocmprt' levenshteinTo:'computer' |
4737 'computer' levenshteinTo:'computer' |
4737 'computer' levenshteinTo:'computer' |
4738 'ocmputer' levenshteinTo:'computer' |
4738 'ocmputer' levenshteinTo:'computer' |
4739 'cmputer' levenshteinTo:'computer' |
4739 'cmputer' levenshteinTo:'computer' |
4740 'computer' levenshteinTo:'cmputer' |
4740 'computer' levenshteinTo:'cmputer' |
4741 'Computer' levenshteinTo:'computer' |
4741 'Computer' levenshteinTo:'computer' |
4742 " |
4742 " |
4743 ! |
4743 ! |
4744 |
4744 |
4745 levenshteinTo:aString s:substWeight k:kbdTypoWeight c:caseWeight i:insrtWeight d:deleteWeight |
4745 levenshteinTo:aString s:substWeight k:kbdTypoWeight c:caseWeight i:insrtWeight d:deleteWeight |
4746 "parametrized levenshtein. |
4746 "parametrized levenshtein. |
4747 return the levenshtein distance to the argument, aString; |
4747 return the levenshtein distance to the argument, aString; |
4748 this value corrensponds to the number of replacements that have to be |
4748 this value corrensponds to the number of replacements that have to be |
4749 made to get aString from the receiver. |
4749 made to get aString from the receiver. |
4750 The arguments are the costs for |
4750 The arguments are the costs for |
4751 s:substitution, |
4751 s:substitution, |
4752 k:keyboard type (substitution), |
4752 k:keyboard type (substitution), |
4753 c:case-change, |
4753 c:case-change, |
4754 i:insertion |
4754 i:insertion |
4755 d:deletion |
4755 d:deletion |
4756 of a character. |
4756 of a character. |
4757 See IEEE transactions on Computers 1976 Pg 172 ff" |
4757 See IEEE transactions on Computers 1976 Pg 172 ff" |
4758 |
4758 |
4759 |d "delta matrix" |
4759 |d "delta matrix" |
4760 len1 "{ Class: SmallInteger }" |
4760 len1 "{ Class: SmallInteger }" |
4761 len2 "{ Class: SmallInteger }" |
4761 len2 "{ Class: SmallInteger }" |
4762 dim "{ Class: SmallInteger }" |
4762 dim "{ Class: SmallInteger }" |
4763 prevRow row col |
4763 prevRow row col |
4764 dimPlus1 "{ Class: SmallInteger }" |
4764 dimPlus1 "{ Class: SmallInteger }" |
4765 min pp c1 c2| |
4765 min pp c1 c2| |
4766 |
4766 |
4767 len1 := self size. |
4767 len1 := self size. |
4768 len2 := aString size. |
4768 len2 := aString size. |
4772 dim := len1 max:len2. |
4772 dim := len1 max:len2. |
4773 dimPlus1 := dim + 1. |
4773 dimPlus1 := dim + 1. |
4774 |
4774 |
4775 d := Array new:dimPlus1. |
4775 d := Array new:dimPlus1. |
4776 1 to:dimPlus1 do:[:i | |
4776 1 to:dimPlus1 do:[:i | |
4777 d at:i put:(Array new:dimPlus1) |
4777 d at:i put:(Array new:dimPlus1) |
4778 ]. |
4778 ]. |
4779 |
4779 |
4780 "init help-matrix" |
4780 "init help-matrix" |
4781 |
4781 |
4782 (d at:1) at:1 put:0. |
4782 (d at:1) at:1 put:0. |
4783 row := d at:1. |
4783 row := d at:1. |
4784 1 to:dim do:[:j | |
4784 1 to:dim do:[:j | |
4785 row at:(j + 1) put:( (row at:j) + insrtWeight ) |
4785 row at:(j + 1) put:( (row at:j) + insrtWeight ) |
4786 ]. |
4786 ]. |
4787 |
4787 |
4788 1 to:dim do:[:i | |
4788 1 to:dim do:[:i | |
4789 (d at:(i + 1)) at:1 put:( ((d at:i) at:1) + deleteWeight ) |
4789 (d at:(i + 1)) at:1 put:( ((d at:i) at:1) + deleteWeight ) |
4790 ]. |
4790 ]. |
4791 |
4791 |
4792 1 to:len1 do:[:i | |
4792 1 to:len1 do:[:i | |
4793 c1 := self at:i. |
4793 c1 := self at:i. |
4794 1 to:len2 do:[:j | |
4794 1 to:len2 do:[:j | |
4795 c2 := aString at:j. |
4795 c2 := aString at:j. |
4796 (c1 == c2) ifTrue:[ |
4796 (c1 == c2) ifTrue:[ |
4797 pp := 0 |
4797 pp := 0 |
4798 ] ifFalse:[ |
4798 ] ifFalse:[ |
4799 (c1 asLowercase == c2 asLowercase) ifTrue:[ |
4799 (c1 asLowercase == c2 asLowercase) ifTrue:[ |
4800 pp := caseWeight |
4800 pp := caseWeight |
4801 ] ifFalse:[ |
4801 ] ifFalse:[ |
4802 pp := substWeight. |
4802 pp := substWeight. |
4803 substWeight ~~ kbdTypoWeight ifTrue:[ |
4803 substWeight ~~ kbdTypoWeight ifTrue:[ |
4804 (DoWhatIMeanSupport isKey:c1 asLowercase nextTo:c2 asLowercase) ifTrue:[ |
4804 (DoWhatIMeanSupport isKey:c1 asLowercase nextTo:c2 asLowercase) ifTrue:[ |
4805 pp := kbdTypoWeight. |
4805 pp := kbdTypoWeight. |
4806 ]. |
4806 ]. |
4807 ]. |
4807 ]. |
4808 ] |
4808 ] |
4809 ]. |
4809 ]. |
4810 prevRow := d at:i. |
4810 prevRow := d at:i. |
4811 row := d at:(i + 1). |
4811 row := d at:(i + 1). |
4812 col := j + 1. |
4812 col := j + 1. |
4813 min := (prevRow at:j) + pp. |
4813 min := (prevRow at:j) + pp. |
4814 min := min min:( (row at:j) + insrtWeight). |
4814 min := min min:( (row at:j) + insrtWeight). |
4815 min := min min:( (prevRow at:col) + deleteWeight). |
4815 min := min min:( (prevRow at:col) + deleteWeight). |
4816 row at:col put: min |
4816 row at:col put: min |
4817 ] |
4817 ] |
4818 ]. |
4818 ]. |
4819 |
4819 |
4820 ^ (d at:(len1 + 1)) at:(len2 + 1) |
4820 ^ (d at:(len1 + 1)) at:(len2 + 1) |
4821 ! |
4821 ! |
4822 |
4822 |
4824 "treating the receiver as a message selector, return how many arguments would it take" |
4824 "treating the receiver as a message selector, return how many arguments would it take" |
4825 |
4825 |
4826 |binopChars firstChar| |
4826 |binopChars firstChar| |
4827 |
4827 |
4828 (self size > 2) ifFalse:[ |
4828 (self size > 2) ifFalse:[ |
4829 binopChars := Scanner binarySelectorCharacters. |
4829 binopChars := Scanner binarySelectorCharacters. |
4830 firstChar := self at:1. |
4830 firstChar := self at:1. |
4831 |
4831 |
4832 (self size == 1) ifTrue:[ |
4832 (self size == 1) ifTrue:[ |
4833 (binopChars includes:firstChar) ifFalse:[^ 0]. |
4833 (binopChars includes:firstChar) ifFalse:[^ 0]. |
4834 ^ 1 |
4834 ^ 1 |
4835 ]. |
4835 ]. |
4836 (binopChars includes:firstChar) ifTrue:[ |
4836 (binopChars includes:firstChar) ifTrue:[ |
4837 (binopChars includes:(self at:2)) ifTrue:[^ 1] |
4837 (binopChars includes:(self at:2)) ifTrue:[^ 1] |
4838 ] |
4838 ] |
4839 ]. |
4839 ]. |
4840 ^ self occurrencesOf:$: |
4840 ^ self occurrencesOf:$: |
4841 |
4841 |
4842 " |
4842 " |
4843 'foo:bar:' numArgs |
4843 'foo:bar:' numArgs |
4844 #foo:bar: numArgs |
4844 #foo:bar: numArgs |
4845 'hello' numArgs |
4845 'hello' numArgs |
4846 '+' numArgs |
4846 '+' numArgs |
4847 '|' numArgs |
4847 '|' numArgs |
4848 '?' numArgs |
4848 '?' numArgs |
4849 " |
4849 " |
4850 |
4850 |
4851 "Modified: 4.1.1997 / 14:16:14 / cg" |
4851 "Modified: 4.1.1997 / 14:16:14 / cg" |
4852 ! |
4852 ! |
4853 |
4853 |
4869 coll add:(self copyFrom:idx1 to:idx2). |
4869 coll add:(self copyFrom:idx1 to:idx2). |
4870 idx1 := idx2 + 1 |
4870 idx1 := idx2 + 1 |
4871 ]. |
4871 ]. |
4872 |
4872 |
4873 " |
4873 " |
4874 'foo:bar:' partsIfSelector |
4874 'foo:bar:' partsIfSelector |
4875 #foo:bar: partsIfSelector |
4875 #foo:bar: partsIfSelector |
4876 'hello' partsIfSelector |
4876 'hello' partsIfSelector |
4877 '+' partsIfSelector |
4877 '+' partsIfSelector |
4878 " |
4878 " |
4879 ! |
4879 ! |
4880 |
4880 |
4881 spellAgainst: aString |
4881 spellAgainst: aString |
4882 "return an integer between 0 and 100 indicating how similar |
4882 "return an integer between 0 and 100 indicating how similar |
4883 the argument is to the receiver. No case conversion is done. |
4883 the argument is to the receiver. No case conversion is done. |
4884 This algorithm is much simpler (but also less exact) than the |
4884 This algorithm is much simpler (but also less exact) than the |
4885 levenshtein distance. Experiment which is better for your |
4885 levenshtein distance. Experiment which is better for your |
4886 application." |
4886 application." |
4887 |
4887 |
4901 i1 := i2 := 1. |
4901 i1 := i2 := 1. |
4902 [i1 <= size1 and: [i2 <= size2]] whileTrue:[ |
4902 [i1 <= size1 and: [i2 <= size2]] whileTrue:[ |
4903 next1 := i1 + 1. |
4903 next1 := i1 + 1. |
4904 next2 := i2 + 1. |
4904 next2 := i2 + 1. |
4905 (self at:i1) == (aString at:i2) ifTrue: [ |
4905 (self at:i1) == (aString at:i2) ifTrue: [ |
4906 score := score+1. |
4906 score := score+1. |
4907 i1 := next1. |
4907 i1 := next1. |
4908 i2 := next2 |
4908 i2 := next2 |
4909 ] ifFalse: [ |
4909 ] ifFalse: [ |
4910 (i2 < size2 and: [(self at:i1) == (aString at:next2)]) ifTrue: [ |
4910 (i2 < size2 and: [(self at:i1) == (aString at:next2)]) ifTrue: [ |
4911 i2 := next2 |
4911 i2 := next2 |
4912 ] ifFalse: [ |
4912 ] ifFalse: [ |
4913 (i1 < size1 and: [(self at:next1) == (aString at:i2)]) ifTrue: [ |
4913 (i1 < size1 and: [(self at:next1) == (aString at:i2)]) ifTrue: [ |
4914 i1 := next1 |
4914 i1 := next1 |
4915 ] ifFalse: [ |
4915 ] ifFalse: [ |
4916 i1 := next1. |
4916 i1 := next1. |
4917 i2 := next2 |
4917 i2 := next2 |
4918 ] |
4918 ] |
4919 ] |
4919 ] |
4920 ] |
4920 ] |
4921 ]. |
4921 ]. |
4922 |
4922 |
4923 score == maxLen ifTrue: [^ 100]. |
4923 score == maxLen ifTrue: [^ 100]. |
4924 ^ 100 * score // maxLen |
4924 ^ 100 * score // maxLen |
4925 |
4925 |
4926 " |
4926 " |
4927 'Smalltalk' spellAgainst: 'Smalltlak' |
4927 'Smalltalk' spellAgainst: 'Smalltlak' |
4928 'Smalltalk' spellAgainst: 'smalltlak' |
4928 'Smalltalk' spellAgainst: 'smalltlak' |
4929 'Smalltalk' spellAgainst: 'smalltalk' |
4929 'Smalltalk' spellAgainst: 'smalltalk' |
4930 'Smalltalk' spellAgainst: 'smalltlk' |
4930 'Smalltalk' spellAgainst: 'smalltlk' |
4931 'Smalltalk' spellAgainst: 'Smalltolk' |
4931 'Smalltalk' spellAgainst: 'Smalltolk' |
4932 " |
4932 " |
4933 ! |
4933 ! |
4934 |
4934 |
4935 startsWith:aString |
4935 startsWith:aString |
4936 "return true, if the receiver starts with something, aString. |
4936 "return true, if the receiver starts with something, aString. |
4937 If the argument is empty, true is returned." |
4937 If the argument is empty, true is returned." |
4938 |
4938 |
4939 |s| |
4939 |s| |
4940 |
4940 |
4941 (s := self string) ~~ self ifTrue:[ |
4941 (s := self string) ~~ self ifTrue:[ |
4942 ^ s startsWith:aString |
4942 ^ s startsWith:aString |
4943 ]. |
4943 ]. |
4944 ^ super startsWith:aString |
4944 ^ super startsWith:aString |
4945 |
4945 |
4946 " |
4946 " |
4947 'hello world' startsWith:'hello' |
4947 'hello world' startsWith:'hello' |
4948 'hello world' asText allBold startsWith:'hello' |
4948 'hello world' asText allBold startsWith:'hello' |
4949 'hello world' asText allBold startsWith:'' |
4949 'hello world' asText allBold startsWith:'' |
4950 " |
4950 " |
4951 |
4951 |
4952 "Created: 12.5.1996 / 15:46:40 / cg" |
4952 "Created: 12.5.1996 / 15:46:40 / cg" |
4953 "Modified: 12.5.1996 / 15:49:24 / cg" |
4953 "Modified: 12.5.1996 / 15:49:24 / cg" |
4954 ! ! |
4954 ! ! |
4971 ! ! |
4971 ! ! |
4972 |
4972 |
4973 !CharacterArray class methodsFor:'documentation'! |
4973 !CharacterArray class methodsFor:'documentation'! |
4974 |
4974 |
4975 version |
4975 version |
4976 ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.314 2005-04-20 14:59:45 cg Exp $' |
4976 ^ '$Header: /cvs/stx/stx/libbasic/CharacterArray.st,v 1.315 2005-04-28 17:29:30 cg Exp $' |
4977 ! ! |
4977 ! ! |
4978 |
4978 |
4979 CharacterArray initialize! |
4979 CharacterArray initialize! |