summaryrefslogtreecommitdiff
path: root/libguile/srfi-13.c
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2012-01-08 20:02:09 -0500
committerMark H Weaver <mhw@netris.org>2012-01-08 20:10:11 -0500
commitb2fb40a90358fcc5264a4a2fe8c7d24d3d7db2a2 (patch)
tree42cc2cc02b33be878bc10d9e6b1cc6e853904363 /libguile/srfi-13.c
parentc60e6ed4b855cb451b45fbba7e19e714d20be466 (diff)
downloadguile-b2fb40a90358fcc5264a4a2fe8c7d24d3d7db2a2.tar.gz
Avoid calling scm_i_string_start_writing if no chars will be mutated
* libguile/srfi-13.c (scm_string_copy_x, scm_substring_fill_x, string_upcase_x, string_downcase_x, string_titlecase_x, string_reverse_x, scm_string_xcopy_x): Avoid calling `scm_i_string_start_writing' if the range of indices to be modified is empty. This avoids the error that would be raised by `scm_i_string_start_writing' if the string is not mutable. Thanks to Bruce Korb <bkorb@gnu.org> for reporting this problem and suggesting the fix.
Diffstat (limited to 'libguile/srfi-13.c')
-rw-r--r--libguile/srfi-13.c170
1 files changed, 95 insertions, 75 deletions
diff --git a/libguile/srfi-13.c b/libguile/srfi-13.c
index 5bba81c7f..92d4a9d70 100644
--- a/libguile/srfi-13.c
+++ b/libguile/srfi-13.c
@@ -546,17 +546,20 @@ SCM_DEFINE (scm_string_copy_x, "string-copy!", 3, 2, 0,
MY_VALIDATE_SUBSTRING_SPEC (3, s,
4, start, cstart,
5, end, cend);
- len = cend - cstart;
- SCM_ASSERT_RANGE (3, s, len <= scm_i_string_length (target) - ctstart);
-
- target = scm_i_string_start_writing (target);
- for (i = 0; i < cend - cstart; i++)
+ if (cstart < cend)
{
- scm_i_string_set_x (target, ctstart + i,
- scm_i_string_ref (s, cstart + i));
+ len = cend - cstart;
+ SCM_ASSERT_RANGE (3, s, len <= scm_i_string_length (target) - ctstart);
+
+ target = scm_i_string_start_writing (target);
+ for (i = 0; i < cend - cstart; i++)
+ {
+ scm_i_string_set_x (target, ctstart + i,
+ scm_i_string_ref (s, cstart + i));
+ }
+ scm_i_string_stop_writing ();
+ scm_remember_upto_here_1 (target);
}
- scm_i_string_stop_writing ();
- scm_remember_upto_here_1 (target);
return SCM_UNSPECIFIED;
}
@@ -970,11 +973,13 @@ SCM_DEFINE (scm_substring_fill_x, "string-fill!", 2, 2, 0,
4, end, cend);
SCM_VALIDATE_CHAR (2, chr);
-
- str = scm_i_string_start_writing (str);
- for (k = cstart; k < cend; k++)
- scm_i_string_set_x (str, k, SCM_CHAR (chr));
- scm_i_string_stop_writing ();
+ if (cstart < cend)
+ {
+ str = scm_i_string_start_writing (str);
+ for (k = cstart; k < cend; k++)
+ scm_i_string_set_x (str, k, SCM_CHAR (chr));
+ scm_i_string_stop_writing ();
+ }
return SCM_UNSPECIFIED;
}
@@ -2089,11 +2094,14 @@ string_upcase_x (SCM v, size_t start, size_t end)
{
size_t k;
- v = scm_i_string_start_writing (v);
- for (k = start; k < end; ++k)
- scm_i_string_set_x (v, k, uc_toupper (scm_i_string_ref (v, k)));
- scm_i_string_stop_writing ();
- scm_remember_upto_here_1 (v);
+ if (start < end)
+ {
+ v = scm_i_string_start_writing (v);
+ for (k = start; k < end; ++k)
+ scm_i_string_set_x (v, k, uc_toupper (scm_i_string_ref (v, k)));
+ scm_i_string_stop_writing ();
+ scm_remember_upto_here_1 (v);
+ }
return v;
}
@@ -2152,11 +2160,14 @@ string_downcase_x (SCM v, size_t start, size_t end)
{
size_t k;
- v = scm_i_string_start_writing (v);
- for (k = start; k < end; ++k)
- scm_i_string_set_x (v, k, uc_tolower (scm_i_string_ref (v, k)));
- scm_i_string_stop_writing ();
- scm_remember_upto_here_1 (v);
+ if (start < end)
+ {
+ v = scm_i_string_start_writing (v);
+ for (k = start; k < end; ++k)
+ scm_i_string_set_x (v, k, uc_tolower (scm_i_string_ref (v, k)));
+ scm_i_string_stop_writing ();
+ scm_remember_upto_here_1 (v);
+ }
return v;
}
@@ -2219,27 +2230,30 @@ string_titlecase_x (SCM str, size_t start, size_t end)
size_t i;
int in_word = 0;
- str = scm_i_string_start_writing (str);
- for(i = start; i < end; i++)
+ if (start < end)
{
- ch = SCM_MAKE_CHAR (scm_i_string_ref (str, i));
- if (scm_is_true (scm_char_alphabetic_p (ch)))
- {
- if (!in_word)
- {
- scm_i_string_set_x (str, i, uc_totitle (SCM_CHAR (ch)));
- in_word = 1;
- }
- else
- {
- scm_i_string_set_x (str, i, uc_tolower (SCM_CHAR (ch)));
- }
- }
- else
- in_word = 0;
+ str = scm_i_string_start_writing (str);
+ for(i = start; i < end; i++)
+ {
+ ch = SCM_MAKE_CHAR (scm_i_string_ref (str, i));
+ if (scm_is_true (scm_char_alphabetic_p (ch)))
+ {
+ if (!in_word)
+ {
+ scm_i_string_set_x (str, i, uc_totitle (SCM_CHAR (ch)));
+ in_word = 1;
+ }
+ else
+ {
+ scm_i_string_set_x (str, i, uc_tolower (SCM_CHAR (ch)));
+ }
+ }
+ else
+ in_word = 0;
+ }
+ scm_i_string_stop_writing ();
+ scm_remember_upto_here_1 (str);
}
- scm_i_string_stop_writing ();
- scm_remember_upto_here_1 (str);
return str;
}
@@ -2309,22 +2323,25 @@ SCM_DEFINE (scm_string_capitalize, "string-capitalize", 1, 0, 0,
static void
string_reverse_x (SCM str, size_t cstart, size_t cend)
{
- SCM tmp;
-
- str = scm_i_string_start_writing (str);
- if (cend > 0)
+ if (cstart < cend)
{
- cend--;
- while (cstart < cend)
- {
- tmp = SCM_MAKE_CHAR (scm_i_string_ref (str, cstart));
- scm_i_string_set_x (str, cstart, scm_i_string_ref (str, cend));
- scm_i_string_set_x (str, cend, SCM_CHAR (tmp));
- cstart++;
- cend--;
- }
+ str = scm_i_string_start_writing (str);
+ if (cend > 0)
+ {
+ SCM tmp;
+
+ cend--;
+ while (cstart < cend)
+ {
+ tmp = SCM_MAKE_CHAR (scm_i_string_ref (str, cstart));
+ scm_i_string_set_x (str, cstart, scm_i_string_ref (str, cend));
+ scm_i_string_set_x (str, cend, SCM_CHAR (tmp));
+ cstart++;
+ cend--;
+ }
+ }
+ scm_i_string_stop_writing ();
}
- scm_i_string_stop_writing ();
}
@@ -2866,26 +2883,29 @@ SCM_DEFINE (scm_string_xcopy_x, "string-xcopy!", 4, 3, 0,
csto = csfrom + (cend - cstart);
else
csto = scm_to_int (sto);
- if (cstart == cend && csfrom != csto)
- SCM_MISC_ERROR ("start and end indices must not be equal", SCM_EOL);
- SCM_ASSERT_RANGE (1, tstart,
- ctstart + (csto - csfrom) <= scm_i_string_length (target));
-
- p = 0;
- target = scm_i_string_start_writing (target);
- while (csfrom < csto)
+ if (csfrom < csto)
{
- size_t t = ((csfrom < 0) ? -csfrom : csfrom) % (cend - cstart);
- if (csfrom < 0)
- scm_i_string_set_x (target, p + cstart, scm_i_string_ref (s, (cend - cstart) - t));
- else
- scm_i_string_set_x (target, p + cstart, scm_i_string_ref (s, t));
- csfrom++;
- p++;
- }
- scm_i_string_stop_writing ();
+ if (cstart == cend)
+ SCM_MISC_ERROR ("start and end indices must not be equal", SCM_EOL);
+ SCM_ASSERT_RANGE (1, tstart,
+ ctstart + (csto - csfrom) <= scm_i_string_length (target));
+
+ p = 0;
+ target = scm_i_string_start_writing (target);
+ while (csfrom < csto)
+ {
+ size_t t = ((csfrom < 0) ? -csfrom : csfrom) % (cend - cstart);
+ if (csfrom < 0)
+ scm_i_string_set_x (target, p + cstart, scm_i_string_ref (s, (cend - cstart) - t));
+ else
+ scm_i_string_set_x (target, p + cstart, scm_i_string_ref (s, t));
+ csfrom++;
+ p++;
+ }
+ scm_i_string_stop_writing ();
- scm_remember_upto_here_2 (target, s);
+ scm_remember_upto_here_2 (target, s);
+ }
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME