mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'string-succ' of https://github.com/mattn/mruby into mattn-string-succ
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -251,3 +251,113 @@ assert('String#slice!') do
|
||||
|
||||
assert_raise(ArgumentError) { "foo".slice! }
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user