[前][次][番号順一覧][スレッド一覧]

ruby-changes:2736

From: ko1@a...
Date: 14 Dec 2007 17:37:56 +0900
Subject: [ruby-changes:2736] matz - Ruby:r14227 (trunk): * string.c (rb_str_cmp): encoding aware comparison.

matz	2007-12-14 17:37:39 +0900 (Fri, 14 Dec 2007)

  New Revision: 14227

  Modified files:
    trunk/ChangeLog
    trunk/string.c

  Log:
    * string.c (rb_str_cmp): encoding aware comparison.
    
    * string.c (rb_str_casecmp): ditto.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/string.c?r1=14227&r2=14226
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14227&r2=14226

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 14226)
+++ ChangeLog	(revision 14227)
@@ -1,3 +1,9 @@
+Fri Dec 14 16:06:18 2007  Yukihiro Matsumoto  <matz@r...>
+
+	* string.c (rb_str_cmp): encoding aware comparison.
+
+	* string.c (rb_str_casecmp): ditto.
+
 Fri Dec 14 13:47:54 2007  Nobuyoshi Nakada  <nobu@r...>
 
 	* common.mk (ruby.imp): fix for circular dependency.  a patch from
Index: string.c
===================================================================
--- string.c	(revision 14226)
+++ string.c	(revision 14227)
@@ -118,7 +118,7 @@
 	    while (p < e) {
 		int c = (unsigned char)*p;
 
-		if (!isascii(c)) {
+		if (!rb_enc_isascii(c, enc)) {
 		    cr = ENC_CODERANGE_8BIT;
 		    break;
 		}
@@ -1276,12 +1276,18 @@
 {
     long len;
     int retval;
+    rb_encoding *enc;
 
-    rb_enc_check(str1, str2);	/* xxxx error-less encoding check? */
+    enc = rb_enc_compatible(str1, str2);
     len = lesser(RSTRING_LEN(str1), RSTRING_LEN(str2));
     retval = memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len);
     if (retval == 0) {
-	if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return 0;
+	if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) {
+	    if (!enc) {
+		return rb_enc_get_index(str1) - rb_enc_get_index(str2);
+	    }
+	    return 0;
+	}
 	if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return 1;
 	return -1;
     }
@@ -1404,19 +1410,35 @@
 static VALUE
 rb_str_casecmp(VALUE str1, VALUE str2)
 {
-    long len;
+    long i, len;
     int retval;
+    rb_encoding *enc;
+    char *p1, *p1end, *p2, *p2end;
 
     StringValue(str2);
-    len = lesser(RSTRING_LEN(str1), RSTRING_LEN(str2));
-    retval = rb_memcicmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len);
-    if (retval == 0) {
-	if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
-	if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
-	return INT2FIX(-1);
+    enc = rb_enc_compatible(str1, str2);
+    if (!enc) {
+	return rb_str_cmp(str1, str2);
     }
-    if (retval == 0) return INT2FIX(0);
-    if (retval > 0) return INT2FIX(1);
+
+    p1 = RSTRING_PTR(str1); p1end = RSTRING_END(p1);
+    p2 = RSTRING_PTR(str2); p2end = RSTRING_END(str2);
+    while (p1 < p1end && p2 < p2end) {
+	int c1 = rb_enc_codepoint(p1, p1end, enc);
+	int c2 = rb_enc_codepoint(p2, p2end, enc);
+
+	if (c1 != c2) {
+	    c1 = rb_enc_toupper(c1, enc);
+	    c2 = rb_enc_toupper(c2, enc);
+	    if (c1 > c2) return INT2FIX(1);
+	    if (c1 < c2) return INT2FIX(-1);
+	}
+	len = rb_enc_codelen(c1, enc);
+	p1 += len;
+	p2 += len;
+    }
+    if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
+    if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
     return INT2FIX(-1);
 }
 
@@ -1834,7 +1856,7 @@
     while ((s = rb_enc_prev_char(sbeg, s, enc)) != 0) {
 	cc = rb_enc_codepoint(s, e, enc);
 	if (rb_enc_isalnum(cc, enc)) {
-	    if (isascii(cc)) {
+	    if (rb_enc_isascii(cc, enc)) {
 		if ((c = succ_char(s)) == 0) break;
 	    }
 	    else {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]