17 category:'Collections-Text' |
17 category:'Collections-Text' |
18 ! |
18 ! |
19 |
19 |
20 String comment:' |
20 String comment:' |
21 COPYRIGHT (c) 1988 by Claus Gittinger |
21 COPYRIGHT (c) 1988 by Claus Gittinger |
22 All Rights Reserved |
22 All Rights Reserved |
23 |
23 |
24 $Header: /cvs/stx/stx/libbasic/String.st,v 1.17 1994-08-05 01:02:46 claus Exp $ |
24 $Header: /cvs/stx/stx/libbasic/String.st,v 1.18 1994-10-10 00:28:43 claus Exp $ |
25 '! |
25 '! |
26 |
26 |
27 !String class methodsFor:'documentation'! |
27 !String class methodsFor:'documentation'! |
28 |
28 |
29 copyright |
29 copyright |
30 " |
30 " |
31 COPYRIGHT (c) 1988 by Claus Gittinger |
31 COPYRIGHT (c) 1988 by Claus Gittinger |
32 All Rights Reserved |
32 All Rights Reserved |
33 |
33 |
34 This software is furnished under a license and may be used |
34 This software is furnished under a license and may be used |
35 only in accordance with the terms of that license and with the |
35 only in accordance with the terms of that license and with the |
36 inclusion of the above copyright notice. This software may not |
36 inclusion of the above copyright notice. This software may not |
37 be provided or otherwise made available to, or used by, any |
37 be provided or otherwise made available to, or used by, any |
98 REGISTER OBJ *op; |
98 REGISTER OBJ *op; |
99 int nInstVars, instsize; |
99 int nInstVars, instsize; |
100 extern OBJ new(); |
100 extern OBJ new(); |
101 |
101 |
102 if (_isSmallInteger(anInteger)) { |
102 if (_isSmallInteger(anInteger)) { |
103 len = _intVal(anInteger); |
103 len = _intVal(anInteger); |
104 if (len >= 0) { |
104 if (len >= 0) { |
105 if (self == String) { |
105 if (self == String) { |
106 instsize = OHDR_SIZE + len + 1; |
106 instsize = OHDR_SIZE + len + 1; |
107 if (_CanDoQuickNew(instsize)) { |
107 if (_CanDoQuickNew(instsize)) { |
108 /* |
108 /* |
109 * the most common case |
109 * the most common case |
110 */ |
110 */ |
111 _qCheckedNew(newString, instsize); |
111 _qCheckedNew(newString, instsize); |
112 _InstPtr(newString)->o_class = self; |
112 _InstPtr(newString)->o_class = self; |
113 cp = _stringVal(newString); |
113 cp = _stringVal(newString); |
114 #ifdef FAST_MEMSET |
114 #ifdef FAST_MEMSET |
115 memset(cp, ' ', len); |
115 memset(cp, ' ', len); |
116 *(cp + len) = '\0'; |
116 *(cp + len) = '\0'; |
117 #else |
117 #else |
118 while (len >= 8) { |
118 while (len >= 8) { |
119 cp[0] = cp[1] = cp[2] = cp[3] = ' '; |
119 cp[0] = cp[1] = cp[2] = cp[3] = ' '; |
120 cp[4] = cp[5] = cp[6] = cp[7] = ' '; |
120 cp[4] = cp[5] = cp[6] = cp[7] = ' '; |
121 cp += 8; |
121 cp += 8; |
122 len -= 8; |
122 len -= 8; |
123 } |
123 } |
124 while (len--) |
124 while (len--) |
125 *cp++ = ' '; |
125 *cp++ = ' '; |
126 *cp = '\0'; |
126 *cp = '\0'; |
127 #endif |
127 #endif |
128 RETURN (newString); |
128 RETURN (newString); |
129 } |
129 } |
130 nInstVars = 0; |
130 nInstVars = 0; |
131 } else { |
131 } else { |
132 nInstVars = _intVal(_ClassInstPtr(self)->c_ninstvars); |
132 nInstVars = _intVal(_ClassInstPtr(self)->c_ninstvars); |
133 instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + len + 1; |
133 instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + len + 1; |
134 } |
134 } |
135 |
135 |
136 PROTECT_CONTEXT |
136 PROTECT_CONTEXT |
137 _qNew(newString, instsize, SENDER); |
137 _qNew(newString, instsize, SENDER); |
138 UNPROTECT_CONTEXT |
138 UNPROTECT_CONTEXT |
139 if (newString == nil) goto fail; |
139 if (newString == nil) goto fail; |
140 _InstPtr(newString)->o_class = self; |
140 _InstPtr(newString)->o_class = self; |
141 |
141 |
142 if (nInstVars) { |
142 if (nInstVars) { |
143 #if defined(memset4) |
143 #if defined(memset4) |
144 memset4(_InstPtr(newString)->i_instvars, nil, nInstVars); |
144 memset4(_InstPtr(newString)->i_instvars, nil, nInstVars); |
145 #else |
145 #else |
146 # if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
146 # if defined(FAST_MEMSET) && ! defined(NEGATIVE_ADDRESSES) |
147 /* |
147 /* |
148 * knowing that nil is 0 |
148 * knowing that nil is 0 |
149 */ |
149 */ |
150 memset(_InstPtr(newString)->i_instvars, 0, __OBJS2BYTES__(nInstVars)); |
150 memset(_InstPtr(newString)->i_instvars, 0, __OBJS2BYTES__(nInstVars)); |
151 # else |
151 # else |
152 op = _InstPtr(newString)->i_instvars; |
152 op = _InstPtr(newString)->i_instvars; |
153 do { |
153 do { |
154 *op++ = nil; |
154 *op++ = nil; |
155 } while (--nInstVars); |
155 } while (--nInstVars); |
156 # endif |
156 # endif |
157 #endif |
157 #endif |
158 cp = _stringVal(newString) + __OBJS2BYTES__(nInstVars); |
158 cp = _stringVal(newString) + __OBJS2BYTES__(nInstVars); |
159 } else { |
159 } else { |
160 cp = _stringVal(newString); |
160 cp = _stringVal(newString); |
161 } |
161 } |
162 |
162 |
163 #ifdef FAST_MEMSET |
163 #ifdef FAST_MEMSET |
164 memset(cp, ' ', len); |
164 memset(cp, ' ', len); |
165 *(cp + len) = '\0'; |
165 *(cp + len) = '\0'; |
166 #else |
166 #else |
167 while (len >= 8) { |
167 while (len >= 8) { |
168 cp[0] = cp[1] = cp[2] = cp[3] = ' '; |
168 cp[0] = cp[1] = cp[2] = cp[3] = ' '; |
169 cp[4] = cp[5] = cp[6] = cp[7] = ' '; |
169 cp[4] = cp[5] = cp[6] = cp[7] = ' '; |
170 cp += 8; |
170 cp += 8; |
171 len -= 8; |
171 len -= 8; |
172 } |
172 } |
173 while (len--) |
173 while (len--) |
174 *cp++ = ' '; |
174 *cp++ = ' '; |
175 *cp = '\0'; |
175 *cp = '\0'; |
176 #endif |
176 #endif |
177 RETURN (newString); |
177 RETURN (newString); |
178 } |
178 } |
179 } |
179 } |
180 fail: ;; |
180 fail: ;; |
181 %} |
181 %} |
182 . |
182 . |
183 " |
183 " |
220 REGISTER int indx; |
220 REGISTER int indx; |
221 int len; |
221 int len; |
222 OBJ cls; |
222 OBJ cls; |
223 |
223 |
224 if (_isSmallInteger(index)) { |
224 if (_isSmallInteger(index)) { |
225 indx = _intVal(index); |
225 indx = _intVal(index); |
226 cls = _qClass(self); |
226 cls = _qClass(self); |
227 if (cls != String) |
227 if (cls != String) |
228 indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
228 indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
229 len = _stringSize(self); |
229 len = _stringSize(self); |
230 if ((indx > 0) && (indx <= len)) { |
230 if ((indx > 0) && (indx <= len)) { |
231 RETURN ( _MKCHARACTER(_stringVal(self)[indx-1] & 0xFF) ); |
231 RETURN ( _MKCHARACTER(_stringVal(self)[indx-1] & 0xFF) ); |
232 } |
232 } |
233 } |
233 } |
234 %} |
234 %}. |
235 . |
235 ^ self subscriptBoundsError:index |
236 self subscriptBoundsError |
|
237 ! |
236 ! |
238 |
237 |
239 basicAt:index put:aCharacter |
238 basicAt:index put:aCharacter |
240 "store the argument, aCharacter at position index, an Integer |
239 "store the argument, aCharacter at position index, an Integer |
241 - reimplemented here since we store characters" |
240 - reimplemented here since we store characters" |
245 REGISTER int value, indx; |
244 REGISTER int value, indx; |
246 int len; |
245 int len; |
247 OBJ cls; |
246 OBJ cls; |
248 |
247 |
249 if (__isCharacter(aCharacter)) { |
248 if (__isCharacter(aCharacter)) { |
250 value = _intVal(_characterVal(aCharacter)); |
249 value = _intVal(_characterVal(aCharacter)); |
251 if ((value > 0) |
250 if ((value > 0) |
252 && (value <= 255) |
251 && (value <= 255) |
253 && _isSmallInteger(index)) { |
252 && _isSmallInteger(index)) { |
254 indx = _intVal(index); |
253 indx = _intVal(index); |
255 cls = _qClass(self); |
254 cls = _qClass(self); |
256 if (cls != String) |
255 if (cls != String) |
257 indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
256 indx += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
258 len = _stringSize(self); |
257 len = _stringSize(self); |
259 if ((indx > 0) && (indx <= len)) { |
258 if ((indx > 0) && (indx <= len)) { |
260 _stringVal(self)[indx-1] = value; |
259 _stringVal(self)[indx-1] = value; |
261 RETURN ( aCharacter ); |
260 RETURN ( aCharacter ); |
262 } |
261 } |
263 } |
262 } |
264 } |
263 } |
265 %} |
264 %}. |
266 . |
|
267 (aCharacter isMemberOf:Character) ifFalse:[ |
265 (aCharacter isMemberOf:Character) ifFalse:[ |
268 self elementNotCharacter |
266 ^ self elementNotCharacter |
269 ] ifTrue:[ |
267 ] ifTrue:[ |
270 (aCharacter asciiValue between:1 and:255) ifFalse:[ |
268 (aCharacter asciiValue between:1 and:255) ifFalse:[ |
271 self elementBoundsError |
269 ^ self elementBoundsError |
272 ] ifTrue:[ |
270 ] ifTrue:[ |
273 self subscriptBoundsError |
271 ^ self subscriptBoundsError:index |
274 ] |
272 ] |
275 ] |
273 ] |
276 ! ! |
274 ! ! |
277 |
275 |
278 !String methodsFor:'converting'! |
276 !String methodsFor:'converting'! |
279 |
277 |
280 asSymbol |
278 asSymbol |
281 "return a unique symbol with name taken from myself. |
279 "return a unique symbol with name taken from myself. |
282 The argument must be a String, subclass instances are not allowed." |
280 The argument must be a String, subclass instances are not allowed." |
283 %{ |
281 %{ |
284 if (_qClass(self) == String) { |
282 if (_qClass(self) == String) { |
285 RETURN ( _MKSYMBOL(_stringVal(self), (OBJ *)0, __context) ); |
283 RETURN ( _MKSYMBOL(_stringVal(self), (OBJ *)0, __context) ); |
286 } |
284 } |
287 %} |
285 %} |
288 . |
286 . |
289 self primitiveFailed |
287 self primitiveFailed |
290 ! ! |
288 ! ! |
331 |
329 |
332 char buffer[800]; |
330 char buffer[800]; |
333 char *cp; |
331 char *cp; |
334 |
332 |
335 if (__isString(formatString)) { |
333 if (__isString(formatString)) { |
336 /* |
334 /* |
337 * actually only needed on sparc: since thisContext is |
335 * actually only needed on sparc: since thisContext is |
338 * in a global register, which gets destroyed by printf, |
336 * in a global register, which gets destroyed by printf, |
339 * manually save it here - very stupid ... |
337 * manually save it here - very stupid ... |
340 */ |
338 */ |
341 OBJ sav = __thisContext; |
339 OBJ sav = __thisContext; |
342 |
340 |
343 cp = (char *)_stringVal(self); |
341 cp = (char *)_stringVal(self); |
344 if (_qClass(self) != String) |
342 if (_qClass(self) != String) |
345 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
343 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
346 |
344 |
347 sprintf(buffer, (char *)_stringVal(formatString), cp); |
345 sprintf(buffer, (char *)_stringVal(formatString), cp); |
348 __thisContext = sav; |
346 __thisContext = sav; |
349 RETURN ( _MKSTRING(buffer COMMA_SND) ); |
347 RETURN ( _MKSTRING(buffer COMMA_SND) ); |
350 } |
348 } |
351 %} |
349 %} |
352 . |
350 . |
353 self primitiveFailed |
351 self primitiveFailed |
354 |
352 |
362 |
360 |
363 |s n index| |
361 |s n index| |
364 |
362 |
365 n := self occurrencesOf:$'. |
363 n := self occurrencesOf:$'. |
366 n == 0 ifFalse:[ |
364 n == 0 ifFalse:[ |
367 s := String new:(n + 2 + self size). |
365 s := String new:(n + 2 + self size). |
368 s at:1 put:$'. |
366 s at:1 put:$'. |
369 index := 2. |
367 index := 2. |
370 self do:[:thisChar | |
368 self do:[:thisChar | |
371 (thisChar == $') ifTrue:[ |
369 (thisChar == $') ifTrue:[ |
372 s at:index put:thisChar. |
370 s at:index put:thisChar. |
373 index := index + 1. |
371 index := index + 1. |
374 ]. |
372 ]. |
375 s at:index put:thisChar. |
373 s at:index put:thisChar. |
376 index := index + 1. |
374 index := index + 1. |
377 ]. |
375 ]. |
378 s at:index put:$'. |
376 s at:index put:$'. |
379 ^ s |
377 ^ s |
380 ]. |
378 ]. |
381 ^ '''' , self , '''' |
379 ^ '''' , self , '''' |
382 ! |
380 ! |
383 |
381 |
384 storeOn:aStream |
382 storeOn:aStream |
385 "put the storeString of myself on aStream" |
383 "put the storeString of myself on aStream" |
386 |
384 |
387 aStream nextPut: $'. |
385 aStream nextPut: $'. |
388 (self includes:$') ifTrue:[ |
386 (self includes:$') ifTrue:[ |
389 self do:[:thisChar | |
387 self do:[:thisChar | |
390 (thisChar == $') ifTrue:[aStream nextPut:thisChar]. |
388 (thisChar == $') ifTrue:[aStream nextPut:thisChar]. |
391 aStream nextPut:thisChar |
389 aStream nextPut:thisChar |
392 ] |
390 ] |
393 ] ifFalse:[ |
391 ] ifFalse:[ |
394 aStream nextPutAll:self |
392 aStream nextPutAll:self |
395 ]. |
393 ]. |
396 aStream nextPut:$' |
394 aStream nextPut:$' |
397 ! ! |
395 ! ! |
398 |
396 |
399 !String methodsFor:'comparing'! |
397 !String methodsFor:'comparing'! |
413 char *cp1, *cp2; |
411 char *cp1, *cp2; |
414 OBJ cls; |
412 OBJ cls; |
415 |
413 |
416 if (_isNonNilObject(s) |
414 if (_isNonNilObject(s) |
417 && (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self)))) { |
415 && (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self)))) { |
418 cp1 = (char *) _stringVal(self); |
416 cp1 = (char *) _stringVal(self); |
419 len1 = _stringSize(self); |
417 len1 = _stringSize(self); |
420 |
418 |
421 /* |
419 /* |
422 * care for instances of subclasses ... |
420 * care for instances of subclasses ... |
423 */ |
421 */ |
424 if (_qClass(self) != String) { |
422 if (_qClass(self) != String) { |
425 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
423 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
426 |
424 |
427 cp1 += n; |
425 cp1 += n; |
428 len1 -= n; |
426 len1 -= n; |
429 } |
427 } |
430 |
428 |
431 cp2 = (char *) _stringVal(s); |
429 cp2 = (char *) _stringVal(s); |
432 len2 = _stringSize(s); |
430 len2 = _stringSize(s); |
433 /* |
431 /* |
434 * care for instances of subclasses ... |
432 * care for instances of subclasses ... |
435 */ |
433 */ |
436 if (cls != String) { |
434 if (cls != String) { |
437 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
435 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
438 |
436 |
439 cp2 += n; |
437 cp2 += n; |
440 len2 -= n; |
438 len2 -= n; |
441 } |
439 } |
442 |
440 |
443 if (len1 <= len2) |
441 if (len1 <= len2) |
444 cmp = strncmp(cp1, cp2, len1); |
442 cmp = strncmp(cp1, cp2, len1); |
445 else |
443 else |
446 cmp = strncmp(cp1, cp2, len2); |
444 cmp = strncmp(cp1, cp2, len2); |
447 |
445 |
448 if (cmp > 0) { |
446 if (cmp > 0) { |
449 RETURN ( true ); |
447 RETURN ( true ); |
450 } |
448 } |
451 if ((cmp == 0) && (len1 > len2)) { |
449 if ((cmp == 0) && (len1 > len2)) { |
452 RETURN ( true ); |
450 RETURN ( true ); |
453 } |
451 } |
454 RETURN ( false ); |
452 RETURN ( false ); |
455 } |
453 } |
456 %} |
454 %} |
457 . |
455 . |
458 ^ super > aString |
456 ^ super > aString |
459 ! |
457 ! |
469 REGISTER OBJ s = aString; |
467 REGISTER OBJ s = aString; |
470 char *cp1, *cp2; |
468 char *cp1, *cp2; |
471 OBJ cls; |
469 OBJ cls; |
472 |
470 |
473 if (s == self) { |
471 if (s == self) { |
474 RETURN ( true ); |
472 RETURN ( true ); |
475 } |
473 } |
476 if (! _isNonNilObject(s)) { |
474 if (! _isNonNilObject(s)) { |
477 RETURN ( false ); |
475 RETURN ( false ); |
478 } |
476 } |
479 |
477 |
480 if (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self))) { |
478 if (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self))) { |
481 cp1 = (char *) _stringVal(self); |
479 cp1 = (char *) _stringVal(self); |
482 l1 = _stringSize(self); |
480 l1 = _stringSize(self); |
483 /* |
481 /* |
484 * care for instances of subclasses ... |
482 * care for instances of subclasses ... |
485 */ |
483 */ |
486 if (_qClass(self) != String) { |
484 if (_qClass(self) != String) { |
487 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
485 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
488 |
486 |
489 cp1 += n; |
487 cp1 += n; |
490 l1 -= n; |
488 l1 -= n; |
491 } |
489 } |
492 |
490 |
493 cp2 = (char *) _stringVal(s); |
491 cp2 = (char *) _stringVal(s); |
494 l2 = _stringSize(s); |
492 l2 = _stringSize(s); |
495 /* |
493 /* |
496 * care for instances of subclasses ... |
494 * care for instances of subclasses ... |
497 */ |
495 */ |
498 if (cls != String) { |
496 if (cls != String) { |
499 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
497 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
500 |
498 |
501 cp2 += n; |
499 cp2 += n; |
502 l2 -= n; |
500 l2 -= n; |
503 } |
501 } |
504 |
502 |
505 if (l1 != l2) { |
503 if (l1 != l2) { |
506 RETURN ( false ); |
504 RETURN ( false ); |
507 } |
505 } |
508 RETURN ( (strncmp(cp1, cp2, l1) == 0) ? true : false ); |
506 RETURN ( (strncmp(cp1, cp2, l1) == 0) ? true : false ); |
509 } |
507 } |
510 %} |
508 %} |
511 . |
509 . |
512 ^ super = aString |
510 ^ super = aString |
513 ! |
511 ! |
523 REGISTER OBJ s = aString; |
521 REGISTER OBJ s = aString; |
524 char *cp1, *cp2; |
522 char *cp1, *cp2; |
525 OBJ cls; |
523 OBJ cls; |
526 |
524 |
527 if (s == self) { |
525 if (s == self) { |
528 RETURN ( false ); |
526 RETURN ( false ); |
529 } |
527 } |
530 if (! _isNonNilObject(s)) { |
528 if (! _isNonNilObject(s)) { |
531 RETURN ( true ); |
529 RETURN ( true ); |
532 } |
530 } |
533 if (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self))) { |
531 if (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self))) { |
534 cp1 = (char *) _stringVal(self); |
532 cp1 = (char *) _stringVal(self); |
535 l1 = _stringSize(self); |
533 l1 = _stringSize(self); |
536 /* |
534 /* |
537 * care for instances of subclasses ... |
535 * care for instances of subclasses ... |
538 */ |
536 */ |
539 if (_qClass(self) != String) { |
537 if (_qClass(self) != String) { |
540 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
538 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
541 |
539 |
542 cp1 += n; |
540 cp1 += n; |
543 l1 -= n; |
541 l1 -= n; |
544 } |
542 } |
545 |
543 |
546 cp2 = (char *) _stringVal(s); |
544 cp2 = (char *) _stringVal(s); |
547 l2 = _stringSize(s); |
545 l2 = _stringSize(s); |
548 /* |
546 /* |
549 * care for instances of subclasses ... |
547 * care for instances of subclasses ... |
550 */ |
548 */ |
551 if (cls != String) { |
549 if (cls != String) { |
552 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
550 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
553 |
551 |
554 cp2 += n; |
552 cp2 += n; |
555 l2 -= n; |
553 l2 -= n; |
556 } |
554 } |
557 |
555 |
558 if (l1 != l2) { |
556 if (l1 != l2) { |
559 RETURN ( true ); |
557 RETURN ( true ); |
560 } |
558 } |
561 RETURN ( (strncmp(cp1, cp2, l1) == 0) ? false : true ); |
559 RETURN ( (strncmp(cp1, cp2, l1) == 0) ? false : true ); |
562 } |
560 } |
563 %} |
561 %} |
564 . |
562 . |
565 ^ super ~= aString |
563 ^ super ~= aString |
566 ! |
564 ! |
579 char *cp1, *cp2; |
577 char *cp1, *cp2; |
580 OBJ cls; |
578 OBJ cls; |
581 |
579 |
582 if (_isNonNilObject(s) |
580 if (_isNonNilObject(s) |
583 && (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self)))) { |
581 && (((cls = _qClass(s)) == String) || (cls == Symbol) || (cls == _qClass(self)))) { |
584 cp1 = (char *) _stringVal(self); |
582 cp1 = (char *) _stringVal(self); |
585 |
583 |
586 /* |
584 /* |
587 * care for instances of subclasses ... |
585 * care for instances of subclasses ... |
588 */ |
586 */ |
589 if (_qClass(self) != String) { |
587 if (_qClass(self) != String) { |
590 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
588 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
591 |
589 |
592 cp1 += n; |
590 cp1 += n; |
593 } |
591 } |
594 |
592 |
595 cp2 = (char *) _stringVal(s); |
593 cp2 = (char *) _stringVal(s); |
596 /* |
594 /* |
597 * care for instances of subclasses ... |
595 * care for instances of subclasses ... |
598 */ |
596 */ |
599 if (cls != String) { |
597 if (cls != String) { |
600 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
598 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
601 |
599 |
602 cp2 += n; |
600 cp2 += n; |
603 } |
601 } |
604 |
602 |
605 #ifdef HAS_STRCOLL |
603 #ifdef HAS_STRCOLL |
606 cmp = strcoll(cp1, cp2); |
604 cmp = strcoll(cp1, cp2); |
607 #else |
605 #else |
608 cmp = strcmp(cp1, cp2); |
606 cmp = strcmp(cp1, cp2); |
609 #endif |
607 #endif |
610 |
608 |
611 if (cmp > 0) { |
609 if (cmp > 0) { |
612 RETURN ( true ); |
610 RETURN ( true ); |
613 } |
611 } |
614 RETURN ( false ); |
612 RETURN ( false ); |
615 } |
613 } |
616 %}. |
614 %}. |
617 " |
615 " |
618 currently, this operation is only defined for strings, symbols |
616 currently, this operation is only defined for strings, symbols |
619 and subclasses. |
617 and subclasses. |
633 REGISTER int byteValue; |
631 REGISTER int byteValue; |
634 REGISTER int count; |
632 REGISTER int count; |
635 OBJ cls; |
633 OBJ cls; |
636 |
634 |
637 if (__isCharacter(aCharacter)) { |
635 if (__isCharacter(aCharacter)) { |
638 count = 0; |
636 count = 0; |
639 byteValue = _intVal(_characterVal(aCharacter)); |
637 byteValue = _intVal(_characterVal(aCharacter)); |
640 cp = _stringVal(self); |
638 cp = _stringVal(self); |
641 if ((cls = _qClass(self)) != String) |
639 if ((cls = _qClass(self)) != String) |
642 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
640 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
643 while (*cp) { |
641 while (*cp) { |
644 if (*cp++ == byteValue) count++; |
642 if (*cp++ == byteValue) count++; |
645 } |
643 } |
646 RETURN ( _MKSMALLINT(count) ); |
644 RETURN ( _MKSMALLINT(count) ); |
647 } |
645 } |
648 %} |
646 %} |
649 . |
647 . |
650 ^ 0 |
648 ^ 0 |
651 |
649 |
668 REGISTER int byteValue; |
666 REGISTER int byteValue; |
669 extern char *strchr(); |
667 extern char *strchr(); |
670 OBJ cls; |
668 OBJ cls; |
671 |
669 |
672 if (__isCharacter(aCharacter)) { |
670 if (__isCharacter(aCharacter)) { |
673 byteValue = _intVal(_characterVal(aCharacter)); |
671 byteValue = _intVal(_characterVal(aCharacter)); |
674 cp = _stringVal(self); |
672 cp = _stringVal(self); |
675 if ((cls = _qClass(self)) != String) |
673 if ((cls = _qClass(self)) != String) |
676 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
674 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
677 #ifdef FAST_STRCHR |
675 #ifdef FAST_STRCHR |
678 cp = (unsigned char *) strchr(cp, _intVal(_characterVal(aCharacter))); |
676 cp = (unsigned char *) strchr(cp, _intVal(_characterVal(aCharacter))); |
679 if (cp) { |
677 if (cp) { |
680 RETURN ( true ); |
678 RETURN ( true ); |
681 } |
679 } |
682 #else |
680 #else |
683 while (*cp) { |
681 while (*cp) { |
684 if (*cp == byteValue) { |
682 if (*cp == byteValue) { |
685 RETURN ( true ); |
683 RETURN ( true ); |
686 } |
684 } |
687 cp++; |
685 cp++; |
688 } |
686 } |
689 #endif |
687 #endif |
690 } |
688 } |
691 %} |
689 %} |
692 . |
690 . |
693 ^ false |
691 ^ false |
716 #endif |
714 #endif |
717 extern char *INDEX(); |
715 extern char *INDEX(); |
718 OBJ cls; |
716 OBJ cls; |
719 |
717 |
720 if (__isString(aCollection)) { |
718 if (__isString(aCollection)) { |
721 matchP = _stringVal(aCollection); |
719 matchP = _stringVal(aCollection); |
722 cp = _stringVal(self); |
720 cp = _stringVal(self); |
723 if ((cls = _qClass(self)) != String) |
721 if ((cls = _qClass(self)) != String) |
724 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
722 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
725 |
723 |
726 while (*cp) { |
724 while (*cp) { |
727 if (INDEX(matchP, *cp)) { |
725 if (INDEX(matchP, *cp)) { |
728 RETURN ( true ); |
726 RETURN ( true ); |
729 } |
727 } |
730 cp++; |
728 cp++; |
731 } |
729 } |
732 RETURN ( false ); |
730 RETURN ( false ); |
733 } |
731 } |
734 %} |
732 %} |
735 . |
733 . |
736 ^ super includesAny:aCollection |
734 ^ super includesAny:aCollection |
737 |
735 |
758 REGISTER int index; |
756 REGISTER int index; |
759 #endif |
757 #endif |
760 OBJ cls; |
758 OBJ cls; |
761 |
759 |
762 if (__isCharacter(aCharacter)) { |
760 if (__isCharacter(aCharacter)) { |
763 cp = _stringVal(self); |
761 cp = _stringVal(self); |
764 if ((cls = _qClass(self)) != String) |
762 if ((cls = _qClass(self)) != String) |
765 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
763 cp += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
766 #ifdef FAST_STRCHR |
764 #ifdef FAST_STRCHR |
767 cp = (unsigned char *) strchr(cp, _intVal(_characterVal(aCharacter))); |
765 cp = (unsigned char *) strchr(cp, _intVal(_characterVal(aCharacter))); |
768 if (cp) { |
766 if (cp) { |
769 RETURN ( _MKSMALLINT(cp - _stringVal(self) + 1) ); |
767 RETURN ( _MKSMALLINT(cp - _stringVal(self) + 1) ); |
770 } |
768 } |
771 #else |
769 #else |
772 byteValue = _intVal(_characterVal(aCharacter)); |
770 byteValue = _intVal(_characterVal(aCharacter)); |
773 index = 1; |
771 index = 1; |
774 while (*cp) { |
772 while (*cp) { |
775 if (*cp++ == byteValue) { |
773 if (*cp++ == byteValue) { |
776 RETURN ( _MKSMALLINT(index) ); |
774 RETURN ( _MKSMALLINT(index) ); |
777 } |
775 } |
778 index++; |
776 index++; |
779 } |
777 } |
780 #endif |
778 #endif |
781 } |
779 } |
782 %} |
780 %} |
783 . |
781 . |
784 ^ 0 |
782 ^ 0 |
803 #endif |
801 #endif |
804 int len; |
802 int len; |
805 OBJ cls; |
803 OBJ cls; |
806 |
804 |
807 if (_isSmallInteger(start)) { |
805 if (_isSmallInteger(start)) { |
808 if (__isCharacter(aCharacter)) { |
806 if (__isCharacter(aCharacter)) { |
809 byteValue = _intVal(_characterVal(aCharacter)); |
807 byteValue = _intVal(_characterVal(aCharacter)); |
810 index = _intVal(start); |
808 index = _intVal(start); |
811 if (index <= 0) |
809 if (index <= 0) |
812 index = 1; |
810 index = 1; |
813 if ((cls = _qClass(self)) != String) |
811 if ((cls = _qClass(self)) != String) |
814 index += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
812 index += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
815 len = _stringSize(self); |
813 len = _stringSize(self); |
816 if (index <= len) { |
814 if (index <= len) { |
817 cp = _stringVal(self) + index - 1; |
815 cp = _stringVal(self) + index - 1; |
818 #ifdef FAST_STRCHR |
816 #ifdef FAST_STRCHR |
819 cp = (unsigned char *) strchr(cp, byteValue); |
817 cp = (unsigned char *) strchr(cp, byteValue); |
820 if (cp) { |
818 if (cp) { |
821 RETURN ( _MKSMALLINT(cp - _stringVal(self) + 1) ); |
819 RETURN ( _MKSMALLINT(cp - _stringVal(self) + 1) ); |
822 } |
820 } |
823 #else |
821 #else |
824 while (*cp) { |
822 while (*cp) { |
825 if (*cp++ == byteValue) { |
823 if (*cp++ == byteValue) { |
826 RETURN ( _MKSMALLINT(index) ); |
824 RETURN ( _MKSMALLINT(index) ); |
827 } |
825 } |
828 index++; |
826 index++; |
829 } |
827 } |
830 #endif |
828 #endif |
831 } |
829 } |
832 } |
830 } |
833 RETURN ( _MKSMALLINT(0) ); |
831 RETURN ( _MKSMALLINT(0) ); |
834 } |
832 } |
835 %} |
833 %} |
836 . |
834 . |
837 ^ super indexOf:aCharacter startingAt:start |
835 ^ super indexOf:aCharacter startingAt:start |
838 |
836 |
852 int len, index; |
850 int len, index; |
853 OBJ cls; |
851 OBJ cls; |
854 |
852 |
855 index = _intVal(start); |
853 index = _intVal(start); |
856 if (index <= 0) { |
854 if (index <= 0) { |
857 index = 1; |
855 index = 1; |
858 } |
856 } |
859 if ((cls = _qClass(self)) != String) |
857 if ((cls = _qClass(self)) != String) |
860 index += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
858 index += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
861 len = _stringSize(self); |
859 len = _stringSize(self); |
862 if (index > len) { |
860 if (index > len) { |
863 RETURN ( _MKSMALLINT(0) ); |
861 RETURN ( _MKSMALLINT(0) ); |
864 } |
862 } |
865 cp = _stringVal(self) + index - 1; |
863 cp = _stringVal(self) + index - 1; |
866 while (c = *cp++) { |
864 while (c = *cp++) { |
867 #ifdef ASCII |
865 #ifdef ASCII |
868 if (c <= ' ') |
866 if (c <= ' ') |
869 #endif |
867 #endif |
870 if ((c == ' ') || (c == '\t') || (c == '\n') |
868 if ((c == ' ') || (c == '\t') || (c == '\n') |
871 || (c == '\r') || (c == '\f')) { |
869 || (c == '\r') || (c == '\f')) { |
872 RETURN ( _MKSMALLINT(cp - _stringVal(self)) ); |
870 RETURN ( _MKSMALLINT(cp - _stringVal(self)) ); |
873 } |
871 } |
874 } |
872 } |
875 %} |
873 %} |
876 . |
874 . |
877 ^ 0 |
875 ^ 0 |
878 |
876 |
886 |
884 |
887 startsWith:aString |
885 startsWith:aString |
888 "return true, if the receiver starts with something, aString." |
886 "return true, if the receiver starts with something, aString." |
889 |
887 |
890 aString isString ifFalse: [ |
888 aString isString ifFalse: [ |
891 (aString isMemberOf:Character) ifTrue:[ |
889 (aString isMemberOf:Character) ifTrue:[ |
892 self isEmpty ifTrue:[^ false]. |
890 self isEmpty ifTrue:[^ false]. |
893 ^ (self at:1) == aString |
891 ^ (self at:1) == aString |
894 ]. |
892 ]. |
895 ^ super startsWith:aString |
893 ^ super startsWith:aString |
896 ]. |
894 ]. |
897 %{ |
895 %{ |
898 int len1, len2; |
896 int len1, len2; |
899 REGISTER unsigned char *src1, *src2; |
897 REGISTER unsigned char *src1, *src2; |
900 REGISTER OBJ s = aString; |
898 REGISTER OBJ s = aString; |
901 OBJ cls; |
899 OBJ cls; |
902 |
900 |
903 len1 = _qSize(self); |
901 len1 = _qSize(self); |
904 src1 = _stringVal(self); |
902 src1 = _stringVal(self); |
905 if ((cls = _qClass(self)) != String) { |
903 if ((cls = _qClass(self)) != String) { |
906 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
904 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
907 len1 -= n; |
905 len1 -= n; |
908 src1 += n; |
906 src1 += n; |
909 } |
907 } |
910 len2 = _qSize(s); |
908 len2 = _qSize(s); |
911 src2 = _stringVal(s); |
909 src2 = _stringVal(s); |
912 if ((cls = _qClass(s)) != String) { |
910 if ((cls = _qClass(s)) != String) { |
913 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
911 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
914 len2 -= n; |
912 len2 -= n; |
915 src2 += n; |
913 src2 += n; |
916 } |
914 } |
917 if (len1 < len2) { |
915 if (len1 < len2) { |
918 RETURN ( false ); |
916 RETURN ( false ); |
919 } |
917 } |
920 while (*src2) |
918 while (*src2) |
921 if (*src2++ != *src1++) { |
919 if (*src2++ != *src1++) { |
922 RETURN ( false ); |
920 RETURN ( false ); |
923 } |
921 } |
924 %} |
922 %} |
925 . |
923 . |
926 ^ true |
924 ^ true |
927 |
925 |
928 " |
926 " |
933 |
931 |
934 endsWith:aString |
932 endsWith:aString |
935 "return true, if the receiver end with something, aString." |
933 "return true, if the receiver end with something, aString." |
936 |
934 |
937 aString isString ifFalse: [ |
935 aString isString ifFalse: [ |
938 (aString isMemberOf:Character) ifTrue:[ |
936 (aString isMemberOf:Character) ifTrue:[ |
939 self isEmpty ifTrue:[^ false]. |
937 self isEmpty ifTrue:[^ false]. |
940 ^ (self at:(self size)) == aString |
938 ^ (self at:(self size)) == aString |
941 ]. |
939 ]. |
942 ^ super endsWith:aString |
940 ^ super endsWith:aString |
943 ]. |
941 ]. |
944 %{ |
942 %{ |
945 int len1, len2; |
943 int len1, len2; |
946 REGISTER unsigned char *src1, *src2; |
944 REGISTER unsigned char *src1, *src2; |
947 REGISTER OBJ s = aString; |
945 REGISTER OBJ s = aString; |
948 OBJ cls; |
946 OBJ cls; |
949 |
947 |
950 len1 = _qSize(self); |
948 len1 = _qSize(self); |
951 src1 = _stringVal(self); |
949 src1 = _stringVal(self); |
952 if ((cls = _qClass(self)) != String) { |
950 if ((cls = _qClass(self)) != String) { |
953 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
951 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
954 len1 -= n; |
952 len1 -= n; |
955 src1 += n; |
953 src1 += n; |
956 } |
954 } |
957 len2 = _qSize(s); |
955 len2 = _qSize(s); |
958 src2 = _stringVal(s); |
956 src2 = _stringVal(s); |
959 if ((cls = _qClass(s)) != String) { |
957 if ((cls = _qClass(s)) != String) { |
960 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
958 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
961 len2 -= n; |
959 len2 -= n; |
962 src2 += n; |
960 src2 += n; |
963 } |
961 } |
964 if (len1 < len2) { |
962 if (len1 < len2) { |
965 RETURN ( false ); |
963 RETURN ( false ); |
966 } |
964 } |
967 src1 = _stringVal(self) + len1 - len2; |
965 src1 = _stringVal(self) + len1 - len2; |
968 src2 = _stringVal(aString); |
966 src2 = _stringVal(aString); |
969 while (*src2) |
967 while (*src2) |
970 if (*src2++ != *src1++) { |
968 if (*src2++ != *src1++) { |
971 RETURN ( false ); |
969 RETURN ( false ); |
972 } |
970 } |
973 %} |
971 %} |
974 . |
972 . |
975 ^ true |
973 ^ true |
976 |
974 |
977 " |
975 " |
1029 |
1027 |
1030 if ((__isString(self) || __isSymbol(self)) |
1028 if ((__isString(self) || __isSymbol(self)) |
1031 && (__isString(aString) || __isSymbol(aString)) |
1029 && (__isString(aString) || __isSymbol(aString)) |
1032 && _isSmallInteger(insrtWeight) && _isSmallInteger(caseWeight) |
1030 && _isSmallInteger(insrtWeight) && _isSmallInteger(caseWeight) |
1033 && _isSmallInteger(substWeight) && _isSmallInteger(deleteWeight)) { |
1031 && _isSmallInteger(substWeight) && _isSmallInteger(deleteWeight)) { |
1034 iW = _intVal(insrtWeight); |
1032 iW = _intVal(insrtWeight); |
1035 cW = _intVal(caseWeight); |
1033 cW = _intVal(caseWeight); |
1036 sW = _intVal(substWeight); |
1034 sW = _intVal(substWeight); |
1037 dW = _intVal(deleteWeight); |
1035 dW = _intVal(deleteWeight); |
1038 s1 = _stringVal(self); |
1036 s1 = _stringVal(self); |
1039 s2 = _stringVal(aString); |
1037 s2 = _stringVal(aString); |
1040 l1 = strlen(s1); |
1038 l1 = strlen(s1); |
1041 l2 = strlen(s2); |
1039 l2 = strlen(s2); |
1042 |
1040 |
1043 sz = (l1 < l2) ? l2 : l1; |
1041 sz = (l1 < l2) ? l2 : l1; |
1044 delta = sz + 1; |
1042 delta = sz + 1; |
1045 if (sz <= FASTSIZE) { |
1043 if (sz <= FASTSIZE) { |
1046 data = fastData; |
1044 data = fastData; |
1047 } else { |
1045 } else { |
1048 /* add ifdef ALLOCA here ... */ |
1046 /* add ifdef ALLOCA here ... */ |
1049 data = (unsigned short *)malloc(delta * delta * sizeof(short)); |
1047 data = (unsigned short *)malloc(delta * delta * sizeof(short)); |
1050 } |
1048 } |
1051 |
1049 |
1052 data[0] = 0; |
1050 data[0] = 0; |
1053 dp = data+1; |
1051 dp = data+1; |
1054 for (j=1, dp=data+1; j<=sz; j++, dp++) |
1052 for (j=1, dp=data+1; j<=sz; j++, dp++) |
1055 *dp = *(dp-1) + iW; |
1053 *dp = *(dp-1) + iW; |
1056 |
1054 |
1057 for (i=1, dp=data+delta; i<=sz; i++, dp+=delta) |
1055 for (i=1, dp=data+delta; i<=sz; i++, dp+=delta) |
1058 *dp = *(dp-delta) + dW; |
1056 *dp = *(dp-delta) + dW; |
1059 |
1057 |
1060 for (i=1; i<=l1; i++) { |
1058 for (i=1; i<=l1; i++) { |
1061 for (j=1; j<=l2; j++) { |
1059 for (j=1; j<=l2; j++) { |
1062 dp = data + (i*delta) + j; |
1060 dp = data + (i*delta) + j; |
1063 if (s1[i] != s2[j]) { |
1061 if (s1[i] != s2[j]) { |
1064 if (tolower(s1[i]) == tolower(s2[j])) { |
1062 if (tolower(s1[i]) == tolower(s2[j])) { |
1065 m = cW; |
1063 m = cW; |
1066 } else { |
1064 } else { |
1067 m = sW; |
1065 m = sW; |
1068 } |
1066 } |
1069 } else |
1067 } else |
1070 m = 0; |
1068 m = 0; |
1071 |
1069 |
1072 v2 = *(dp - 1) + iW; |
1070 v2 = *(dp - 1) + iW; |
1073 v3 = *(dp - delta) + dW; |
1071 v3 = *(dp - delta) + dW; |
1074 v1 = *(dp - delta - 1) + m; |
1072 v1 = *(dp - delta - 1) + m; |
1075 if (v1 < v2) |
1073 if (v1 < v2) |
1076 if (v1 < v3) |
1074 if (v1 < v3) |
1077 m = v1; |
1075 m = v1; |
1078 else |
1076 else |
1079 m = v3; |
1077 m = v3; |
1080 else |
1078 else |
1081 if (v2 < v3) |
1079 if (v2 < v3) |
1082 m = v2; |
1080 m = v2; |
1083 else |
1081 else |
1084 m = v3; |
1082 m = v3; |
1085 *dp = m; |
1083 *dp = m; |
1086 } |
1084 } |
1087 } |
1085 } |
1088 m = data[l1 * delta + l2]; |
1086 m = data[l1 * delta + l2]; |
1089 if (sz > FASTSIZE) |
1087 if (sz > FASTSIZE) |
1090 free(data); |
1088 free(data); |
1091 RETURN ( _MKSMALLINT(m) ); |
1089 RETURN ( _MKSMALLINT(m) ); |
1092 } |
1090 } |
1093 } |
1091 } |
1094 %} |
1092 %} |
1095 . |
1093 . |
1096 |
1094 |
1097 ^ super levenshteinTo:aString |
1095 ^ super levenshteinTo:aString |
1098 s:substWeight c:caseWeight |
1096 s:substWeight c:caseWeight |
1099 i:insrtWeight d:deleteWeight |
1097 i:insrtWeight d:deleteWeight |
1100 |
1098 |
1101 "'ocmprt' levenshteinTo:'computer' |
1099 "'ocmprt' levenshteinTo:'computer' |
1102 'computer' levenshteinTo:'computer' |
1100 'computer' levenshteinTo:'computer' |
1103 'ocmputer' levenshteinTo:'computer' |
1101 'ocmputer' levenshteinTo:'computer' |
1104 'cmputer' levenshteinTo:'computer' |
1102 'cmputer' levenshteinTo:'computer' |
1109 |
1107 |
1110 shallowCopy |
1108 shallowCopy |
1111 "return a copy of the receiver" |
1109 "return a copy of the receiver" |
1112 |
1110 |
1113 (self isMemberOf:String) ifTrue:[ |
1111 (self isMemberOf:String) ifTrue:[ |
1114 ^ self copyFrom:1 |
1112 ^ self copyFrom:1 |
1115 ]. |
1113 ]. |
1116 ^ super shallowCopy |
1114 ^ super shallowCopy |
1117 ! |
1115 ! |
1118 |
1116 |
1119 deepCopyUsing:aDictionary |
1117 deepCopyUsing:aDictionary |
1120 "return a copy of the receiver - reimplemented to be a bit faster" |
1118 "return a copy of the receiver - reimplemented to be a bit faster" |
1121 |
1119 |
|
1120 " |
|
1121 could be an instance of a subclass which needs deepCopy |
|
1122 of its named instvars ... |
|
1123 " |
1122 (self isMemberOf:String) ifTrue:[ |
1124 (self isMemberOf:String) ifTrue:[ |
1123 ^ self copyFrom:1 |
1125 ^ self copyFrom:1 |
1124 ]. |
1126 ]. |
1125 ^ super deepCopy |
1127 ^ super deepCopy |
1126 ! |
1128 ! |
1127 |
1129 |
1128 simpleDeepCopy |
1130 simpleDeepCopy |
1129 "return a copy of the receiver" |
1131 "return a copy of the receiver" |
1130 |
1132 |
|
1133 " |
|
1134 could be an instance of a subclass which needs deepCopy |
|
1135 of its named instvars ... |
|
1136 " |
1131 (self isMemberOf:String) ifTrue:[ |
1137 (self isMemberOf:String) ifTrue:[ |
1132 ^ self copyFrom:1 |
1138 ^ self copyFrom:1 |
1133 ]. |
1139 ]. |
1134 ^ super deepCopy |
1140 ^ super deepCopy |
1135 ! |
1141 ! |
1136 |
1142 |
1137 deepCopy |
1143 deepCopy |
1138 "return a copy of the receiver" |
1144 "return a copy of the receiver" |
1139 |
1145 |
|
1146 " |
|
1147 could be an instance of a subclass which needs deepCopy |
|
1148 of its named instvars ... |
|
1149 " |
1140 (self isMemberOf:String) ifTrue:[ |
1150 (self isMemberOf:String) ifTrue:[ |
1141 ^ self copyFrom:1 |
1151 ^ self copyFrom:1 |
1142 ]. |
1152 ]. |
1143 ^ super deepCopy |
1153 ^ super deepCopy |
1144 ! |
1154 ! |
1145 |
1155 |
1146 , aString |
1156 , aString |
1156 REGISTER OBJ _String = String; |
1166 REGISTER OBJ _String = String; |
1157 OBJ myClass, argClass, newString; |
1167 OBJ myClass, argClass, newString; |
1158 OBJ new(); |
1168 OBJ new(); |
1159 |
1169 |
1160 if (_isNonNilObject(s)) { |
1170 if (_isNonNilObject(s)) { |
1161 myClass = _qClass(self); |
1171 myClass = _qClass(self); |
1162 argClass = _qClass(s); |
1172 argClass = _qClass(s); |
1163 /* |
1173 /* |
1164 * either same class or both Strings/Symbols: |
1174 * either same class or both Strings/Symbols: |
1165 * can do it here |
1175 * can do it here |
1166 */ |
1176 */ |
1167 if ((myClass == argClass) |
1177 if ((myClass == argClass) |
1168 || (((myClass == _String) || (myClass == Symbol)) |
1178 || (((myClass == _String) || (myClass == Symbol)) |
1169 && ((argClass == _String) || (argClass == Symbol)))) { |
1179 && ((argClass == _String) || (argClass == Symbol)))) { |
1170 cp1 = (char *) _stringVal(self); |
1180 cp1 = (char *) _stringVal(self); |
1171 l1 = _stringSize(self); |
1181 l1 = _stringSize(self); |
1172 if (myClass != _String) { |
1182 if (myClass != _String) { |
1173 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1183 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1174 |
1184 |
1175 cp1 += n; |
1185 cp1 += n; |
1176 l1 -= n; |
1186 l1 -= n; |
1177 } |
1187 } |
1178 |
1188 |
1179 cp2 = (char *) _stringVal(s); |
1189 cp2 = (char *) _stringVal(s); |
1180 l2 = _stringSize(s); |
1190 l2 = _stringSize(s); |
1181 if (argClass != _String) { |
1191 if (argClass != _String) { |
1182 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(s))->c_ninstvars)); |
1192 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(s))->c_ninstvars)); |
1183 |
1193 |
1184 cp2 += n; |
1194 cp2 += n; |
1185 l2 -= n; |
1195 l2 -= n; |
1186 } |
1196 } |
1187 |
1197 |
1188 sz = OHDR_SIZE + l1 + l2 + 1; |
1198 sz = OHDR_SIZE + l1 + l2 + 1; |
1189 _qNew(newString, sz, __context); |
1199 _qNew(newString, sz, __context); |
1190 if (newString != nil) { |
1200 if (newString != nil) { |
1191 _InstPtr(newString)->o_class = String; |
1201 _InstPtr(newString)->o_class = String; |
1192 dstp = _stringVal(newString); |
1202 dstp = _stringVal(newString); |
1193 /* |
1203 /* |
1194 * refetch in case of a GC |
1204 * refetch in case of a GC |
1195 */ |
1205 */ |
1196 cp1 = (char *) _stringVal(self); |
1206 cp1 = (char *) _stringVal(self); |
1197 cp2 = (char *) _stringVal(s); |
1207 cp2 = (char *) _stringVal(s); |
1198 #ifdef FAST_MEMCPY |
1208 #ifdef FAST_MEMCPY |
1199 bcopy(cp1, dstp, l1); |
1209 bcopy(cp1, dstp, l1); |
1200 bcopy(cp2, dstp + l1, l2+1); |
1210 bcopy(cp2, dstp + l1, l2+1); |
1201 #else |
1211 #else |
1202 # ifdef FAST_STRCPY |
1212 # ifdef FAST_STRCPY |
1203 strcpy(dstp, cp1); |
1213 strcpy(dstp, cp1); |
1204 strcpy(dstp + l1, cp2); |
1214 strcpy(dstp + l1, cp2); |
1205 # else |
1215 # else |
1206 while ((*dstp++ = *cp1++) != '\0') ; |
1216 while ((*dstp++ = *cp1++) != '\0') ; |
1207 dstp--; |
1217 dstp--; |
1208 while ((*dstp++ = *cp2++) != '\0') ; |
1218 while ((*dstp++ = *cp2++) != '\0') ; |
1209 # endif |
1219 # endif |
1210 #endif |
1220 #endif |
1211 RETURN ( newString ); |
1221 RETURN ( newString ); |
1212 } |
1222 } |
1213 } |
1223 } |
1214 } |
1224 } |
1215 %} |
1225 %} |
1216 . |
1226 . |
1217 ^ super , aString |
1227 ^ super , aString |
1218 ! |
1228 ! |
1232 OBJ new(); |
1242 OBJ new(); |
1233 |
1243 |
1234 if ((__isString(self) || __isSymbol(self)) |
1244 if ((__isString(self) || __isSymbol(self)) |
1235 && (__isString(string1) || __isSymbol(string1)) |
1245 && (__isString(string1) || __isSymbol(string1)) |
1236 && (__isString(string2) || __isSymbol(string2))) { |
1246 && (__isString(string2) || __isSymbol(string2))) { |
1237 len1 = _stringSize(self); |
1247 len1 = _stringSize(self); |
1238 len2 = _stringSize(string1); |
1248 len2 = _stringSize(string1); |
1239 len3 = _stringSize(string2); |
1249 len3 = _stringSize(string2); |
1240 sz = OHDR_SIZE + len1 + len2 + len3 + 1; |
1250 sz = OHDR_SIZE + len1 + len2 + len3 + 1; |
1241 _qNew(newString, sz, __context); |
1251 _qNew(newString, sz, __context); |
1242 if (newString != nil) { |
1252 if (newString != nil) { |
1243 _InstPtr(newString)->o_class = String; |
1253 _InstPtr(newString)->o_class = String; |
1244 dstp = _stringVal(newString); |
1254 dstp = _stringVal(newString); |
1245 #ifdef FAST_MEMCPY |
1255 #ifdef FAST_MEMCPY |
1246 bcopy(_stringVal(self), dstp, len1); |
1256 bcopy(_stringVal(self), dstp, len1); |
1247 bcopy(_stringVal(string1), dstp + len1, len2); |
1257 bcopy(_stringVal(string1), dstp + len1, len2); |
1248 bcopy(_stringVal(string2), dstp + len1 + len2, len3+1); |
1258 bcopy(_stringVal(string2), dstp + len1 + len2, len3+1); |
1249 #else |
1259 #else |
1250 # ifdef FAST_STRCPY |
1260 # ifdef FAST_STRCPY |
1251 strcpy(dstp, _stringVal(self)); |
1261 strcpy(dstp, _stringVal(self)); |
1252 strcpy(dstp + len1, _stringVal(string1)); |
1262 strcpy(dstp + len1, _stringVal(string1)); |
1253 strcpy(dstp + len1 + len2, _stringVal(string2)); |
1263 strcpy(dstp + len1 + len2, _stringVal(string2)); |
1254 # else |
1264 # else |
1255 srcp = _stringVal(self); |
1265 srcp = _stringVal(self); |
1256 while ((*dstp++ = *srcp++) != '\0') ; |
1266 while ((*dstp++ = *srcp++) != '\0') ; |
1257 dstp--; |
1267 dstp--; |
1258 srcp = _stringVal(string1); |
1268 srcp = _stringVal(string1); |
1259 while ((*dstp++ = *srcp++) != '\0') ; |
1269 while ((*dstp++ = *srcp++) != '\0') ; |
1260 dstp--; |
1270 dstp--; |
1261 srcp = _stringVal(string2); |
1271 srcp = _stringVal(string2); |
1262 while ((*dstp++ = *srcp++) != '\0') ; |
1272 while ((*dstp++ = *srcp++) != '\0') ; |
1263 # endif |
1273 # endif |
1264 #endif |
1274 #endif |
1265 RETURN ( newString ); |
1275 RETURN ( newString ); |
1266 } |
1276 } |
1267 } |
1277 } |
1268 %} |
1278 %} |
1269 . |
1279 . |
1270 ^ super , string1 , string2 |
1280 ^ super , string1 , string2 |
1271 ! |
1281 ! |
1286 |
1296 |
1287 if ((__isString(self) || __isSymbol(self)) |
1297 if ((__isString(self) || __isSymbol(self)) |
1288 && (__isString(string1) || __isSymbol(string1)) |
1298 && (__isString(string1) || __isSymbol(string1)) |
1289 && (__isString(string2) || __isSymbol(string2)) |
1299 && (__isString(string2) || __isSymbol(string2)) |
1290 && (__isString(string3) || __isSymbol(string3))) { |
1300 && (__isString(string3) || __isSymbol(string3))) { |
1291 len1 = _stringSize(self); |
1301 len1 = _stringSize(self); |
1292 len2 = _stringSize(string1); |
1302 len2 = _stringSize(string1); |
1293 len3 = _stringSize(string2); |
1303 len3 = _stringSize(string2); |
1294 len4 = _stringSize(string3); |
1304 len4 = _stringSize(string3); |
1295 sz = OHDR_SIZE + len1 + len2 + len3 + len4 + 1; |
1305 sz = OHDR_SIZE + len1 + len2 + len3 + len4 + 1; |
1296 _qNew(newString, sz, __context); |
1306 _qNew(newString, sz, __context); |
1297 if (newString != nil) { |
1307 if (newString != nil) { |
1298 _InstPtr(newString)->o_class = String; |
1308 _InstPtr(newString)->o_class = String; |
1299 dstp = _stringVal(newString); |
1309 dstp = _stringVal(newString); |
1300 #ifdef FAST_MEMCPY |
1310 #ifdef FAST_MEMCPY |
1301 bcopy(_stringVal(self), dstp, len1); |
1311 bcopy(_stringVal(self), dstp, len1); |
1302 bcopy(_stringVal(string1), dstp + len1, len2); |
1312 bcopy(_stringVal(string1), dstp + len1, len2); |
1303 bcopy(_stringVal(string2), dstp + len1 + len2, len3); |
1313 bcopy(_stringVal(string2), dstp + len1 + len2, len3); |
1304 bcopy(_stringVal(string3), dstp + len1 + len2 + len3, len4+1); |
1314 bcopy(_stringVal(string3), dstp + len1 + len2 + len3, len4+1); |
1305 #else |
1315 #else |
1306 # ifdef FAST_STRCPY |
1316 # ifdef FAST_STRCPY |
1307 strcpy(dstp, _stringVal(self)); |
1317 strcpy(dstp, _stringVal(self)); |
1308 strcpy(dstp + len1, _stringVal(string1)); |
1318 strcpy(dstp + len1, _stringVal(string1)); |
1309 strcpy(dstp + len1 + len2, _stringVal(string2)); |
1319 strcpy(dstp + len1 + len2, _stringVal(string2)); |
1310 strcpy(dstp + len1 + len2 + len3, _stringVal(string3)); |
1320 strcpy(dstp + len1 + len2 + len3, _stringVal(string3)); |
1311 # else |
1321 # else |
1312 srcp = _stringVal(self); |
1322 srcp = _stringVal(self); |
1313 while ((*dstp++ = *srcp++) != '\0') ; |
1323 while ((*dstp++ = *srcp++) != '\0') ; |
1314 dstp--; |
1324 dstp--; |
1315 srcp = _stringVal(string1); |
1325 srcp = _stringVal(string1); |
1316 while ((*dstp++ = *srcp++) != '\0') ; |
1326 while ((*dstp++ = *srcp++) != '\0') ; |
1317 dstp--; |
1327 dstp--; |
1318 srcp = _stringVal(string2); |
1328 srcp = _stringVal(string2); |
1319 while ((*dstp++ = *srcp++) != '\0') ; |
1329 while ((*dstp++ = *srcp++) != '\0') ; |
1320 dstp--; |
1330 dstp--; |
1321 srcp = _stringVal(string3); |
1331 srcp = _stringVal(string3); |
1322 while ((*dstp++ = *srcp++) != '\0') ; |
1332 while ((*dstp++ = *srcp++) != '\0') ; |
1323 # endif |
1333 # endif |
1324 #endif |
1334 #endif |
1325 RETURN ( newString ); |
1335 RETURN ( newString ); |
1326 } |
1336 } |
1327 } |
1337 } |
1328 %} |
1338 %} |
1329 . |
1339 . |
1330 ^ super , string1 , string2 , string3 |
1340 ^ super , string1 , string2 , string3 |
1331 ! |
1341 ! |
1340 REGISTER unsigned char *dstp; |
1350 REGISTER unsigned char *dstp; |
1341 int offs; |
1351 int offs; |
1342 OBJ cls, newString; |
1352 OBJ cls, newString; |
1343 |
1353 |
1344 if (__isCharacter(aCharacter)) { |
1354 if (__isCharacter(aCharacter)) { |
1345 sz = _qSize(self) + 1; |
1355 sz = _qSize(self) + 1; |
1346 if ((cls = _qClass(self)) != String) { |
1356 if ((cls = _qClass(self)) != String) { |
1347 offs = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
1357 offs = __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars)); |
1348 sz -= offs; |
1358 sz -= offs; |
1349 } else |
1359 } else |
1350 offs = 0; |
1360 offs = 0; |
1351 |
1361 |
1352 PROTECT_CONTEXT |
1362 PROTECT_CONTEXT |
1353 _qNew(newString, sz, SENDER); |
1363 _qNew(newString, sz, SENDER); |
1354 UNPROTECT_CONTEXT |
1364 UNPROTECT_CONTEXT |
1355 if (newString) { |
1365 if (newString) { |
1356 _InstPtr(newString)->o_class = String; |
1366 _InstPtr(newString)->o_class = String; |
1357 dstp = _stringVal(newString); |
1367 dstp = _stringVal(newString); |
1358 #ifdef FAST_MEMCPY |
1368 #ifdef FAST_MEMCPY |
1359 sz = sz - OHDR_SIZE - 1 - 1; |
1369 sz = sz - OHDR_SIZE - 1 - 1; |
1360 bcopy(_stringVal(self) + offs, dstp, sz); |
1370 bcopy(_stringVal(self) + offs, dstp, sz); |
1361 dstp += sz; |
1371 dstp += sz; |
1362 #else |
1372 #else |
1363 # ifdef FAST_STRCPY |
1373 # ifdef FAST_STRCPY |
1364 strcpy(dstp, _stringVal(self) + offs); |
1374 strcpy(dstp, _stringVal(self) + offs); |
1365 dstp += sz - OHDR_SIZE - 1 - 1; |
1375 dstp += sz - OHDR_SIZE - 1 - 1; |
1366 # else |
1376 # else |
1367 { |
1377 { |
1368 REGISTER unsigned char *srcp; |
1378 REGISTER unsigned char *srcp; |
1369 |
1379 |
1370 srcp = _stringVal(self) + offs; |
1380 srcp = _stringVal(self) + offs; |
1371 while ((*dstp = *srcp++) != '\0') |
1381 while ((*dstp = *srcp++) != '\0') |
1372 dstp++; |
1382 dstp++; |
1373 } |
1383 } |
1374 # endif |
1384 # endif |
1375 #endif |
1385 #endif |
1376 *dstp++ = _intVal(_characterVal(aCharacter)); |
1386 *dstp++ = _intVal(_characterVal(aCharacter)); |
1377 *dstp = '\0'; |
1387 *dstp = '\0'; |
1378 RETURN (newString ); |
1388 RETURN (newString ); |
1379 } |
1389 } |
1380 } |
1390 } |
1381 %}. |
1391 %}. |
1382 "fall back in case of non-character arg; |
1392 "fall back in case of non-character arg; |
1383 will eventually lead to an bad element signal raise" |
1393 will eventually lead to an bad element signal raise" |
1384 |
1394 |
1400 REGISTER int count; |
1410 REGISTER int count; |
1401 int len, sz, index1, index2; |
1411 int len, sz, index1, index2; |
1402 OBJ newString; |
1412 OBJ newString; |
1403 |
1413 |
1404 if (_isSmallInteger(start) && _isSmallInteger(stop)) { |
1414 if (_isSmallInteger(start) && _isSmallInteger(stop)) { |
1405 len = _stringSize(self); |
1415 len = _stringSize(self); |
1406 index1 = _intVal(start); |
1416 index1 = _intVal(start); |
1407 index2 = _intVal(stop); |
1417 index2 = _intVal(stop); |
1408 |
1418 |
1409 if ((index1 <= index2) && (index1 > 0)) { |
1419 if ((index1 <= index2) && (index1 > 0)) { |
1410 if (_qClass(self) != String) { |
1420 if (_qClass(self) != String) { |
1411 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1421 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1412 |
1422 |
1413 index1 += n; |
1423 index1 += n; |
1414 index2 += n; |
1424 index2 += n; |
1415 } |
1425 } |
1416 if (index2 <= len) { |
1426 if (index2 <= len) { |
1417 count = index2 - index1 + 1; |
1427 count = index2 - index1 + 1; |
1418 PROTECT_CONTEXT |
1428 PROTECT_CONTEXT |
1419 sz = OHDR_SIZE + count + 1; |
1429 sz = OHDR_SIZE + count + 1; |
1420 _qNew(newString, sz, SENDER); |
1430 _qNew(newString, sz, SENDER); |
1421 UNPROTECT_CONTEXT |
1431 UNPROTECT_CONTEXT |
1422 if (newString != nil) { |
1432 if (newString != nil) { |
1423 _InstPtr(newString)->o_class = String; |
1433 _InstPtr(newString)->o_class = String; |
1424 dstp = _stringVal(newString); |
1434 dstp = _stringVal(newString); |
1425 #ifdef FAST_MEMCPY |
1435 #ifdef FAST_MEMCPY |
1426 bcopy(_stringVal(self) + index1 - 1, dstp, count); |
1436 bcopy(_stringVal(self) + index1 - 1, dstp, count); |
1427 dstp[count] = '\0'; |
1437 dstp[count] = '\0'; |
1428 #else |
1438 #else |
1429 srcp = _stringVal(self) + index1 - 1; |
1439 srcp = _stringVal(self) + index1 - 1; |
1430 while (count--) { |
1440 while (count--) { |
1431 *dstp++ = *srcp++; |
1441 *dstp++ = *srcp++; |
1432 } |
1442 } |
1433 *dstp = '\0'; |
1443 *dstp = '\0'; |
1434 #endif |
1444 #endif |
1435 RETURN ( newString ); |
1445 RETURN ( newString ); |
1436 } |
1446 } |
1437 } |
1447 } |
1438 } |
1448 } |
1439 } |
1449 } |
1440 %}. |
1450 %}. |
1441 "fall back in case of non-integer index or out-of-bound index; |
1451 "fall back in case of non-integer index or out-of-bound index; |
1442 will eventually lead to an out-of-bound signal raise" |
1452 will eventually lead to an out-of-bound signal raise" |
1443 |
1453 |
1459 REGISTER int count; |
1469 REGISTER int count; |
1460 int len, index1, sz; |
1470 int len, index1, sz; |
1461 OBJ newString; |
1471 OBJ newString; |
1462 |
1472 |
1463 if (_isSmallInteger(start)) { |
1473 if (_isSmallInteger(start)) { |
1464 len = _stringSize(self); |
1474 len = _stringSize(self); |
1465 index1 = _intVal(start); |
1475 index1 = _intVal(start); |
1466 if (index1 > 0) { |
1476 if (index1 > 0) { |
1467 if (_qClass(self) != String) { |
1477 if (_qClass(self) != String) { |
1468 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1478 int n = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1469 |
1479 |
1470 index1 += n; |
1480 index1 += n; |
1471 } |
1481 } |
1472 if (index1 <= len) { |
1482 if (index1 <= len) { |
1473 count = len - index1 + 1; |
1483 count = len - index1 + 1; |
1474 PROTECT_CONTEXT |
1484 PROTECT_CONTEXT |
1475 sz = OHDR_SIZE + count + 1; |
1485 sz = OHDR_SIZE + count + 1; |
1476 _qNew(newString, sz, SENDER); |
1486 _qNew(newString, sz, SENDER); |
1477 UNPROTECT_CONTEXT |
1487 UNPROTECT_CONTEXT |
1478 if (newString != nil) { |
1488 if (newString != nil) { |
1479 _InstPtr(newString)->o_class = String; |
1489 _InstPtr(newString)->o_class = String; |
1480 dstp = _stringVal(newString); |
1490 dstp = _stringVal(newString); |
1481 #ifdef FAST_MEMCPY |
1491 #ifdef FAST_MEMCPY |
1482 bcopy(_stringVal(self) + index1 - 1, dstp, count); |
1492 bcopy(_stringVal(self) + index1 - 1, dstp, count); |
1483 dstp[count] = '\0'; |
1493 dstp[count] = '\0'; |
1484 #else |
1494 #else |
1485 srcp = _stringVal(self) + index1 - 1; |
1495 srcp = _stringVal(self) + index1 - 1; |
1486 while (count--) { |
1496 while (count--) { |
1487 *dstp++ = *srcp++; |
1497 *dstp++ = *srcp++; |
1488 } |
1498 } |
1489 *dstp = '\0'; |
1499 *dstp = '\0'; |
1490 #endif |
1500 #endif |
1491 RETURN ( newString ); |
1501 RETURN ( newString ); |
1492 } |
1502 } |
1493 } |
1503 } |
1494 } |
1504 } |
1495 } |
1505 } |
1496 %}. |
1506 %}. |
1497 "fall back in case of non-integer index or out-of-bound index; |
1507 "fall back in case of non-integer index or out-of-bound index; |
1498 will eventually lead to an out-of-bound signal raise" |
1508 will eventually lead to an out-of-bound signal raise" |
1499 |
1509 |
1517 |
1527 |
1518 if ((__isString(aString) || __isSymbol(aString)) |
1528 if ((__isString(aString) || __isSymbol(aString)) |
1519 && __isString(self) |
1529 && __isString(self) |
1520 && _isSmallInteger(start) |
1530 && _isSmallInteger(start) |
1521 && _isSmallInteger(stop)) { |
1531 && _isSmallInteger(stop)) { |
1522 len = _stringSize(self); |
1532 len = _stringSize(self); |
1523 index1 = _intVal(start); |
1533 index1 = _intVal(start); |
1524 index2 = _intVal(stop); |
1534 index2 = _intVal(stop); |
1525 count = index2 - index1 + 1; |
1535 count = index2 - index1 + 1; |
1526 if (count <= 0) { |
1536 if (count <= 0) { |
1527 RETURN (self); |
1537 RETURN (self); |
1528 } |
1538 } |
1529 if ((index2 <= len) && (index1 > 0)) { |
1539 if ((index2 <= len) && (index1 > 0)) { |
1530 repLen = _stringSize(aString); |
1540 repLen = _stringSize(aString); |
1531 repIndex = _intVal(repStart); |
1541 repIndex = _intVal(repStart); |
1532 if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) { |
1542 if ((repIndex > 0) && ((repIndex + count - 1) <= repLen)) { |
1533 srcp = _stringVal(aString) + repIndex - 1; |
1543 srcp = _stringVal(aString) + repIndex - 1; |
1534 dstp = _stringVal(self) + index1 - 1; |
1544 dstp = _stringVal(self) + index1 - 1; |
1535 if (aString == self) { |
1545 if (aString == self) { |
1536 /* take care of overlapping copy */ |
1546 /* take care of overlapping copy */ |
1537 if (srcp < dstp) { |
1547 if (srcp < dstp) { |
1538 /* must do a reverse copy */ |
1548 /* must do a reverse copy */ |
1539 srcp += count; |
1549 srcp += count; |
1540 dstp += count; |
1550 dstp += count; |
1541 while (count-- > 0) { |
1551 while (count-- > 0) { |
1542 *--dstp = *--srcp; |
1552 *--dstp = *--srcp; |
1543 } |
1553 } |
1544 RETURN (self); |
1554 RETURN (self); |
1545 } |
1555 } |
1546 } |
1556 } |
1547 #ifdef FAST_MEMCPY |
1557 #ifdef FAST_MEMCPY |
1548 bcopy(srcp, dstp, count); |
1558 bcopy(srcp, dstp, count); |
1549 #else |
1559 #else |
1550 while (count-- > 0) { |
1560 while (count-- > 0) { |
1551 *dstp++ = *srcp++; |
1561 *dstp++ = *srcp++; |
1552 } |
1562 } |
1553 #endif |
1563 #endif |
1554 RETURN (self); |
1564 RETURN (self); |
1555 } |
1565 } |
1556 } |
1566 } |
1557 } |
1567 } |
1558 %} |
1568 %} |
1559 . |
1569 . |
1560 ^ super replaceFrom:start to:stop with:aString startingAt:repStart |
1570 ^ super replaceFrom:start to:stop with:aString startingAt:repStart |
1561 ! |
1571 ! |
1569 REGISTER unsigned oldVal, newVal; |
1579 REGISTER unsigned oldVal, newVal; |
1570 |
1580 |
1571 if (__isCharacter(oldCharacter) |
1581 if (__isCharacter(oldCharacter) |
1572 && __isCharacter(newCharacter) |
1582 && __isCharacter(newCharacter) |
1573 && __isString(self)) { |
1583 && __isString(self)) { |
1574 srcp = (unsigned char *)_stringVal(self); |
1584 srcp = (unsigned char *)_stringVal(self); |
1575 oldVal = _intVal(_characterVal(oldCharacter)); |
1585 oldVal = _intVal(_characterVal(oldCharacter)); |
1576 newVal = _intVal(_characterVal(newCharacter)); |
1586 newVal = _intVal(_characterVal(newCharacter)); |
1577 while (*srcp) { |
1587 while (*srcp) { |
1578 if (*srcp == oldVal) |
1588 if (*srcp == oldVal) |
1579 *srcp = newVal; |
1589 *srcp = newVal; |
1580 srcp++; |
1590 srcp++; |
1581 } |
1591 } |
1582 RETURN ( self ); |
1592 RETURN ( self ); |
1583 } |
1593 } |
1584 %} |
1594 %} |
1585 . |
1595 . |
1586 ^ super replaceAll:oldCharacter by:newCharacter |
1596 ^ super replaceAll:oldCharacter by:newCharacter |
1587 ! |
1597 ! |
1625 REGISTER unsigned char *srcp, *dstp; |
1635 REGISTER unsigned char *srcp, *dstp; |
1626 int len, offs; |
1636 int len, offs; |
1627 |
1637 |
1628 len = _qSize(self); |
1638 len = _qSize(self); |
1629 if (_qClass(self) != String) { |
1639 if (_qClass(self) != String) { |
1630 offs = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1640 offs = __OBJS2BYTES__(_intVal(_ClassInstPtr(_qClass(self))->c_ninstvars)); |
1631 len -= offs; |
1641 len -= offs; |
1632 } else |
1642 } else |
1633 offs = 0; |
1643 offs = 0; |
1634 |
1644 |
1635 _qNew(newString, len, __context); |
1645 _qNew(newString, len, __context); |
1636 if (newString != nil) { |
1646 if (newString != nil) { |
1637 _InstPtr(newString)->o_class = String; |
1647 _InstPtr(newString)->o_class = String; |
1638 srcp = _stringVal(self) + offs; |
1648 srcp = _stringVal(self) + offs; |
1639 dstp = _stringVal(newString); |
1649 dstp = _stringVal(newString); |
1640 while (c = *srcp++) |
1650 while (c = *srcp++) |
1641 if (c == '\\') |
1651 if (c == '\\') |
1642 *dstp++ = '\n'; |
1652 *dstp++ = '\n'; |
1643 else |
1653 else |
1644 *dstp++ = c; |
1654 *dstp++ = c; |
1645 *dstp++ = '\0'; |
1655 *dstp++ = '\0'; |
1646 RETURN ( newString ); |
1656 RETURN ( newString ); |
1647 } |
1657 } |
1648 %} |
1658 %} |
1649 . |
1659 . |
1650 ^ super withCRs |
1660 ^ super withCRs |
1651 ! |
1661 ! |
1661 REGISTER unsigned char *dst; |
1671 REGISTER unsigned char *dst; |
1662 REGISTER int l; |
1672 REGISTER int l; |
1663 #endif |
1673 #endif |
1664 |
1674 |
1665 if (__isCharacter(aCharacter) && __isString(self)) { |
1675 if (__isCharacter(aCharacter) && __isString(self)) { |
1666 byteValue = _intVal(_characterVal(aCharacter)); |
1676 byteValue = _intVal(_characterVal(aCharacter)); |
1667 #ifdef FAST_MEMSET |
1677 #ifdef FAST_MEMSET |
1668 memset(_stringVal(self), byteValue, _qSize(self) - OHDR_SIZE - 1); |
1678 memset(_stringVal(self), byteValue, _qSize(self) - OHDR_SIZE - 1); |
1669 #else |
1679 #else |
1670 dst = _stringVal(self); |
1680 dst = _stringVal(self); |
1671 l = _qSize(self) - OHDR_SIZE - 1; |
1681 l = _qSize(self) - OHDR_SIZE - 1; |
1672 while (l >= 8) { |
1682 while (l >= 8) { |
1673 dst[0] = dst[1] = dst[2] = dst[3] = byteValue; |
1683 dst[0] = dst[1] = dst[2] = dst[3] = byteValue; |
1674 dst[4] = dst[5] = dst[6] = dst[7] = byteValue; |
1684 dst[4] = dst[5] = dst[6] = dst[7] = byteValue; |
1675 dst += 8; |
1685 dst += 8; |
1676 l -= 8; |
1686 l -= 8; |
1677 } |
1687 } |
1678 while (l--) |
1688 while (l--) |
1679 *dst++ = byteValue; |
1689 *dst++ = byteValue; |
1680 #endif |
1690 #endif |
1681 RETURN ( self ); |
1691 RETURN ( self ); |
1682 } |
1692 } |
1683 %} |
1693 %} |
1684 . |
1694 . |
1685 ^ super atAllPut:aCharacter |
1695 ^ super atAllPut:aCharacter |
1686 |
1696 |
1703 REGISTER unsigned char *cp0; |
1713 REGISTER unsigned char *cp0; |
1704 REGISTER unsigned char *cp; |
1714 REGISTER unsigned char *cp; |
1705 |
1715 |
1706 /* ignore instances of subclasses ... */ |
1716 /* ignore instances of subclasses ... */ |
1707 if (_qClass(self) == String) { |
1717 if (_qClass(self) == String) { |
1708 cp = cp0 = _stringVal(self); |
1718 cp = cp0 = _stringVal(self); |
1709 while (*cp == ' ') cp++; |
1719 while (*cp == ' ') cp++; |
1710 startIndex = _MKSMALLINT(cp - cp0 + 1); |
1720 startIndex = _MKSMALLINT(cp - cp0 + 1); |
1711 cp = cp + strlen(cp) - 1; |
1721 cp = cp + strlen(cp) - 1; |
1712 while ((cp >= cp0) && (*cp == ' ')) cp--; |
1722 while ((cp >= cp0) && (*cp == ' ')) cp--; |
1713 endIndex = _MKSMALLINT(cp - cp0 + 1); |
1723 endIndex = _MKSMALLINT(cp - cp0 + 1); |
1714 } |
1724 } |
1715 %} |
1725 %} |
1716 . |
1726 . |
1717 sz := self size. |
1727 sz := self size. |
1718 startIndex == 0 ifTrue:[ |
1728 startIndex == 0 ifTrue:[ |
1719 startIndex := 1. |
1729 startIndex := 1. |
1720 endIndex := sz. |
1730 endIndex := sz. |
1721 blank := Character space. |
1731 blank := Character space. |
1722 [(startIndex < endIndex) and:[(self at:startIndex) == blank]] whileTrue:[ |
1732 [(startIndex < endIndex) and:[(self at:startIndex) == blank]] whileTrue:[ |
1723 startIndex := startIndex + 1 |
1733 startIndex := startIndex + 1 |
1724 ]. |
1734 ]. |
1725 [(endIndex > 1) and:[(self at:endIndex) == blank]] whileTrue:[ |
1735 [(endIndex > 1) and:[(self at:endIndex) == blank]] whileTrue:[ |
1726 endIndex := endIndex - 1 |
1736 endIndex := endIndex - 1 |
1727 ] |
1737 ] |
1728 ]. |
1738 ]. |
1729 startIndex > endIndex ifTrue:[ |
1739 startIndex > endIndex ifTrue:[ |
1730 ^ '' |
1740 ^ '' |
1731 ]. |
1741 ]. |
1732 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
1742 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
1733 ^ self |
1743 ^ self |
1734 ]. |
1744 ]. |
1735 ^ self copyFrom:startIndex to:endIndex |
1745 ^ self copyFrom:startIndex to:endIndex |
1736 ! |
1746 ! |
1737 |
1747 |
1738 withoutSeparators |
1748 withoutSeparators |
1749 REGISTER unsigned char *cp; |
1759 REGISTER unsigned char *cp; |
1750 REGISTER unsigned char c; |
1760 REGISTER unsigned char c; |
1751 |
1761 |
1752 /* ignore instances of subclasses ... */ |
1762 /* ignore instances of subclasses ... */ |
1753 if (_qClass(self) == String) { |
1763 if (_qClass(self) == String) { |
1754 cp = cp0 = _stringVal(self); |
1764 cp = cp0 = _stringVal(self); |
1755 c = *cp; |
1765 c = *cp; |
1756 while ((c == ' ') || (c == '\n') || (c == '\t') |
1766 while ((c == ' ') || (c == '\n') || (c == '\t') |
1757 || (c == '\r') || (c == '\f')) { |
1767 || (c == '\r') || (c == '\f')) { |
1758 cp++; |
1768 cp++; |
1759 c = *cp; |
1769 c = *cp; |
1760 } |
1770 } |
1761 startIndex = _MKSMALLINT(cp - cp0 + 1); |
1771 startIndex = _MKSMALLINT(cp - cp0 + 1); |
1762 cp = cp + strlen(cp) - 1; |
1772 cp = cp + strlen(cp) - 1; |
1763 while ((cp >= cp0) && (*cp == ' ')) cp--; |
1773 while ((cp >= cp0) && (*cp == ' ')) cp--; |
1764 c = *cp; |
1774 c = *cp; |
1765 while ((cp >= cp0) && |
1775 while ((cp >= cp0) && |
1766 ((c == ' ') || (c == '\n') || (c == '\t') |
1776 ((c == ' ') || (c == '\n') || (c == '\t') |
1767 || (c == '\r') || (c == '\f'))) { |
1777 || (c == '\r') || (c == '\f'))) { |
1768 cp--; |
1778 cp--; |
1769 c = *cp; |
1779 c = *cp; |
1770 } |
1780 } |
1771 endIndex = _MKSMALLINT(cp - cp0 + 1); |
1781 endIndex = _MKSMALLINT(cp - cp0 + 1); |
1772 } |
1782 } |
1773 %} |
1783 %} |
1774 . |
1784 . |
1775 sz := self size. |
1785 sz := self size. |
1776 startIndex == 0 ifTrue:[ |
1786 startIndex == 0 ifTrue:[ |
1777 startIndex := 1. |
1787 startIndex := 1. |
1778 endIndex := self size. |
1788 endIndex := self size. |
1779 [(startIndex < endIndex) and:[(self at:startIndex) isSeparator]] whileTrue:[ |
1789 [(startIndex < endIndex) and:[(self at:startIndex) isSeparator]] whileTrue:[ |
1780 startIndex := startIndex + 1 |
1790 startIndex := startIndex + 1 |
1781 ]. |
1791 ]. |
1782 [(endIndex > 1) and:[(self at:endIndex) isSeparator]] whileTrue:[ |
1792 [(endIndex > 1) and:[(self at:endIndex) isSeparator]] whileTrue:[ |
1783 endIndex := endIndex - 1 |
1793 endIndex := endIndex - 1 |
1784 ]. |
1794 ]. |
1785 ]. |
1795 ]. |
1786 startIndex > endIndex ifTrue:[ |
1796 startIndex > endIndex ifTrue:[ |
1787 ^ '' |
1797 ^ '' |
1788 ]. |
1798 ]. |
1789 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
1799 ((startIndex == 1) and:[endIndex == sz]) ifTrue:[ |
1790 ^ self |
1800 ^ self |
1791 ]. |
1801 ]. |
1792 ^ self copyFrom:startIndex to:endIndex |
1802 ^ self copyFrom:startIndex to:endIndex |
1793 ! ! |
1803 ! ! |
1794 |
1804 |
1795 !String methodsFor:'queries'! |
1805 !String methodsFor:'queries'! |