summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c65
-rw-r--r--mrbgems/mruby-string-utf8/test/string.rb37
2 files changed, 102 insertions, 0 deletions
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