summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-08 16:38:40 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-08 16:38:40 +0000
commit6e0b5f40cc708f93013262c55991a6ab4e115823 (patch)
treeb16fd9b8b32bb44c8888258517b5b20e18bcb27a /string.c
parent1d1a3fb75a0e4b0f492d67226653c77965d35fcf (diff)
* 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". git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17963 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r--string.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/string.c b/string.c
index 8c1cf0d831..e1bb65599e 100644
--- a/string.c
+++ b/string.c
@@ -2516,11 +2516,12 @@ rb_str_succ(VALUE orig)
{
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 @@ rb_str_succ(VALUE orig)
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;