diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 687daefb..369e3b65 100644 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -810,7 +810,7 @@ SEXP_API sexp sexp_length(sexp ctx, sexp ls); SEXP_API sexp sexp_c_string(sexp ctx, char *str, sexp_sint_t slen); SEXP_API sexp sexp_make_string(sexp ctx, sexp len, sexp ch); SEXP_API sexp sexp_substring (sexp ctx, sexp str, sexp start, sexp end); -SEXP_API sexp sexp_string_concatenate (sexp ctx, sexp str_ls); +SEXP_API sexp sexp_string_concatenate (sexp ctx, sexp str_ls, sexp sep); SEXP_API sexp sexp_intern(sexp ctx, char *str); SEXP_API sexp sexp_string_to_symbol(sexp ctx, sexp str); SEXP_API sexp sexp_make_vector(sexp ctx, sexp len, sexp dflt); diff --git a/opcodes.c b/opcodes.c index d3c77865..85a35afc 100644 --- a/opcodes.c +++ b/opcodes.c @@ -104,7 +104,7 @@ _FN2OPT(SEXP_FIXNUM, SEXP_CHAR, "make-string", sexp_make_character(' '), sexp_ma _FN3(SEXP_STRING, SEXP_STRING, "string-cmp", 0, sexp_string_cmp), _FN3(SEXP_STRING, SEXP_FIXNUM, "substring", 0, sexp_substring), _FN1(SEXP_STRING, "string->symbol", 0, sexp_string_to_symbol), -_FN1(SEXP_PAIR, "string-concatenate", 0, sexp_string_concatenate), +_FN2OPT(SEXP_PAIR, SEXP_STRING, "string-concatenate", SEXP_FALSE, sexp_string_concatenate), _FN2(0, SEXP_PAIR, "memq", 0, sexp_memq), _FN2(0, SEXP_PAIR, "assq", 0, sexp_assq), _FN3(SEXP_ENV, SEXP_PAIR, "make-syntactic-closure", 0, sexp_make_synclo), diff --git a/sexp.c b/sexp.c index 221e674d..2a3ff0f6 100644 --- a/sexp.c +++ b/sexp.c @@ -646,21 +646,29 @@ sexp sexp_substring (sexp ctx, sexp str, sexp start, sexp end) { return res; } -sexp sexp_string_concatenate (sexp ctx, sexp str_ls) { +sexp sexp_string_concatenate (sexp ctx, sexp str_ls, sexp sep) { sexp res, ls; - sexp_uint_t len=0; - char *p; - for (ls=str_ls; sexp_pairp(ls); ls=sexp_cdr(ls)) + sexp_uint_t len=0, i=0, sep_len=0; + char *p, *csep; + for (ls=str_ls; sexp_pairp(ls); ls=sexp_cdr(ls), i++) if (! sexp_stringp(sexp_car(ls))) return sexp_type_exception(ctx, "not a string", sexp_car(ls)); else len += sexp_string_length(sexp_car(ls)); + if (sexp_stringp(sep) && ((sep_len=sexp_string_length(sep)) > 0)) { + csep = sexp_string_data(sep); + len += sep_len*(i-1); + } res = sexp_make_string(ctx, sexp_make_fixnum(len), SEXP_VOID); p = sexp_string_data(res); for (ls=str_ls; sexp_pairp(ls); ls=sexp_cdr(ls)) { len = sexp_string_length(sexp_car(ls)); memcpy(p, sexp_string_data(sexp_car(ls)), len); p += len; + if (sep_len && sexp_pairp(sexp_cdr(ls))) { + memcpy(p, csep, sep_len); + p += sep_len; + } } *p = '\0'; return res; @@ -990,7 +998,7 @@ sexp sexp_get_output_string (sexp ctx, sexp out) { } else { ls = sexp_port_cookie(out); } - res = sexp_string_concatenate(ctx, ls); + res = sexp_string_concatenate(ctx, ls, SEXP_FALSE); sexp_gc_release2(ctx); return res; }