summaryrefslogtreecommitdiffhomepage
path: root/src/string.c
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-05-31 16:34:57 +0900
committerYukihiro Matsumoto <[email protected]>2012-05-31 16:34:57 +0900
commit3055a3bc8c82a27c72f0fdf9fc2c52b385c37a16 (patch)
tree9d953c7fb393d25735e705bbbd07bc1e5fdffd72 /src/string.c
parent5450f925dab709efd426f1b7af9e4947077aef42 (diff)
downloadmruby-3055a3bc8c82a27c72f0fdf9fc2c52b385c37a16.tar.gz
mruby-3055a3bc8c82a27c72f0fdf9fc2c52b385c37a16.zip
reimplement String#*
Diffstat (limited to 'src/string.c')
-rw-r--r--src/string.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/string.c b/src/string.c
index 774277d20..a42565084 100644
--- a/src/string.c
+++ b/src/string.c
@@ -402,7 +402,33 @@ mrb_str_size(mrb_state *mrb, mrb_value self)
static mrb_value
mrb_str_times(mrb_state *mrb, mrb_value self)
{
- return mrb_nil_value();
+ mrb_value str2;
+ mrb_int n,len,times;
+ char *ptr2;
+
+ mrb_get_args(mrb, "i", &times);
+ if (times < 0) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
+ }
+ if (times && INT32_MAX/times < RSTRING_LEN(self)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
+ }
+
+ len = RSTRING_LEN(self)*times;
+ str2 = mrb_str_new_with_class(mrb, self, 0, len);
+ ptr2 = RSTRING_PTR(str2);
+ if (len > 0) {
+ n = RSTRING_LEN(self);
+ memcpy(ptr2, RSTRING_PTR(self), n);
+ while (n <= len/2) {
+ memcpy(ptr2 + n, ptr2, n);
+ n *= 2;
+ }
+ memcpy(ptr2 + n, ptr2, len-n);
+ }
+ ptr2[RSTRING_LEN(str2)] = '\0';
+
+ return str2;
}
/* -------------------------------------------------------------- */