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