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
 

Reply via email to