Hello, currently there is no (simple) way to open a file on an other layer than the default layer. But this is necessary if we want to take advantage from the layered approach.
So i added two new functions: pio_open_with_layer and pio_fdopen_with_layer which create IO-Objects on different layers. I'm not keen on the names, but I didn't find better ones. So to test this I need another layer on which I can open files: stdio should be available on all systems. So far so good, now I can open files on with stdio and fdopen existing handles. But there are some issues: * During layer initialisation the layers want to register the handles for stdin, stdout and stderr. I went around this by conditionally only compiling the handle init if stdio is the base IO systems. Is this a good solution? * I needed many casts from PIOHANDLE to FILE * and vice versa. I'm not sure if this one fits all approach of PIOHANDLE is the right way. Maybe its better to make PIOHANDLE a union. But what to do then with the fdopen and getfd ops. It is not guaranteed that a union can be casted to an INTVAL and back. * Modifying the same file through different layers might lead to very unpredictable results. But thats already a problem with unix-handles/stdio-handles. * PIO_isatty and PIO_getblksize are macros which are coded at compile-time to some layer, and not as read, write etc go through a LayerAPI. Comments bö
? icu/source/test ? languages/befunge/befunge.pbc ? t/src/headers.t Index: include/parrot/io.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/io.h,v retrieving revision 1.49 diff -u -r1.49 io.h --- include/parrot/io.h 25 Oct 2003 05:40:08 -0000 1.49 +++ include/parrot/io.h 4 Nov 2003 14:15:32 -0000 @@ -261,7 +261,11 @@ extern INTVAL PIO_parse_open_flags(const char *flagstr); extern PMC *PIO_open(theINTERP, const char *, const char *); +extern PMC *PIO_open_with_layer(theINTERP, ParrotIOLayer *, + const char *, const char *); extern PMC *PIO_fdopen(theINTERP, PIOHANDLE, const char *); +extern PMC *PIO_fdopen_with_layer(theINTERP, ParrotIOLayer *, PIOHANDLE, + const char *); extern INTVAL PIO_close(theINTERP, PMC *); extern void PIO_flush(theINTERP, PMC *); extern INTVAL PIO_read(theINTERP, PMC *, void *, size_t); Index: io/io.c =================================================================== RCS file: /cvs/public/parrot/io/io.c,v retrieving revision 1.70 diff -u -r1.70 io.c --- io/io.c 30 Oct 2003 08:49:14 -0000 1.70 +++ io/io.c 4 Nov 2003 14:15:32 -0000 @@ -574,6 +574,25 @@ return new_io_pmc(interpreter, io); } +PMC * +PIO_open_with_layer(theINTERP, ParrotIOLayer *layer, + const char *spath, const char *sflags) +{ + ParrotIO *io; + INTVAL flags = PIO_parse_open_flags(sflags); + + io = PIO_open_down(interpreter, layer, spath, flags); + /* io could be null here but we still have to + * to create a PMC for the caller, no PMCNULL here + * as that would cause an exception upon access. + */ + if (io) { + io->stack = layer; + } + + return new_io_pmc(interpreter, io); +} + /* * Create an IO object on an existing, open file descriptor. @@ -595,6 +614,26 @@ */ if (io) { io->stack = l; + } + + return new_io_pmc(interpreter, io); +} + + +PMC * +PIO_fdopen_with_layer(theINTERP, ParrotIOLayer *layer, PIOHANDLE fd, + const char *sflags) +{ + ParrotIO *io; + INTVAL flags = PIO_parse_open_flags(sflags); + + io = PIO_fdopen_down(interpreter, layer, fd, flags); + /* io could be null here but we still have to + * to create a PMC for the caller, no PMCNULL here + * as that would cause an exception upon access. + */ + if (io) { + io->stack = layer; } return new_io_pmc(interpreter, io); Index: io/io_stdio.c =================================================================== RCS file: /cvs/public/parrot/io/io_stdio.c,v retrieving revision 1.33 diff -u -r1.33 io_stdio.c --- io/io_stdio.c 11 Oct 2003 13:15:30 -0000 1.33 +++ io/io_stdio.c 4 Nov 2003 14:15:32 -0000 @@ -19,7 +19,8 @@ #include "parrot/parrot.h" #include "io_private.h" -#ifdef PIO_OS_STDIO +extern INTVAL PIO_stdio_isatty(PIOHANDLE fd); +extern INTVAL PIO_stdio_getblksize(PIOHANDLE fd); /* Defined at bottom */ extern ParrotIOLayerAPI pio_stdio_layer_api; @@ -93,6 +94,8 @@ static INTVAL PIO_stdio_init(theINTERP, ParrotIOLayer *layer) { +#ifdef PIO_OS_STDIO + /* Only set standard handles if stdio is the OS IO */ PIO_STDIN(interpreter) = new_io_pmc(interpreter, PIO_stdio_fdopen(interpreter, layer, stdin, PIO_F_READ)); @@ -104,7 +107,7 @@ PIO_STDERR(interpreter) = new_io_pmc(interpreter, PIO_stdio_fdopen(interpreter, layer, stderr, PIO_F_WRITE)); - +#endif /* PIO_OS_STDIO */ return 0; } @@ -140,10 +143,10 @@ /* File open */ if (fptr != NULL) { - if (PIO_isatty(fptr)) + if (PIO_stdio_isatty((PIOHANDLE)fptr)) flags |= PIO_F_CONSOLE; io = PIO_new(interpreter, type, flags, 0); - io->fd = fptr; + io->fd = (PIOHANDLE)fptr; return io; } return NULL; @@ -172,9 +175,10 @@ static INTVAL PIO_stdio_close(theINTERP, ParrotIOLayer *layer, ParrotIO *io) { - if (io->fd != NULL) - fclose(io->fd); - io->fd = NULL; + FILE *fptr = (FILE*)io->fd; + if (fptr != NULL) + fclose(fptr); + io->fd = (PIOHANDLE)NULL; return 0; } @@ -198,7 +202,7 @@ static INTVAL PIO_stdio_flush(theINTERP, ParrotIOLayer *layer, ParrotIO *io) { - return fflush(io->fd); + return fflush((FILE*)io->fd); } @@ -207,14 +211,15 @@ void *buffer, size_t len) { size_t bytes; + FILE *fptr = (FILE *)io->fd; UNUSED(interpreter); UNUSED(layer); - bytes = fread(buffer, 1, len, io->fd); + bytes = fread(buffer, 1, len, fptr); if (bytes != len) { - if (feof(io->fd)) { + if (feof(fptr)) { io->flags |= PIO_F_EOF; } } @@ -230,7 +235,7 @@ UNUSED(interpreter); UNUSED(layer); - return(fwrite(buffer, 1, len, io->fd)); + return(fwrite(buffer, 1, len, (FILE*)io->fd)); } @@ -244,7 +249,7 @@ PIOOFF_T pos; errno = 0; - if ((pos = fseek(io->fd, offset, whence)) >= 0) { + if ((pos = fseek((FILE*)io->fd, offset, whence)) >= 0) { io->lpos = io->fpos; io->fpos = pos; } @@ -258,7 +263,7 @@ static PIOOFF_T PIO_stdio_tell(theINTERP, ParrotIOLayer *l, ParrotIO *io) { - return(ftell(io->fd)); + return(ftell((FILE*)io->fd)); } @@ -294,8 +299,6 @@ 0 /* no recv */ }; -#endif /* PIO_OS_STDIO */ - /* * Local variables: * c-indentation-style: bsd @@ -304,4 +307,4 @@ * End: * * vim: expandtab shiftwidth=4: -*/ + */ Index: t/src/io.t =================================================================== RCS file: /cvs/public/parrot/t/src/io.t,v retrieving revision 1.5 diff -u -r1.5 io.t --- t/src/io.t 30 Oct 2003 06:02:30 -0000 1.5 +++ t/src/io.t 4 Nov 2003 14:15:36 -0000 @@ -1,6 +1,6 @@ #! perl -w -use Parrot::Test tests => 16; +use Parrot::Test tests => 17; use Test::More; $/=undef; # slurp mode @@ -607,3 +607,30 @@ } ############################################################################### + +c_output_is(<<'CODE', <<'OUTPUT', 'stdio-layer'); +#include "parrot/parrot.h" + +extern ParrotIOLayer pio_stdio_layer; + +int main() +{ + Interp *interpreter; + PMC *io; + + interpreter = Parrot_new(); + + if ( interpreter == NULL ) return 1; + + Parrot_init(interpreter); + + io = PIO_fdopen_with_layer(interpreter, &pio_stdio_layer, + (PIOHANDLE)stdout, ">"); + PIO_puts(interpreter, io, "Hello, World\n"); + PIO_flush(interpreter, io); + + return 0; +} +CODE +Hello, World +OUTPUT