From f18771eb4246547643c437572dd646aa21b728e8 Mon Sep 17 00:00:00 2001 From: mattn Date: Wed, 4 Jun 2014 10:10:58 +0900 Subject: Add String#chars, String#each_char, String#codepoints, String#each_codepoint --- mrbgems/mruby-string-utf8/src/string.c | 65 ++++++++++++++++++++++++++++++++ mrbgems/mruby-string-utf8/test/string.rb | 37 ++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index 1da7e3fdc..c8934d241 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -1,5 +1,6 @@ #include "mruby.h" #include "mruby/array.h" +#include "mruby/class.h" #include "mruby/string.h" #include "mruby/range.h" #include "mruby/re.h" @@ -671,6 +672,66 @@ mrb_str_chr(mrb_state *mrb, mrb_value self) 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; + 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)) { + mrb_value arg; + while (p < e) { + mrb_int 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) { + mrb_int len = utf8len((unsigned char*) p); + mrb_ary_push(mrb, result, mrb_str_new(mrb, p, len)); + p += len; + } + return result; +} + +static mrb_value +mrb_str_codepoints(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + mrb_value blk; + 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)) { + mrb_value arg; + while (p < e) { + mrb_int 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) { + mrb_int len = utf8len((unsigned char*) p); + mrb_ary_push(mrb, result, mrb_fixnum_value(utf8code((unsigned char*) p))); + p += len; + } + return result; +} + void mrb_mruby_string_utf8_gem_init(mrb_state* mrb) { @@ -687,6 +748,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, "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, "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()); } diff --git a/mrbgems/mruby-string-utf8/test/string.rb b/mrbgems/mruby-string-utf8/test/string.rb index ad864410a..34f47e1cd 100644 --- a/mrbgems/mruby-string-utf8/test/string.rb +++ b/mrbgems/mruby-string-utf8/test/string.rb @@ -70,3 +70,40 @@ end assert('String#chr') do assert_equal "こ", "こんにちは世界!".chr 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 -- cgit v1.2.3 From 5410b9c46c53cc5f5f59a67aaefcf3d639baa63d Mon Sep 17 00:00:00 2001 From: mattn Date: Wed, 4 Jun 2014 10:20:51 +0900 Subject: arena save/restore --- mrbgems/mruby-string-utf8/src/string.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index c8934d241..e47d6a725 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -695,8 +695,10 @@ mrb_str_chars(mrb_state *mrb, mrb_value self) return self; } while (p < e) { + int ai = mrb_gc_arena_save(mrb); mrb_int 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; @@ -725,8 +727,10 @@ mrb_str_codepoints(mrb_state *mrb, mrb_value self) return self; } while (p < e) { + int ai = mrb_gc_arena_save(mrb); mrb_int 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; -- cgit v1.2.3 From 6d0388c68ef1156cc33ee947f1541120e5dc5909 Mon Sep 17 00:00:00 2001 From: mattn Date: Wed, 4 Jun 2014 10:28:34 +0900 Subject: Refactor variable definitions --- mrbgems/mruby-string-utf8/src/string.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index e47d6a725..e31eca5d3 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -677,6 +677,9 @@ 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); @@ -685,9 +688,8 @@ mrb_str_chars(mrb_state *mrb, mrb_value self) result = mrb_ary_new(mrb); if (!mrb_nil_p(blk)) { - mrb_value arg; while (p < e) { - mrb_int len = utf8len((unsigned char*) p); + len = utf8len((unsigned char*) p); arg = mrb_str_new(mrb, p, len); mrb_yield_argv(mrb, blk, 1, &arg); p += len; @@ -695,8 +697,8 @@ mrb_str_chars(mrb_state *mrb, mrb_value self) return self; } while (p < e) { - int ai = mrb_gc_arena_save(mrb); - mrb_int len = utf8len((unsigned char*) p); + 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; @@ -709,6 +711,9 @@ 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); @@ -717,9 +722,8 @@ mrb_str_codepoints(mrb_state *mrb, mrb_value self) result = mrb_ary_new(mrb); if (!mrb_nil_p(blk)) { - mrb_value arg; while (p < e) { - mrb_int len = utf8len((unsigned char*) p); + len = utf8len((unsigned char*) p); arg = mrb_fixnum_value(utf8code((unsigned char*) p)); mrb_yield_argv(mrb, blk, 1, &arg); p += len; @@ -727,8 +731,8 @@ mrb_str_codepoints(mrb_state *mrb, mrb_value self) return self; } while (p < e) { - int ai = mrb_gc_arena_save(mrb); - mrb_int len = utf8len((unsigned char*) p); + 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; -- cgit v1.2.3