don't use global mutable variable!
This commit is contained in:
parent
e43a9c7881
commit
78bd3047f8
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue