summaryrefslogtreecommitdiff
path: root/libguile/read.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2009-12-28 17:35:48 +0100
committerAndy Wingo <wingo@pobox.com>2009-12-28 17:35:48 +0100
commitb521d265b1d02771500527f00704e6c9371a3c37 (patch)
tree609394dc97fc8a2d0029bc21f6b6f25ec2a44651 /libguile/read.c
parent8b0d7b9d94b9f142dc4f08ce12b345321359b3cd (diff)
downloadguile-b521d265b1d02771500527f00704e6c9371a3c37.tar.gz
Fix bugs reading long tokens
The commit "don't take string-write mutex in read.c:read_token", from 8b0d7b9d94b9f142dc4f08ce12b345321359b3cd, had a number of bugs. Not sure how I missed these before. * libguile/read.c (read_token): Remove a couple of bogus scm_i_string_stop_writing () calls, now that we no longer take the string-write mutex. (read_complete_token): read_token really needs a fresh buffer, which was not the case when we are reading long tokens and thus hit the overflow case. Fixes fractions.test.
Diffstat (limited to 'libguile/read.c')
-rw-r--r--libguile/read.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/libguile/read.c b/libguile/read.c
index da4a17433..dedfed2fe 100644
--- a/libguile/read.c
+++ b/libguile/read.c
@@ -200,16 +200,12 @@ read_token (SCM port, SCM buf, size_t *read)
chr = scm_getc (port);
if (chr == EOF)
- {
- scm_i_string_stop_writing ();
- return 0;
- }
+ return 0;
chr = (SCM_CASE_INSENSITIVE_P ? uc_tolower (chr) : chr);
if (CHAR_IS_DELIMITER (chr))
{
- scm_i_string_stop_writing ();
scm_ungetc (chr, port);
return 0;
}
@@ -224,25 +220,27 @@ read_token (SCM port, SCM buf, size_t *read)
static SCM
read_complete_token (SCM port, size_t *read)
{
- SCM buffer, str = SCM_EOL;
- size_t len;
+ SCM buffer;
int overflow;
+ size_t overflow_read;
+ SCM tail = SCM_EOL;
buffer = scm_i_make_string (READER_BUFFER_SIZE, NULL);
overflow = read_token (port, buffer, read);
- if (!overflow)
- return scm_i_substring (buffer, 0, *read);
-
- str = scm_string_copy (buffer);
- do
- {
- overflow = read_token (port, buffer, &len);
- str = scm_string_append (scm_list_2 (str, buffer));
- *read += len;
+ while (overflow)
+ {
+ tail = scm_cons (buffer, tail);
+ buffer = scm_i_make_string (READER_BUFFER_SIZE, NULL);
+ overflow = read_token (port, buffer, &overflow_read);
+ *read += overflow_read;
}
- while (overflow);
- return scm_i_substring (str, 0, *read);
+ if (scm_is_null (tail))
+ return scm_i_substring (buffer, 0, *read);
+ else
+ return scm_string_append
+ (scm_reverse (scm_cons (scm_i_substring (buffer, 0, overflow_read),
+ tail)));
}
/* Skip whitespace from PORT and return the first non-whitespace character