Commit e3074eff authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #2356 from mattn/string-codepoints

Add String#chars, String#each_char, String#codepoints, String#each_codepoint
parents 9763eee6 6d0388c6
#include "mruby.h" #include "mruby.h"
#include "mruby/array.h" #include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/string.h" #include "mruby/string.h"
#include "mruby/range.h" #include "mruby/range.h"
#include "mruby/re.h" #include "mruby/re.h"
...@@ -671,6 +672,74 @@ mrb_str_chr(mrb_state *mrb, mrb_value self) ...@@ -671,6 +672,74 @@ mrb_str_chr(mrb_state *mrb, mrb_value self)
return str_substr(mrb, self, 0, 1); return str_substr(mrb, self, 0, 1);
} }
static mrb_value
mrb_str_chars(mrb_state *mrb, mrb_value self)
{
mrb_value result;
mrb_value blk;
int ai;
mrb_int len;
mrb_value arg;
char *p = RSTRING_PTR(self);
char *e = p + RSTRING_LEN(self);
mrb_get_args(mrb, "&", &blk);
result = mrb_ary_new(mrb);
if (!mrb_nil_p(blk)) {
while (p < e) {
len = utf8len((unsigned char*) p);
arg = mrb_str_new(mrb, p, len);
mrb_yield_argv(mrb, blk, 1, &arg);
p += len;
}
return self;
}
while (p < e) {
ai = mrb_gc_arena_save(mrb);
len = utf8len((unsigned char*) p);
mrb_ary_push(mrb, result, mrb_str_new(mrb, p, len));
mrb_gc_arena_restore(mrb, ai);
p += len;
}
return result;
}
static mrb_value
mrb_str_codepoints(mrb_state *mrb, mrb_value self)
{
mrb_value result;
mrb_value blk;
int ai;
mrb_int len;
mrb_value arg;
char *p = RSTRING_PTR(self);
char *e = p + RSTRING_LEN(self);
mrb_get_args(mrb, "&", &blk);
result = mrb_ary_new(mrb);
if (!mrb_nil_p(blk)) {
while (p < e) {
len = utf8len((unsigned char*) p);
arg = mrb_fixnum_value(utf8code((unsigned char*) p));
mrb_yield_argv(mrb, blk, 1, &arg);
p += len;
}
return self;
}
while (p < e) {
ai = mrb_gc_arena_save(mrb);
len = utf8len((unsigned char*) p);
mrb_ary_push(mrb, result, mrb_fixnum_value(utf8code((unsigned char*) p)));
mrb_gc_arena_restore(mrb, ai);
p += len;
}
return result;
}
void void
mrb_mruby_string_utf8_gem_init(mrb_state* mrb) mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
{ {
...@@ -687,6 +756,10 @@ mrb_mruby_string_utf8_gem_init(mrb_state* mrb) ...@@ -687,6 +756,10 @@ mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY()); mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY());
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, "chars", mrb_str_chars, MRB_ARGS_NONE());
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "each_char"), mrb_intern_lit(mrb, "chars"));
mrb_define_method(mrb, s, "codepoints", mrb_str_codepoints, MRB_ARGS_NONE());
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "each_codepoint"), mrb_intern_lit(mrb, "codepoints"));
mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
} }
......
...@@ -70,3 +70,40 @@ end ...@@ -70,3 +70,40 @@ end
assert('String#chr(utf-8)') do assert('String#chr(utf-8)') do
assert_equal "こ", "こんにちは世界!".chr assert_equal "こ", "こんにちは世界!".chr
end end
assert('String#chars') do
expect = ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']
assert_equal expect, "こんにちは世界!".chars
s = ""
"こんにちは世界!".chars do |x|
s += x
end
assert_equal "こんにちは世界!", s
end
assert('String#each_char') do
expect = ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']
s = ""
"こんにちは世界!".each_char do |x|
s += x
end
assert_equal "こんにちは世界!", s
end
assert('String#codepoints') do
expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
assert_equal expect, "こんにちは世界!".codepoints
cp = []
"こんにちは世界!".codepoints do |x|
cp << x
end
assert_equal expect, cp
end
assert('String#each_codepoint') do
expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
cp = []
"こんにちは世界!".each_codepoint do |x|
cp << x
end
assert_equal expect, cp
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