summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-string-utf8/src/string.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-06-04 10:41:24 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-06-04 10:41:24 +0900
commite3074eff6f0088b42571baa14f6d3beffa64fb56 (patch)
treeebb9d5c1e2ecbb82d9d6d7760b5949764c19dd23 /mrbgems/mruby-string-utf8/src/string.c
parent9763eee616faff0645878d455c64a0ae23745a61 (diff)
parent6d0388c68ef1156cc33ee947f1541120e5dc5909 (diff)
downloadmruby-e3074eff6f0088b42571baa14f6d3beffa64fb56.tar.gz
mruby-e3074eff6f0088b42571baa14f6d3beffa64fb56.zip
Merge pull request #2356 from mattn/string-codepoints
Add String#chars, String#each_char, String#codepoints, String#each_codepoint
Diffstat (limited to 'mrbgems/mruby-string-utf8/src/string.c')
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c
index 1da7e3fdc..e31eca5d3 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,74 @@ 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;
+ 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
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, "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());
}