diff options
author | Andy Wingo <wingo@pobox.com> | 2009-12-28 17:35:48 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2009-12-28 17:35:48 +0100 |
commit | b521d265b1d02771500527f00704e6c9371a3c37 (patch) | |
tree | 609394dc97fc8a2d0029bc21f6b6f25ec2a44651 /libguile/read.c | |
parent | 8b0d7b9d94b9f142dc4f08ce12b345321359b3cd (diff) | |
download | guile-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.c | 34 |
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 |