diff options
author | Andy Wingo <wingo@pobox.com> | 2016-04-04 11:28:28 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-04-04 16:30:57 +0200 |
commit | b77fb752dd7e14876741ecb6360ef0319eae18e0 (patch) | |
tree | c8c54b604d9f77f2634b0307bbf52dbccc9af39a /libguile/strports.c | |
parent | b7e49a75a9f0c4f992c212e9f61de164dbaa66ec (diff) | |
download | guile-b77fb752dd7e14876741ecb6360ef0319eae18e0.tar.gz |
Flush buffered reads / writes before seeking
* libguile/ports.c (scm_seek): Flush before seeking on a buffered port.
* libguile/fports.c (fport_seek):
* libguile/strports.c (st_seek): Remove code to flush buffers.
* test-suite/tests/ports.test: Update test expectations that the
putback buffer is flushed on a seek. Previously there was a special
case for SEEK_CUR with an offset of 0 to avoid flushing buffers, but
that's an arbitrary choice that differs from all other combinations of
OFFSET and WHENCE.
Diffstat (limited to 'libguile/strports.c')
-rw-r--r-- | libguile/strports.c | 88 |
1 files changed, 34 insertions, 54 deletions
diff --git a/libguile/strports.c b/libguile/strports.c index 6c65ec86c..064e2f04a 100644 --- a/libguile/strports.c +++ b/libguile/strports.c @@ -162,64 +162,44 @@ st_seek (SCM port, scm_t_off offset, int whence) scm_t_port *pt = SCM_PTAB_ENTRY (port); scm_t_off target; - if (pt->rw_active == SCM_PORT_READ && offset == 0 && whence == SEEK_CUR) - /* special case to avoid disturbing the unread-char buffer. */ + switch (whence) { - if (pt->read_buf == pt->putback_buf) - { - target = pt->saved_read_pos - pt->saved_read_buf - - (pt->read_end - pt->read_pos); - } - else - { - target = pt->read_pos - pt->read_buf; - } + case SEEK_CUR: + target = pt->read_pos - pt->read_buf + offset; + break; + case SEEK_END: + target = pt->read_end - pt->read_buf + offset; + break; + default: /* SEEK_SET */ + target = offset; + break; } - else - /* all other cases. */ - { - if (pt->rw_active == SCM_PORT_READ) - scm_end_input_unlocked (port); - - pt->rw_active = SCM_PORT_NEITHER; - - switch (whence) - { - case SEEK_CUR: - target = pt->read_pos - pt->read_buf + offset; - break; - case SEEK_END: - target = pt->read_end - pt->read_buf + offset; - break; - default: /* SEEK_SET */ - target = offset; - break; - } - - if (target < 0) - scm_misc_error ("st_seek", "negative offset", SCM_EOL); + + if (target < 0) + scm_misc_error ("st_seek", "negative offset", SCM_EOL); - if (target >= pt->write_buf_size) - { - if (!(SCM_CELL_WORD_0 (port) & SCM_WRTNG)) - { - if (target > pt->write_buf_size) - { - scm_misc_error ("st_seek", - "seek past end of read-only strport", - SCM_EOL); - } - } - else if (target == pt->write_buf_size) - st_resize_port (pt, target * 2); - } - pt->read_pos = pt->write_pos = pt->read_buf + target; - if (pt->read_pos > pt->read_end) - { - pt->read_end = (unsigned char *) pt->read_pos; - pt->read_buf_size = pt->read_end - pt->read_buf; - } + if (target >= pt->write_buf_size) + { + if (!(SCM_CELL_WORD_0 (port) & SCM_WRTNG)) + { + if (target > pt->write_buf_size) + { + scm_misc_error ("st_seek", + "seek past end of read-only strport", + SCM_EOL); + } + } + else if (target == pt->write_buf_size) + st_resize_port (pt, target * 2); + } + + pt->read_pos = pt->write_pos = pt->read_buf + target; + if (pt->read_pos > pt->read_end) + { + pt->read_end = (unsigned char *) pt->read_pos; + pt->read_buf_size = pt->read_end - pt->read_buf; } + return target; } |