#REFACTORING by cg
authorClaus Gittinger <cg@exept.de>
Wed, 29 May 2019 11:23:39 +0200
changeset 24233 9db9068aed81
parent 24232 506ee6a81f82
child 24234 524b83156e8e
#REFACTORING by cg class: String added: #compareCaselessWith:
String.st
--- a/String.st	Wed May 29 10:11:12 2019 +0200
+++ b/String.st	Wed May 29 11:23:39 2019 +0200
@@ -526,8 +526,6 @@
 ! !
 
 
-
-
 !String class methodsFor:'queries'!
 
 defaultPlatformClass
@@ -548,10 +546,6 @@
 ! !
 
 
-
-
-
-
 !String methodsFor:'accessing'!
 
 at:index
@@ -1964,6 +1958,100 @@
     ^ super > aString
 !
 
+compareCaselessWith:aString
+    "Compare the receiver against the argument, ignoring case.
+     Return 1 if the receiver is greater, 0 if equal and -1 if less than the argument."
+
+%{  /* NOCONTEXT */
+
+    int cmp;
+
+    if (__isNonNilObject(aString)) {
+        int argIsString = __qIsStringLike(aString);
+
+        if (argIsString || __qClass(aString) == __qClass(self)) {
+            unsigned char *cp1, *cp2;
+            unsigned char ch1, ch2;
+
+            //
+            // care for instances of subclasses ...
+            //
+            cp1 = __stringVal(self);
+            if (!__qIsStringLike(self)) {
+                int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
+
+                cp1 += n;
+            }
+
+            //
+            // care for instances of subclasses ...
+            //
+            cp2 = __stringVal(aString);
+            if (!argIsString) {
+                int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aString))->c_ninstvars));
+
+                cp2 += n;
+            }
+
+            while (1) {
+                while ((ch1 = *cp1++) == (ch2 = *cp2++)) {
+                    if (ch1 == 0) {
+                        RETURN( __mkSmallInteger( 0 ) );
+                    }
+                }
+                    
+                // first difference
+                if (ch1 == 0) {
+                    // receiver shorter
+                    RETURN( __mkSmallInteger( -1 ) );
+                }
+                if (ch2 == 0) {
+                    // arg shorter
+                    RETURN( __mkSmallInteger( 1 ) );
+                }
+
+                if (((ch1 >= 'A') && (ch1 <= 'Z'))
+                 || ((ch1 >= 0xC0) && (ch1 <= 0xDE) && (ch1 != 0xD7))) {
+                    ch1 += 'a'-'A';
+                }    
+                if (((ch2 >= 'A') && (ch2 <= 'Z'))
+                 || ((ch2 >= 0xC0) && (ch2 <= 0xDE) && (ch2 != 0xD7))) {
+                    ch2 += 'a'-'A';
+                }
+                if (ch1 != ch2) {
+                    if (ch1 < ch2) {
+                        RETURN( __mkSmallInteger( -1 ) );
+                    }
+                    RETURN( __mkSmallInteger( 1 ) );
+                }
+            }
+        }
+    }
+getOutOfHere: ;
+%}.
+    "
+     currently, this operation is only defined for strings, symbols and subclasses.
+     allow for an implementation in Smalltalk
+    "
+    ^ super compareCaselessWith:aString
+
+    "
+     'aaa' compareCaselessWith:'aaaa' -1
+     'aaaa' compareCaselessWith:'aaa' 1
+     
+     'aaaa' compareCaselessWith:'aaaA' 0
+     'aaaA' compareCaselessWith:'aaaa' 0
+     'aaaAB' compareCaselessWith:'aaaa' 1
+     'aaaaB' compareCaselessWith:'aaaA' 1
+     'aaaa' compareCaselessWith:'aaaAB' -1
+     'aaaA' compareCaselessWith:'aaaaB' -1
+     'aaaa' compareCaselessWith:'aaax'  -1
+     'aaaa' compareCaselessWith:'aaaX'  -1
+    "
+
+    "Created: / 29-05-2019 / 10:48:39 / Claus Gittinger"
+!
+
 compareCollatingWith:aString
     "Compare the receiver with the argument and return 1 if the receiver is
      greater, 0 if equal and -1 if less than the argument in a sorted list.
@@ -5015,7 +5103,6 @@
     "Modified (comment): / 01-05-2017 / 14:05:41 / cg"
 ! !
 
-
 !String methodsFor:'substring searching'!
 
 caseInsensitiveIndexOfSubCollection:aSubString startingAt:startIndex ifAbsent:exceptionValue
@@ -5321,7 +5408,6 @@
 
 ! !
 
-
 !String class methodsFor:'documentation'!
 
 version