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

ruby-changes:6447

From: nobu <ko1@a...>
Date: Wed, 9 Jul 2008 01:39:09 +0900 (JST)
Subject: [ruby-changes:6447] Ruby:r17963 (trunk, ruby_1_8): * string.c (rb_str_succ): alphabets or numerics mutually enclosing

nobu	2008-07-09 01:38:40 +0900 (Wed, 09 Jul 2008)

  New Revision: 17963

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

  Log:
    * string.c (rb_str_succ): alphabets or numerics mutually enclosing
      non-alphanumeric characters can carry up.  e.g., "1.999".succ should
      be "2.000".

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 17962)
+++ ChangeLog	(revision 17963)
@@ -1,3 +1,9 @@
+Wed Jul  9 01:38:37 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (rb_str_succ): alphabets or numerics mutually enclosing
+	  non-alphanumeric characters can carry up.  e.g., "1.999".succ should
+	  be "2.000".
+
 Wed Jul  9 00:12:31 2008  Yusuke Endoh  <mame@t...>
 
 	* thread.c (rb_set_coverages, rb_reset_coverages): enable and disable
Index: string.c
===================================================================
--- string.c	(revision 17962)
+++ string.c	(revision 17963)
@@ -2516,11 +2516,12 @@
 {
     rb_encoding *enc;
     VALUE str;
-    char *sbeg, *s, *e;
+    char *sbeg, *s, *e, *last_alnum = 0;
     int c = -1;
     long l;
     char carry[ONIGENC_CODE_TO_MBC_MAXLEN] = "\1";
     int carry_pos = 0, carry_len = 1;
+    enum neighbor_char neighbor = NEIGHBOR_FOUND;
 
     str = rb_str_new5(orig, RSTRING_PTR(orig), RSTRING_LEN(orig));
     rb_enc_cr_str_copy_for_substr(str, orig);
@@ -2532,19 +2533,27 @@
     s = e = sbeg + RSTRING_LEN(str);
 
     while ((s = rb_enc_prev_char(sbeg, s, enc)) != 0) {
-        enum neighbor_char neighbor;
+	if (neighbor == NEIGHBOR_NOT_CHAR && last_alnum) {
+	    if (ISALPHA(*last_alnum) ? ISDIGIT(*s) :
+		ISDIGIT(*last_alnum) ? ISALPHA(*s) : 0) {
+		s = last_alnum;
+		break;
+	    }
+	}
 	if ((l = rb_enc_precise_mbclen(s, e, enc)) <= 0) continue;
         neighbor = enc_succ_alnum_char(s, l, enc, carry);
-        if (neighbor == NEIGHBOR_NOT_CHAR) {
-	    if (c == -1) continue;
-            s++;
+        switch (neighbor) {
+	  case NEIGHBOR_NOT_CHAR:
+	    continue;
+	  case NEIGHBOR_FOUND:
+	    return str;
+	  case NEIGHBOR_WRAPPED:
+	    last_alnum = s;
+	    break;
 	}
-        else if (neighbor == NEIGHBOR_FOUND)
-            return str;
         c = 1;
         carry_pos = s - sbeg;
         carry_len = l;
-        if (neighbor == NEIGHBOR_NOT_CHAR) break;
     }
     if (c == -1) {		/* str contains no alnum */
 	s = e;
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 17962)
+++ test/ruby/test_string.rb	(revision 17963)
@@ -1221,6 +1221,7 @@
 
     assert_equal(S("124"),  S("123").succ)
     assert_equal(S("1000"), S("999").succ)
+    assert_equal(S("2.000"), S("1.999").succ)
 
     assert_equal(S("No.10"), S("No.9").succ)
     assert_equal(S("2000aaa"),  S("1999zzz").succ)
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 17962)
+++ ruby_1_8/ChangeLog	(revision 17963)
@@ -1,3 +1,9 @@
+Wed Jul  9 01:38:37 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (rb_str_succ): alphabets or numerics mutually enclosing
+	  non-alphanumeric characters can carry up.  e.g., "1.999".succ should
+	  be "2.000".
+
 Tue Jul  8 00:22:58 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* string.c (rb_str_succ): limit carrying in an alphanumeric region if
Index: ruby_1_8/string.c
===================================================================
--- ruby_1_8/string.c	(revision 17962)
+++ ruby_1_8/string.c	(revision 17963)
@@ -1401,7 +1401,7 @@
     VALUE orig;
 {
     VALUE str;
-    char *sbeg, *s;
+    char *sbeg, *s, *last_alnum = 0;
     int c = -1;
     long n = 0;
 
@@ -1413,13 +1413,18 @@
 
     while (sbeg <= s) {
 	if (ISALNUM(*s)) {
+	    if (last_alnum && last_alnum > s + 1) {
+		if (ISALPHA(*last_alnum) ? ISDIGIT(*s) :
+		    ISDIGIT(*last_alnum) ? ISALPHA(*s) : 0) {
+		    s = last_alnum;
+		    n = s - sbeg;
+		    break;
+		}
+	    }
+	    last_alnum = s;
 	    if ((c = succ_char(s)) == 0) break;
 	    n = s - sbeg;
 	}
-	else if (c != -1) {
-	    n = ++s - sbeg;
-	    break;
-	}
 	s--;
     }
     if (c == -1) {		/* str contains no alnum */
Index: ruby_1_8/test/ruby/test_string.rb
===================================================================
--- ruby_1_8/test/ruby/test_string.rb	(revision 17962)
+++ ruby_1_8/test/ruby/test_string.rb	(revision 17963)
@@ -25,6 +25,7 @@
 
     assert_equal("124",  "123".succ)
     assert_equal("1000", "999".succ)
+    assert_equal("2.000", "1.999".succ)
 
     assert_equal("No.10", "No.9".succ)
     assert_equal("2000aaa",  "1999zzz".succ)

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

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