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

ruby-changes:10929

From: nobu <ko1@a...>
Date: Sun, 22 Feb 2009 14:33:22 +0900 (JST)
Subject: [ruby-changes:10929] Ruby:r22505 (trunk): * string.c (tr_trans): should not be affected by the encoding of

nobu	2009-02-22 14:33:07 +0900 (Sun, 22 Feb 2009)

  New Revision: 22505

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22505

  Log:
    * string.c (tr_trans): should not be affected by the encoding of
      replacement unless actually modified.  [ruby-talk:328967]

  Modified files:
    trunk/ChangeLog
    trunk/string.c
    trunk/test/ruby/test_string.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22504)
+++ ChangeLog	(revision 22505)
@@ -1,3 +1,8 @@
+Sun Feb 22 14:33:06 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (tr_trans): should not be affected by the encoding of
+	  replacement unless actually modified.  [ruby-talk:328967]
+
 Sun Feb 22 13:38:44 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/socket/init.c (s_recvfrom_nonblock): handles EAGAIN too.
Index: string.c
===================================================================
--- string.c	(revision 22504)
+++ string.c	(revision 22505)
@@ -4791,8 +4791,10 @@
 	char *buf = ALLOC_N(char, max), *t = buf;
 
 	while (s < send) {
-	    c0 = c = rb_enc_codepoint(s, send, enc);
-	    tlen = clen = rb_enc_codelen(c, enc);
+	    int may_modify = 0;
+	    c0 = c = rb_enc_codepoint(s, send, e1);
+	    clen = rb_enc_codelen(c, e1);
+	    tlen = enc == e1 ? clen : rb_enc_codelen(c, enc);
 
 	    s += clen;
 	    if (c < 256) {
@@ -4819,6 +4821,7 @@
 	    else {
 		save = -1;
 		c = c0;
+		if (enc != e1) may_modify = 1;
 	    }
 	    while (t - buf + tlen >= max) {
 		offset = t - buf;
@@ -4827,6 +4830,9 @@
 		t = buf + offset;
 	    }
 	    rb_enc_mbcput(c, t, enc);
+	    if (may_modify && memcmp(s, t, tlen) != 0) {
+		modify = 1;
+	    }
 	    t += tlen;
 	}
 	*t = '\0';
@@ -4858,8 +4864,10 @@
 	char *buf = ALLOC_N(char, max), *t = buf;
 
 	while (s < send) {
-	    c0 = c = rb_enc_codepoint(s, send, enc);
-	    tlen = clen = rb_enc_codelen(c, enc);
+	    int may_modify = 0;
+	    c0 = c = rb_enc_codepoint(s, send, e1);
+	    clen = rb_enc_codelen(c, e1);
+	    tlen = enc == e1 ? clen : rb_enc_codelen(c, enc);
 
 	    if (c < 256) {
 		c = trans[c];
@@ -4881,8 +4889,8 @@
 		modify = 1;
 	    }
 	    else {
-		modify = 1;
 		c = c0;
+		if (enc != e1) may_modify = 1;
 	    }
 	    while (t - buf + tlen >= max) {
 		offset = t - buf;
@@ -4890,7 +4898,12 @@
 		REALLOC_N(buf, char, max);
 		t = buf + offset;
 	    }
-	    if (s != t) rb_enc_mbcput(c, t, enc);
+	    if (s != t) {
+		rb_enc_mbcput(c, t, enc);
+		if (may_modify && memcmp(s, t, tlen) != 0) {
+		    modify = 1;
+		}
+	    }
 	    s += clen;
 	    t += tlen;
 	}
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 22504)
+++ test/ruby/test_string.rb	(revision 22505)
@@ -1395,6 +1395,9 @@
     assert_equal(S("hippo"), S("hello").tr(S("el"), S("ip")))
     assert_equal(S("*e**o"), S("hello").tr(S("^aeiou"), S("*")))
     assert_equal(S("hal"),   S("ibm").tr(S("b-z"), S("a-z")))
+
+    a = "abc".force_encoding(Encoding::US_ASCII)
+    assert_equal(Encoding::US_ASCII, a.tr(S("z"), S("\u0101")).encoding)
   end
 
   def test_tr!
@@ -1415,6 +1418,10 @@
     a = S("ibm")
     assert_nil(a.tr!(S("B-Z"), S("A-Z")))
     assert_equal(S("ibm"), a)
+
+    a = "abc".force_encoding(Encoding::US_ASCII)
+    assert_nil(a.tr!(S("z"), S("\u0101")))
+    assert_equal(Encoding::US_ASCII, a.encoding)
   end
 
   def test_tr_s

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

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