From 39af5ca254fd383dea5f4e88c404f7f79ab97432 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 9 Feb 2014 02:42:50 +0900 Subject: [PATCH] implement string-append in C --- piclib/built-in.scm | 8 -------- src/string.c | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/piclib/built-in.scm b/piclib/built-in.scm index 55ac8686..2ceec2e7 100644 --- a/piclib/built-in.scm +++ b/piclib/built-in.scm @@ -476,14 +476,6 @@ (string-copy! res 0 v start end) res))) -(define (string-append . vs) - (define (string-append-2-inv w v) - (let ((res (make-string (+ (string-length v) (string-length w))))) - (string-copy! res 0 v) - (string-copy! res (string-length v) w) - res)) - (fold string-append-2-inv #() vs)) - (define (string-fill! v fill . opts) (let ((start (if (pair? opts) (car opts) 0)) (end (if (>= (length opts) 2) diff --git a/src/string.c b/src/string.c index 1e3044fb..4d5ea02f 100644 --- a/src/string.c +++ b/src/string.c @@ -122,6 +122,29 @@ DEFINE_STRING_CMP(gt, >) DEFINE_STRING_CMP(le, <=) DEFINE_STRING_CMP(ge, >=) +static pic_value +pic_str_string_append(pic_state *pic) +{ + size_t argc, len, i; + pic_value *argv; + char *buf; + + pic_get_args(pic, "*", &argc, &argv); + + len = 0; + buf = NULL; + for (i = 0; i < argc; ++i) { + if (! pic_str_p(argv[i])) { + pic_error(pic, "type error"); + } + buf = pic_realloc(pic, buf, len + pic_str_ptr(argv[i])->len); + /* copy! */ + memcpy(buf + len, pic_str_ptr(argv[i])->str, pic_str_ptr(argv[i])->len); + len += pic_str_ptr(argv[i])->len; + } + return pic_obj_value(pic_str_new(pic, buf, len)); +} + void pic_init_str(pic_state *pic) { @@ -135,4 +158,5 @@ pic_init_str(pic_state *pic) pic_defun(pic, "string>?", pic_str_string_gt); pic_defun(pic, "string<=?", pic_str_string_le); pic_defun(pic, "string>=?", pic_str_string_ge); + pic_defun(pic, "string-append", pic_str_string_append); }