diff options
author | Kevin Ryde <user42@zip.com.au> | 2005-11-30 00:26:08 +0000 |
---|---|---|
committer | Kevin Ryde <user42@zip.com.au> | 2005-11-30 00:26:08 +0000 |
commit | a003f3eb60b4b193a8b6d453bb07458531b49db7 (patch) | |
tree | 1a599ef68f1d6c05c01a94a5123bb04daa262a29 /libguile/srfi-13.c | |
parent | 606183ba1bc74ad453e6727ca63f6deeac6e404e (diff) | |
download | guile-a003f3eb60b4b193a8b6d453bb07458531b49db7.tar.gz |
(scm_string_append_shared): No copying if just one
non-empty string in args.
Diffstat (limited to 'libguile/srfi-13.c')
-rw-r--r-- | libguile/srfi-13.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/libguile/srfi-13.c b/libguile/srfi-13.c index a98b75546..4887b4b1f 100644 --- a/libguile/srfi-13.c +++ b/libguile/srfi-13.c @@ -2651,21 +2651,35 @@ SCM_DEFINE (scm_string_reverse_x, "string-reverse!", 1, 2, 0, SCM_DEFINE (scm_string_append_shared, "string-append/shared", 0, 0, 1, - (SCM ls), + (SCM rest), "Like @code{string-append}, but the result may share memory\n" "with the argument strings.") #define FUNC_NAME s_scm_string_append_shared { - long i; + /* If "rest" contains just one non-empty string, return that. + If it's entirely empty strings, then return scm_nullstr. + Otherwise use scm_string_concatenate. */ - SCM_VALIDATE_REST_ARGUMENT (ls); + SCM ret = scm_nullstr; + int seen_nonempty = 0; + SCM l, s; - /* Optimize the one-argument case. */ - i = scm_ilength (ls); - if (i == 1) - return SCM_CAR (ls); - else - return scm_string_append (ls); + SCM_VALIDATE_REST_ARGUMENT (rest); + + for (l = rest; scm_is_pair (l); l = SCM_CDR (l)) + { + s = SCM_CAR (l); + if (scm_c_string_length (s) != 0) + { + if (seen_nonempty) + /* two or more non-empty strings, need full concat */ + return scm_string_append (rest); + + seen_nonempty = 1; + ret = s; + } + } + return ret; } #undef FUNC_NAME |