summaryrefslogtreecommitdiff
path: root/libguile/strports.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2016-04-04 11:28:28 +0200
committerAndy Wingo <wingo@pobox.com>2016-04-04 16:30:57 +0200
commitb77fb752dd7e14876741ecb6360ef0319eae18e0 (patch)
treec8c54b604d9f77f2634b0307bbf52dbccc9af39a /libguile/strports.c
parentb7e49a75a9f0c4f992c212e9f61de164dbaa66ec (diff)
downloadguile-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.c88
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;
}