Commit 04962ca0 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #2357 from mattn/string-lines

Add String#lines
parents e3074eff c9272774
#include <ctype.h>
#include <string.h>
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/string.h"
static mrb_value
......@@ -190,6 +192,53 @@ mrb_str_chr(mrb_state *mrb, mrb_value self)
return mrb_str_substr(mrb, self, 0, 1);
}
/*
* call-seq:
* string.lines -> array of string
*
* Returns strings per line;
*
* a = "abc\ndef"
* a.lines #=> ["abc", "def"]
*/
static mrb_value
mrb_str_lines(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), *t;
char *e = p + RSTRING_LEN(self);
mrb_get_args(mrb, "&", &blk);
result = mrb_ary_new(mrb);
if (!mrb_nil_p(blk)) {
while (p < e) {
t = p;
while (p < e && *p != '\n') p++;
if (*p == '\n') p++;
len = (mrb_int) (p - t);
arg = mrb_str_new(mrb, t, len);
mrb_yield_argv(mrb, blk, 1, &arg);
}
return self;
}
while (p < e) {
ai = mrb_gc_arena_save(mrb);
t = p;
while (p < e && *p != '\n') p++;
if (*p == '\n') p++;
len = (mrb_int) (p - t);
mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
mrb_gc_arena_restore(mrb, ai);
}
return result;
}
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
......@@ -206,6 +255,7 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "hex", mrb_str_hex, MRB_ARGS_NONE());
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());
}
void
......
......@@ -165,3 +165,10 @@ end
assert('String#chr') do
assert_equal "a", "abcde".chr
end
assert('String#lines') do
assert_equal ["こん\n", "にちは\n", "世界!"], "こん\nにちは\n世界!".lines
assert_equal ["こん\n", "にちは\n", "世界!\n"], "こん\nにちは\n世界!\n".lines
assert_equal ["\n", "\n", "\n"], "\n\n\n".lines
assert_equal [], "".lines
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