Commit 0381de3e authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge branch 'string-succ' of https://github.com/mattn/mruby into mattn-string-succ

parents b54682bb dc0c3546
...@@ -239,6 +239,76 @@ mrb_str_lines(mrb_state *mrb, mrb_value self) ...@@ -239,6 +239,76 @@ mrb_str_lines(mrb_state *mrb, mrb_value self)
return result; 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 void
mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{ {
...@@ -256,6 +326,10 @@ 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, "oct", mrb_str_oct, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "chr", mrb_str_chr, 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, "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 void
......
...@@ -251,3 +251,113 @@ assert('String#slice!') do ...@@ -251,3 +251,113 @@ assert('String#slice!') do
assert_raise(ArgumentError) { "foo".slice! } assert_raise(ArgumentError) { "foo".slice! }
end end
assert('String#succ') do
assert_equal "", "".succ
assert_equal "1", "0".succ
assert_equal "10", "9".succ
assert_equal "01", "00".succ
assert_equal "a1", "a0".succ
assert_equal "A1", "A0".succ
assert_equal "10", "09".succ
assert_equal "b0", "a9".succ
assert_equal "B0", "A9".succ
assert_equal "b", "a".succ
assert_equal "aa", "z".succ
assert_equal "ab", "aa".succ
assert_equal "Ab", "Aa".succ
assert_equal "0b", "0a".succ
assert_equal "ba", "az".succ
assert_equal "Ba", "Az".succ
assert_equal "1a", "0z".succ
assert_equal "B", "A".succ
assert_equal "AA", "Z".succ
assert_equal "AB", "AA".succ
assert_equal "aB", "aA".succ
assert_equal "0B", "0A".succ
assert_equal "BA", "AZ".succ
assert_equal "bA", "aZ".succ
assert_equal "1A", "0Z".succ
assert_equal "-", "-".succ
assert_equal "-b", "-a".succ
assert_equal "-aa", "-z".succ
assert_equal "あ", "あ".succ
assert_equal "あb", "あa".succ
assert_equal "あba", "あaz".succ
a = ""; a.succ!
assert_equal "", a
a = "0"; a.succ!
assert_equal "1", a
a = "9"; a.succ!
assert_equal "10", a
a = "00"; a.succ!
assert_equal "01", a
a = "a0"; a.succ!
assert_equal "a1", a
a = "A0"; a.succ!
assert_equal "A1", a
a = "09"; a.succ!
assert_equal "10", a
a = "a9"; a.succ!
assert_equal "b0", a
a = "A9"; a.succ!
assert_equal "B0", a
a = "a"; a.succ!
assert_equal "b", a
a = "z"; a.succ!
assert_equal "aa", a
a = "aa"; a.succ!
assert_equal "ab", a
a = "Aa"; a.succ!
assert_equal "Ab", a
a = "0a"; a.succ!
assert_equal "0b", a
a = "az"; a.succ!
assert_equal "ba", a
a = "Az"; a.succ!
assert_equal "Ba", a
a = "0z"; a.succ!
assert_equal "1a", a
a = "A"; a.succ!
assert_equal "B", a
a = "Z"; a.succ!
assert_equal "AA", a
a = "AA"; a.succ!
assert_equal "AB", a
a = "aA"; a.succ!
assert_equal "aB", a
a = "0A"; a.succ!
assert_equal "0B", a
a = "AZ"; a.succ!
assert_equal "BA", a
a = "aZ"; a.succ!
assert_equal "bA", a
a = "0Z"; a.succ!
assert_equal "1A", a
a = "-"; a.succ!
assert_equal "-", a
a = "-a"; a.succ!
assert_equal "-b", a
a = "-z"; a.succ!
assert_equal "-aa", a
a = "あ"; a.succ!
assert_equal "あ", a
a = "あa"; a.succ!
assert_equal "あb", a
a = "あaz"; a.succ!
assert_equal "あba", a
end
assert('String#next') do
assert_equal "01", "00".next
a = "00"; a.next!
assert_equal "01", a
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment