diff options
| author | mattn <[email protected]> | 2014-08-08 17:58:07 +0900 |
|---|---|---|
| committer | mattn <[email protected]> | 2014-08-08 17:58:07 +0900 |
| commit | dc0c3546581fb10b2a9abb0e399f1f58488a2fc5 (patch) | |
| tree | 5db5a93d4e89bd9dc2dfce2a5e919604edc019d1 /mrbgems/mruby-string-ext/src/string.c | |
| parent | 569c7dec5f884c3d1345dcc22b7ac0f568a06437 (diff) | |
| download | mruby-dc0c3546581fb10b2a9abb0e399f1f58488a2fc5.tar.gz mruby-dc0c3546581fb10b2a9abb0e399f1f58488a2fc5.zip | |
Add String#succ, String#succ!, String#next, String#next!
Diffstat (limited to 'mrbgems/mruby-string-ext/src/string.c')
| -rw-r--r-- | mrbgems/mruby-string-ext/src/string.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index f04f12c4b..2d745589b 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -239,6 +239,76 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) return result; } +/* + * call-seq: + * string.succ -> string + * + * Returns next sequence of the string; + * + * a = "abc" + * a.succ #=> "abd" + */ +static mrb_value +mrb_str_succ_bang(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + char *p, *e, *b, *t, *prepend; + struct RString *s = mrb_str_ptr(self); + size_t l; + + if (RSTRING_LEN(self) == 0) + return self; + + mrb_str_modify(mrb, s); + l = RSTRING_LEN(self); + b = p = RSTRING_PTR(self); + t = e = p + l; + *(e--) = 0; + + while (b < e) { + if (ISALNUM(*b)) + break; + b++; + } + result = mrb_str_new(mrb, p, b - p); + + while (e >= b) { + if (!ISALNUM(*e)) + break; + prepend = NULL; + if (*e == '9') { + if (e == b) prepend = "1"; + *e = '0'; + } else if (*e == 'z') { + if (e == b) prepend = "a"; + *e = 'a'; + } else if (*e == 'Z') { + if (e == b) prepend = "A"; + *e = 'A'; + } else { + (*e)++; + break; + } + if (prepend) mrb_str_cat_cstr(mrb, result, prepend); + e--; + } + result = mrb_str_cat(mrb, result, b, t - b); + l = RSTRING_LEN(result); + mrb_str_resize(mrb, self, l); + memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l); + return self; +} + +static mrb_value +mrb_str_succ(mrb_state *mrb, mrb_value self) +{ + mrb_value str; + + str = mrb_str_dup(mrb, self); + mrb_str_succ_bang(mrb, str); + return str; +} + void mrb_mruby_string_ext_gem_init(mrb_state* mrb) { @@ -256,6 +326,10 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE()); + mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ")); + mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!")); } void |
