String.st
changeset 159 514c749165c3
parent 95 d22739a0c6e9
child 186 a4c3032fc825
equal deleted inserted replaced
158:be947d4e7fb2 159:514c749165c3
     1 "
     1 "
     2  COPYRIGHT (c) 1988 by Claus Gittinger
     2  COPYRIGHT (c) 1988 by Claus Gittinger
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    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
    40 "
    40 "
    41 !
    41 !
    42 
    42 
    43 version
    43 version
    44 "
    44 "
    45 $Header: /cvs/stx/stx/libbasic/String.st,v 1.17 1994-08-05 01:02:46 claus Exp $
    45 $Header: /cvs/stx/stx/libbasic/String.st,v 1.18 1994-10-10 00:28:43 claus Exp $
    46 "
    46 "
    47 !
    47 !
    48 
    48 
    49 documentation
    49 documentation
    50 "
    50 "
    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     "
   202 %{  /* NOCONTEXT */
   202 %{  /* NOCONTEXT */
   203     OBJ cls;
   203     OBJ cls;
   204 
   204 
   205     cls = _qClass(self);
   205     cls = _qClass(self);
   206     if ((cls == String) || (cls == Symbol)) {
   206     if ((cls == String) || (cls == Symbol)) {
   207         RETURN ( _MKSMALLINT(_stringSize(self)) );
   207 	RETURN ( _MKSMALLINT(_stringSize(self)) );
   208     }
   208     }
   209 %}
   209 %}
   210 .
   210 .
   211     ^ super basicSize - 1
   211     ^ super basicSize - 1
   212 !
   212 !
   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 ! !
   310      even in case of emergency."
   308      even in case of emergency."
   311 
   309 
   312 %{  /* NOCONTEXT */
   310 %{  /* NOCONTEXT */
   313 
   311 
   314     if (_qClass(self) == String) {
   312     if (_qClass(self) == String) {
   315         printf("%s", _stringVal(self));
   313 	printf("%s", _stringVal(self));
   316         RETURN (self);
   314 	RETURN (self);
   317     }
   315     }
   318 %}
   316 %}
   319 .
   317 .
   320     ^ super print
   318     ^ super print
   321 !
   319 !
   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     "
   990     REGISTER unsigned char *src;
   988     REGISTER unsigned char *src;
   991     OBJ cls;
   989     OBJ cls;
   992 
   990 
   993     src = _stringVal(self);
   991     src = _stringVal(self);
   994     if ((cls = _qClass(self)) != String)
   992     if ((cls = _qClass(self)) != String)
   995         src += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   993 	src += __OBJS2BYTES__(_intVal(_ClassInstPtr(cls)->c_ninstvars));
   996 
   994 
   997     while (*src)
   995     while (*src)
   998         if (*src++ != ' ') {
   996 	if (*src++ != ' ') {
   999             RETURN ( false );
   997 	    RETURN ( false );
  1000         }
   998 	}
  1001 %}
   999 %}
  1002 .
  1000 .
  1003     ^ true
  1001     ^ true
  1004 !
  1002 !
  1005 
  1003 
  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 !
  1595 
  1605 
  1596     REGISTER char c;
  1606     REGISTER char c;
  1597     REGISTER unsigned char *hip, *lowp;
  1607     REGISTER unsigned char *hip, *lowp;
  1598 
  1608 
  1599     if (__isString(self)) {
  1609     if (__isString(self)) {
  1600         lowp = _stringVal(self);
  1610 	lowp = _stringVal(self);
  1601         hip = lowp + _stringSize(self) - 1;
  1611 	hip = lowp + _stringSize(self) - 1;
  1602         while (lowp < hip) {
  1612 	while (lowp < hip) {
  1603             c = *lowp;
  1613 	    c = *lowp;
  1604             *lowp = *hip;
  1614 	    *lowp = *hip;
  1605             *hip = c;
  1615 	    *hip = c;
  1606             lowp++;
  1616 	    lowp++;
  1607             hip--;
  1617 	    hip--;
  1608         }
  1618 	}
  1609         RETURN ( self );
  1619 	RETURN ( self );
  1610     }
  1620     }
  1611 %}
  1621 %}
  1612 .
  1622 .
  1613     ^ super reverse
  1623     ^ super reverse
  1614 !
  1624 !
  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'!
  1818 %{  /* NOCONTEXT */
  1828 %{  /* NOCONTEXT */
  1819     OBJ cls;
  1829     OBJ cls;
  1820 
  1830 
  1821     cls = _qClass(self);
  1831     cls = _qClass(self);
  1822     if ((cls == String) || (cls == Symbol)) {
  1832     if ((cls == String) || (cls == Symbol)) {
  1823         RETURN ( (_stringSize(self) == 0) ? true : false);
  1833 	RETURN ( (_stringSize(self) == 0) ? true : false);
  1824     }
  1834     }
  1825 %}
  1835 %}
  1826 .
  1836 .
  1827     ^ super isEmpty
  1837     ^ super isEmpty
  1828 ! !
  1838 ! !