From 0f55478a19d4989a2503014898261cc46ce4d849 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Mon, 1 Sep 2014 13:43:54 +0900 Subject: [PATCH] pluggable stdios --- gc.c | 11 +++++++++++ include/picrin.h | 4 +++- port.c | 20 +++++--------------- state.c | 14 +++++++++++++- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/gc.c b/gc.c index 9a947837..c71a2161 100644 --- a/gc.c +++ b/gc.c @@ -625,6 +625,17 @@ gc_mark_phase(pic_state *pic) /* library table */ gc_mark(pic, pic->libs); + + /* standard I/O ports */ + if (pic->xSTDIN) { + gc_mark_object(pic, (struct pic_object *)pic->xSTDIN); + } + if (pic->xSTDOUT) { + gc_mark_object(pic, (struct pic_object *)pic->xSTDOUT); + } + if (pic->xSTDERR) { + gc_mark_object(pic, (struct pic_object *)pic->xSTDERR); + } } static void diff --git a/include/picrin.h b/include/picrin.h index 381b1a44..c370015e 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -108,6 +108,8 @@ typedef struct { struct pic_object **arena; size_t arena_size, arena_idx; + struct pic_port *xSTDIN, *xSTDOUT, *xSTDERR; + char *native_stack_start; } pic_state; @@ -133,7 +135,7 @@ void pic_gc_arena_restore(pic_state *, size_t); pic_gc_arena_restore(pic, ai); \ } while (0) -pic_state *pic_open(int argc, char *argv[], char **envp); +pic_state *pic_open(int argc, char *argv[], char **envp, xFILE *stdio[3]); void pic_close(pic_state *); void pic_define(pic_state *, const char *, pic_value); /* automatic export */ diff --git a/port.c b/port.c index b8a15154..db1a6e96 100644 --- a/port.c +++ b/port.c @@ -43,8 +43,8 @@ pic_stdout(pic_state *pic) return pic_port_ptr(pic_apply(pic, proc, pic_nil_value())); } -static struct pic_port * -port_new_stdport(pic_state *pic, xFILE *file, short dir) +struct pic_port * +pic_port_make_stdport(pic_state *pic, xFILE *file, short dir) { struct pic_port *port; @@ -690,19 +690,9 @@ pic_port_flush(pic_state *pic) void pic_init_port(pic_state *pic) { - struct pic_port *STDIN, *STDOUT, *STDERR; - - STDIN = port_new_stdport(pic, xstdin, PIC_PORT_IN); - STDOUT = port_new_stdport(pic, xstdout, PIC_PORT_OUT); - STDERR = port_new_stdport(pic, xstderr, PIC_PORT_OUT); - - pic_define(pic, "standard-input-port", pic_obj_value(STDIN)); - pic_define(pic, "standard-output-port", pic_obj_value(STDOUT)); - pic_define(pic, "standard-error-port", pic_obj_value(STDERR)); - - pic_define(pic, "current-input-port", pic_obj_value(pic_var_new(pic, pic_obj_value(STDIN), NULL))); - pic_define(pic, "current-output-port", pic_obj_value(pic_var_new(pic, pic_obj_value(STDOUT), NULL))); - pic_define(pic, "current-error-port", pic_obj_value(pic_var_new(pic, pic_obj_value(STDERR), NULL))); + pic_define(pic, "current-input-port", pic_obj_value(pic_var_new(pic, pic_obj_value(pic->xSTDIN), NULL))); + pic_define(pic, "current-output-port", pic_obj_value(pic_var_new(pic, pic_obj_value(pic->xSTDOUT), NULL))); + pic_define(pic, "current-error-port", pic_obj_value(pic_var_new(pic, pic_obj_value(pic->xSTDERR), NULL))); pic_defun(pic, "input-port?", pic_port_input_port_p); pic_defun(pic, "output-port?", pic_port_output_port_p); diff --git a/state.c b/state.c index 4810af25..28ee47e1 100644 --- a/state.c +++ b/state.c @@ -10,13 +10,15 @@ #include "picrin/proc.h" #include "picrin/macro.h" #include "picrin/cont.h" +#include "picrin/port.h" #include "picrin/error.h" void pic_init_core(pic_state *); pic_state * -pic_open(int argc, char *argv[], char **envp) +pic_open(int argc, char *argv[], char **envp, xFILE *stdio[3]) { + struct pic_port *pic_port_make_stdport(pic_state *, xFILE *, short); char t; pic_state *pic; @@ -72,6 +74,11 @@ pic_open(int argc, char *argv[], char **envp) pic->try_jmp_idx = 0; pic->try_jmp_size = PIC_RESCUE_SIZE; + /* standard ports */ + pic->xSTDIN = NULL; + pic->xSTDOUT = NULL; + pic->xSTDERR = NULL; + /* GC arena */ pic->arena = calloc(PIC_ARENA_SIZE, sizeof(struct pic_object **)); pic->arena_size = PIC_ARENA_SIZE; @@ -148,6 +155,11 @@ pic_open(int argc, char *argv[], char **envp) pic->PICRIN_USER = pic_open_library(pic, pic_read_cstr(pic, "(picrin user)")); pic->lib = pic->PICRIN_USER; + /* standard I/O */ + pic->xSTDIN = pic_port_make_stdport(pic, stdio[0], PIC_PORT_IN); + pic->xSTDOUT = pic_port_make_stdport(pic, stdio[1], PIC_PORT_OUT); + pic->xSTDERR = pic_port_make_stdport(pic, stdio[2], PIC_PORT_OUT); + pic_init_core(pic); return pic;