From b521d265b1d02771500527f00704e6c9371a3c37 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 28 Dec 2009 17:35:48 +0100 Subject: [PATCH] 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. --- libguile/read.c | 34 ++++++++++++++++------------------ 1 file 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