On Thursday 11 December 2008 06:14:36 François PERRAD wrote:
> Since the merge of the branch ppd22io, the mode of the stdin stream has
> changed. Currently, it isn't possible to peek on stdin.
>
> $ cat peek.pir
> .sub 'main'
> $P0 = getstdin
> $S0 = peek $S0
> .end
>
> $ ./parrot peek.pir < peek.pir
> Can't peek at unbuffered I/O
>
> The issue was detected with I/O library of Lua (see
> languages/lua/t/io.t#17).
We should support this; how about upgrading the IO PMC to buffered reads when
we detect a peek? Here's a patch that makes the test pass for me. Any
objections, anyone else?
-- c
=== src/io/buffer.c
==================================================================
--- src/io/buffer.c (revision 34326)
+++ src/io/buffer.c (local)
@@ -395,14 +395,12 @@
Parrot_io_peek_buffer(PARROT_INTERP, ARGMOD(PMC *filehandle),
ARGOUT(STRING **buf))
{
- UINTVAL len = 1;
- size_t avail = 0;
-
+ unsigned char *buffer_next, *buffer_end;
+ STRING * const s = Parrot_io_make_string(interp, buf, 1);
+ UINTVAL len = 1;
+ size_t avail = 0;
INTVAL buffer_flags = Parrot_io_get_buffer_flags(interp, filehandle);
- unsigned char *buffer_next, *buffer_end;
- STRING * const s = Parrot_io_make_string(interp, buf, 1);
-
/* write buffer flush */
if (buffer_flags & PIO_BF_WRITEBUF) {
Parrot_io_flush(interp, filehandle);
@@ -419,7 +417,7 @@
/* if we have data available, copy out the next byte */
if (avail) {
ret_string:
- memcpy(s->strstart, buffer_next, len);
+ memmove(s->strstart, buffer_next, len);
s->bufused = s->strlen = len;
return len;
}
@@ -428,11 +426,13 @@
/* (re)fill the buffer */
if (! (buffer_flags & PIO_BF_READBUF)) {
size_t got;
- /* exception if we're unbuffered */
- if (Parrot_io_get_buffer_size(interp, filehandle) == 0)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
- "Can't peek at unbuffered I/O");
+ /* promote to buffered if unbuffered */
+ if (Parrot_io_get_buffer_size(interp, filehandle) == 0) {
+ Parrot_io_setbuf(interp, filehandle, 1);
+ return Parrot_io_peek_buffer(interp, filehandle, buf);
+ }
+
/* Parrot_io_fill_readbuf() can return -1, but len should be positive */
got = Parrot_io_fill_readbuf(interp, filehandle);
@@ -449,6 +449,7 @@
goto ret_string;
}
+
/*
=item C<size_t Parrot_io_readline_buffer>
=== src/io/portable.c
==================================================================
--- src/io/portable.c (revision 34326)
+++ src/io/portable.c (local)
@@ -170,7 +170,7 @@
=item C<PMC * Parrot_io_fdopen_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -204,7 +204,7 @@
=item C<INTVAL Parrot_io_close_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -245,7 +245,7 @@
=item C<static INTVAL io_is_tty_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -297,7 +297,7 @@
=item C<INTVAL Parrot_io_getblksize_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -317,7 +317,7 @@
=item C<INTVAL Parrot_io_flush_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -334,7 +334,7 @@
=item C<size_t Parrot_io_read_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -368,7 +368,7 @@
=item C<size_t Parrot_io_write_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -386,7 +386,7 @@
=item C<PIOOFF_T Parrot_io_seek_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut
@@ -413,7 +413,7 @@
=item C<PIOOFF_T Parrot_io_tell_portable>
-RT#48260: Not yet documented!!!
+RT #48260: Not yet documented!!!
=cut