diff --git a/contrib/05.r7rs/src/file.c b/contrib/05.r7rs/src/file.c index 36e50e86..c354c179 100644 --- a/contrib/05.r7rs/src/file.c +++ b/contrib/05.r7rs/src/file.c @@ -20,7 +20,7 @@ generic_open_file(pic_state *pic, const char *fname, char *mode, short flags) struct pic_port *port; xFILE *file; - file = xfopen(fname, mode); + file = xfopen(pic, fname, mode); if (! file) { file_error(pic, "could not open file"); } diff --git a/contrib/05.r7rs/src/load.c b/contrib/05.r7rs/src/load.c index 385767d8..8f519327 100644 --- a/contrib/05.r7rs/src/load.c +++ b/contrib/05.r7rs/src/load.c @@ -10,7 +10,7 @@ pic_load(pic_state *pic, const char *filename) struct pic_port *port; xFILE *file; - file = xfopen(filename, "r"); + file = xfopen(pic, filename, "r"); if (file == NULL) { pic_errorf(pic, "could not open file: %s", filename); } diff --git a/extlib/benz/file.c b/extlib/benz/file.c index 23a78f45..146f63e6 100644 --- a/extlib/benz/file.c +++ b/extlib/benz/file.c @@ -51,7 +51,7 @@ file_close(pic_state PIC_UNUSED(*pic), void *cookie) { return fclose(cookie); } -xFILE *xfopen(const char *name, const char *mode) { +xFILE *xfopen(pic_state *pic, const char *name, const char *mode) { FILE *fp; if ((fp = fopen(name, mode)) == NULL) { @@ -60,28 +60,28 @@ xFILE *xfopen(const char *name, const char *mode) { switch (*mode) { case 'r': - return xfunopen(fp, file_read, NULL, file_seek, file_close); + return xfunopen(pic, fp, file_read, NULL, file_seek, file_close); default: - return xfunopen(fp, NULL, file_write, file_seek, file_close); + return xfunopen(pic, fp, NULL, file_write, file_seek, file_close); } } #define FILE_VTABLE { 0, file_read, file_write, file_seek, file_close } -xFILE x_iob[XOPEN_MAX] = { +const xFILE x_iob[XOPEN_MAX] = { { { 0 }, 0, NULL, NULL, FILE_VTABLE, X_READ }, { { 0 }, 0, NULL, NULL, FILE_VTABLE, X_WRITE | X_LNBUF }, { { 0 }, 0, NULL, NULL, FILE_VTABLE, X_WRITE | X_UNBUF } }; -xFILE *xfunopen(void *cookie, int (*read)(pic_state *, void *, char *, int), int (*write)(pic_state *, void *, const char *, int), long (*seek)(pic_state *, void *, long, int), int (*close)(pic_state *, void *)) { +xFILE *xfunopen(pic_state *pic, void *cookie, int (*read)(pic_state *, void *, char *, int), int (*write)(pic_state *, void *, const char *, int), long (*seek)(pic_state *, void *, long, int), int (*close)(pic_state *, void *)) { xFILE *fp; - for (fp = x_iob; fp < x_iob + XOPEN_MAX; fp++) + for (fp = pic->files; fp < pic->files + XOPEN_MAX; fp++) if ((fp->flag & (X_READ | X_WRITE)) == 0) break; /* found free slot */ - if (fp >= x_iob + XOPEN_MAX) /* no free slots */ + if (fp >= pic->files + XOPEN_MAX) /* no free slots */ return NULL; fp->cnt = 0; @@ -198,7 +198,7 @@ int xfflush(pic_state *pic, xFILE *f) { if (f == NULL) { /* flush all output streams */ for (i = 0; i < XOPEN_MAX; i++) { - if ((x_iob[i].flag & X_WRITE) && (xfflush(pic, &x_iob[i]) == -1)) + if ((pic->files[i].flag & X_WRITE) && (xfflush(pic, &pic->files[i]) == -1)) retval = -1; } } else { diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index 8eb641fe..f250305a 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -46,6 +46,9 @@ extern "C" { #include "picrin/value.h" typedef struct pic_code pic_code; +typedef struct pic_state pic_state; + +#include "picrin/file.h" typedef struct pic_jmpbuf { PIC_JMPBUF buf; @@ -71,9 +74,7 @@ typedef struct { typedef void *(*pic_allocf)(void *, size_t); -typedef struct xFILE xFILE; - -typedef struct { +struct pic_state { int argc; char **argv, **envp; @@ -137,6 +138,7 @@ typedef struct { struct pic_reg *attrs; struct pic_reader *reader; + xFILE files[XOPEN_MAX]; bool gc_enable; struct pic_heap *heap; @@ -148,7 +150,7 @@ typedef struct { pic_code *iseq; /* for pic_apply_trampoline */ char *native_stack_start; -} pic_state; +}; typedef pic_value (*pic_func_t)(pic_state *); @@ -283,7 +285,6 @@ pic_value pic_fdisplay(pic_state *, pic_value, xFILE *); #include "picrin/read.h" #include "picrin/vector.h" #include "picrin/reg.h" -#include "picrin/file.h" #if defined(__cplusplus) } diff --git a/extlib/benz/include/picrin/file.h b/extlib/benz/include/picrin/file.h index 2b761184..22af7f8e 100644 --- a/extlib/benz/include/picrin/file.h +++ b/extlib/benz/include/picrin/file.h @@ -14,7 +14,7 @@ extern "C" { #define XBUFSIZ 1024 #define XOPEN_MAX 1024 -struct xFILE { +typedef struct { /* buffer */ char buf[1]; /* fallback buffer */ long cnt; /* characters left */ @@ -29,13 +29,13 @@ struct xFILE { int (*close)(pic_state *, void *); } vtable; int flag; /* mode of the file access */ -}; +} xFILE; -extern xFILE x_iob[XOPEN_MAX]; +#define xstdin (&pic->files[0]) +#define xstdout (&pic->files[1]) +#define xstderr (&pic->files[2]) -#define xstdin (x_iob[0].vtable.cookie || (x_iob[0].vtable.cookie = stdin ), &x_iob[0]) -#define xstdout (x_iob[1].vtable.cookie || (x_iob[1].vtable.cookie = stdout), &x_iob[1]) -#define xstderr (x_iob[2].vtable.cookie || (x_iob[2].vtable.cookie = stderr), &x_iob[2]) +extern const xFILE x_iob[XOPEN_MAX]; enum _flags { X_READ = 01, @@ -63,8 +63,8 @@ enum _flags { #define xputchar(pic, x) xputc((pic), (x), xstdout) /* resource aquisition */ -xFILE *xfunopen(void *cookie, int (*read)(pic_state *, void *, char *, int), int (*write)(pic_state *, void *, const char *, int), long (*seek)(pic_state *, void *, long, int), int (*close)(pic_state *, void *)); -xFILE *xfopen(const char *, const char *); +xFILE *xfunopen(pic_state *, void *cookie, int (*read)(pic_state *, void *, char *, int), int (*write)(pic_state *, void *, const char *, int), long (*seek)(pic_state *, void *, long, int), int (*close)(pic_state *, void *)); +xFILE *xfopen(pic_state *, const char *, const char *); int xfclose(pic_state *, xFILE *); /* buffer management */ diff --git a/extlib/benz/port.c b/extlib/benz/port.c index 867626f8..c14ce632 100644 --- a/extlib/benz/port.c +++ b/extlib/benz/port.c @@ -131,9 +131,9 @@ string_open(pic_state *pic, const char *data, size_t size) if (data != NULL) { memcpy(m->buf, data, size); - file = xfunopen(m, string_read, NULL, string_seek, string_close); + file = xfunopen(pic, m, string_read, NULL, string_seek, string_close); } else { - file = xfunopen(m, NULL, string_write, string_seek, string_close); + file = xfunopen(pic, m, NULL, string_write, string_seek, string_close); } if (file == NULL) { diff --git a/extlib/benz/state.c b/extlib/benz/state.c index 7a355e47..fc0877ff 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -254,6 +254,12 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf) /* raised error object */ pic->err = pic_invalid_value(); + /* file pool */ + memcpy(pic->files, x_iob, sizeof pic->files); + pic->files[0].vtable.cookie = stdin; + pic->files[1].vtable.cookie = stdout; + pic->files[2].vtable.cookie = stderr; + /* parameter table */ pic->ptable = pic_nil_value();