diff options
Diffstat (limited to 'mrbgems/mruby-string-ext/src')
| -rw-r--r-- | mrbgems/mruby-string-ext/src/string.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 2d745589b..085de76ef 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -252,7 +252,8 @@ static mrb_value mrb_str_succ_bang(mrb_state *mrb, mrb_value self) { mrb_value result; - char *p, *e, *b, *t, *prepend; + unsigned char *p, *e, *b, *t; + char *prepend; struct RString *s = mrb_str_ptr(self); size_t l; @@ -261,20 +262,41 @@ mrb_str_succ_bang(mrb_state *mrb, mrb_value self) mrb_str_modify(mrb, s); l = RSTRING_LEN(self); - b = p = RSTRING_PTR(self); + b = p = (unsigned char*) RSTRING_PTR(self); t = e = p + l; *(e--) = 0; - while (b < e) { - if (ISALNUM(*b)) + // find trailing ascii/number + while (e >= b) { + if (ISALNUM(*e)) break; - b++; + e--; + } + if (e < b) { + e = p + l - 1; + result = mrb_str_new_lit(mrb, ""); + } else { + // find leading letter of the ascii/number + b = e; + while (b > p) { + if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z')) + break; + b--; + } + if (!ISALNUM(*b)) + b++; + result = mrb_str_new(mrb, (char*) p, b - p); } - result = mrb_str_new(mrb, p, b - p); while (e >= b) { - if (!ISALNUM(*e)) + if (!ISALNUM(*e)) { + if (*e == 0xff) { + mrb_str_cat_cstr(mrb, result, "\x01"); + (*e) = 0; + } else + (*e)++; break; + } prepend = NULL; if (*e == '9') { if (e == b) prepend = "1"; @@ -292,7 +314,7 @@ mrb_str_succ_bang(mrb_state *mrb, mrb_value self) if (prepend) mrb_str_cat_cstr(mrb, result, prepend); e--; } - result = mrb_str_cat(mrb, result, b, t - b); + result = mrb_str_cat(mrb, result, (char*) b, t - b); l = RSTRING_LEN(result); mrb_str_resize(mrb, self, l); memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l); |
