From 94a44f1fd7e5337b218059d01688226674e4d6d0 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 5 Nov 2023 16:58:45 +0900 Subject: [PATCH] separted the IO handlers to the source code handler and user stream handlers --- bin/main.c | 79 ++++++++++++++++-------- go/cb.go | 28 ++++----- go/hcl.go | 49 ++++++++++----- lib/hcl-s.c | 3 +- lib/hcl.c | 4 ++ lib/hcl.h | 50 ++++++++++----- lib/read.c | 132 +++++++++++++++++++++------------------- lib/std.c | 172 +++++++++++++++++++++++++++++----------------------- main.go | 8 ++- 9 files changed, 312 insertions(+), 213 deletions(-) diff --git a/bin/main.c b/bin/main.c index a507038..6bbe369 100644 --- a/bin/main.c +++ b/bin/main.c @@ -71,7 +71,12 @@ # if defined(HAVE_SIGNAL_H) # include # endif +#endif +#if defined(__DOS__) || defined(_WIN32) || defined(__OS2__) +#define FOPEN_R_FLAGS "rb" +#else +#define FOPEN_R_FLAGS "r" #endif typedef struct bb_t bb_t; @@ -88,8 +93,8 @@ struct bb_t typedef struct xtn_t xtn_t; struct xtn_t { - const char* read_path; /* main source file */ - const char* print_path; + const char* sci_path; /* main source file */ + const char* udo_path; int vm_running; /*hcl_oop_t sym_errstr;*/ @@ -355,7 +360,7 @@ static void print_synerr (hcl_t* hcl) } else { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "%s", xtn->read_path); + hcl_logbfmt (hcl, HCL_LOG_STDERR, "%s", xtn->sci_path); } hcl_logbfmt (hcl, HCL_LOG_STDERR, "[%zu,%zu] %js", @@ -384,7 +389,7 @@ static hcl_oop_t execute_in_interactive_mode (hcl_t* hcl) retv = hcl_execute(hcl); /* flush pending output data in the interactive mode(e.g. printf without a newline) */ - hcl_flushio (hcl); + hcl_flushudio (hcl); if (!retv) { @@ -422,7 +427,7 @@ static hcl_oop_t execute_in_batch_mode (hcl_t* hcl, int verbose) /*setup_tick ();*/ retv = hcl_execute(hcl); - hcl_flushio (hcl); + hcl_flushudio (hcl); if (!retv) { @@ -447,11 +452,25 @@ static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj) return 0; } -static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose) +static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) { + FILE* fp = HCL_NULL; + hcl_bch_t buf[1024]; + hcl_oow_t xlen; + int is_tty; + + fp = fopen(xtn->sci_path, FOPEN_R_FLAGS); + if (!fp) + { + hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: failed to open - %hs - %hs\n", xtn->sci_path, strerror(errno)); + goto oops; + } + + is_tty = isatty(fileno(fp)); + /* override the default cnode handler. the default one simply * compiles the expression node without execution */ - if (hcl_beginfeed(hcl, hcl_isstdreadertty(hcl)? on_fed_cnode_in_interactive_mode: HCL_NULL) <= -1) + if (hcl_beginfeed(hcl, is_tty? on_fed_cnode_in_interactive_mode: HCL_NULL) <= -1) { hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot begin feed - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); goto oops; @@ -460,14 +479,19 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose) /* [NOTE] it isn't a very nice idea to get this internal data and use it with read_input() */ while (1) { - hcl_ooch_t* ptr; - hcl_oow_t xlen; - - ptr = hcl_readbasesrraw(hcl, &xlen); - if (HCL_UNLIKELY(!ptr)) goto oops; - if (xlen <= 0) break; - if (hcl_feed(hcl, ptr, xlen) <= -1) goto feed_error; + xlen = fread(buf, HCL_SIZEOF(buf[0]), HCL_COUNTOF(buf), fp); + if (xlen > 0 && hcl_feedbchars(hcl, buf, xlen) <= -1) goto feed_error; + if (xlen < HCL_COUNTOF(buf)) + { + if (ferror(fp)) + { + hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: failed to read - %hs - %hs\n", xtn->sci_path, strerror(errno)); + goto oops; + } + break; + } } + if (hcl_endfeed(hcl) <= -1) { feed_error: @@ -475,11 +499,13 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int cflags, int verbose) else hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot feed - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); goto oops; /* TODO: proceed or just exit? */ } + fclose (fp); - if (!hcl_isstdreadertty(hcl) && hcl_getbclen(hcl) > 0) execute_in_batch_mode (hcl, verbose); + if (!is_tty && hcl_getbclen(hcl) > 0) execute_in_batch_mode (hcl, verbose); return 0; oops: + if (fp) fclose (fp); return -1; } @@ -511,7 +537,6 @@ int main (int argc, char* argv[]) const char* logopt = HCL_NULL; hcl_oow_t heapsize = DEFAULT_HEAPSIZE; - int cflags; int verbose = 0; int show_info = 0; /*int experimental = 0;*/ @@ -640,7 +665,6 @@ int main (int argc, char* argv[]) return 0; } - if (hcl_ignite(hcl, heapsize) <= -1) { hcl_logbfmt (hcl, HCL_LOG_STDERR, "cannot ignite hcl - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); @@ -653,12 +677,18 @@ int main (int argc, char* argv[]) goto oops; } - xtn->read_path = argv[opt.ind++]; - if (opt.ind < argc) xtn->print_path = argv[opt.ind++]; -/* TODO: add scan path */ - if (hcl_attachiostdwithbcstr(hcl, xtn->read_path, "", xtn->print_path) <= -1) + xtn->sci_path = argv[opt.ind++]; /* input source code file */ + if (opt.ind < argc) xtn->udo_path = argv[opt.ind++]; + + if (hcl_attachsciostdwithbcstr(hcl, xtn->sci_path) <= -1) { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot attach IO streams - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); + hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot attach source input stream - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); + goto oops; + } + + if (hcl_attachudiostdwithbcstr(hcl, "", xtn->udo_path) <= -1) /* TODO: add udi path */ + { + hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot attach user data streams - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); goto oops; } @@ -691,10 +721,7 @@ int main (int argc, char* argv[]) } #endif - cflags = 0; - if (hcl_isstdreadertty(hcl)) cflags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK; - - if (feed_loop(hcl, xtn, cflags, verbose) <= -1) goto oops; + if (feed_loop(hcl, xtn, verbose) <= -1) goto oops; set_signal_to_default (SIGINT); hcl_close (hcl); diff --git a/go/cb.go b/go/cb.go index b6e1a73..3b9fa7b 100644 --- a/go/cb.go +++ b/go/cb.go @@ -77,7 +77,7 @@ func (io *IOHandleTable) slot_to_io_handle(slot int) IOHandle { var io_tab IOHandleTable = IOHandleTable{} //export hcl_go_read_handler -func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.int { +func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.int { var ( g *HCL err error @@ -88,13 +88,13 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in switch cmd { case C.HCL_IO_OPEN: var ( - ioarg *C.hcl_iosrarg_t + ioarg *C.hcl_io_sciarg_t name string includer_name string fd int ) - ioarg = (*C.hcl_iosrarg_t)(arg) + ioarg = (*C.hcl_io_sciarg_t)(arg) if ioarg.name == nil { // main stream when it's not feed based. name = "" } else { @@ -119,18 +119,18 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in return 0 case C.HCL_IO_CLOSE: - var ioarg *C.hcl_iosrarg_t = (*C.hcl_iosrarg_t)(arg) + var ioarg *C.hcl_io_sciarg_t = (*C.hcl_io_sciarg_t)(arg) g.io.r.Close(int(uintptr(ioarg.handle))) return 0 case C.HCL_IO_READ: var ( - ioarg *C.hcl_iosrarg_t + ioarg *C.hcl_io_sciarg_t n int i int buf []rune ) - ioarg = (*C.hcl_iosrarg_t)(arg) + ioarg = (*C.hcl_io_sciarg_t)(arg) buf = make([]rune, 1024) // TODO: different size... n, err = g.io.r.Read(int(uintptr(ioarg.handle)), buf) @@ -151,7 +151,7 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in } //export hcl_go_scan_handler -func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.int { +func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.int { var ( g *HCL err error @@ -177,12 +177,12 @@ func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in case C.HCL_IO_READ: var ( - ioarg *C.hcl_ioinarg_t + ioarg *C.hcl_io_udiarg_t n int err error buf []rune ) - ioarg = (*C.hcl_ioinarg_t)(arg) + ioarg = (*C.hcl_io_udiarg_t)(arg) buf = make([]rune, 1024) // TODO: different size... n, err = g.io.s.Read(buf) @@ -199,7 +199,7 @@ func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in } //export hcl_go_print_handler -func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.int { +func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.int { var ( g *HCL err error @@ -225,11 +225,11 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i case C.HCL_IO_WRITE: var ( - ioarg *C.hcl_iooutarg_t + ioarg *C.hcl_io_udoarg_t data []rune err error ) - ioarg = (*C.hcl_iooutarg_t)(arg) + ioarg = (*C.hcl_io_udoarg_t)(arg) data = uchars_to_rune_slice((*C.hcl_uch_t)(ioarg.ptr), uintptr(ioarg.len)) err = g.io.p.Write(data) if err != nil { @@ -241,11 +241,11 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i case C.HCL_IO_WRITE_BYTES: var ( - ioarg *C.hcl_iooutarg_t + ioarg *C.hcl_io_udoarg_t data []byte err error ) - ioarg = (*C.hcl_iooutarg_t)(arg) + ioarg = (*C.hcl_io_udoarg_t)(arg) data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len) err = g.io.p.WriteBytes(data) if err != nil { diff --git a/go/hcl.go b/go/hcl.go index b06d065..9d2832c 100644 --- a/go/hcl.go +++ b/go/hcl.go @@ -5,17 +5,17 @@ package hcl #include #include // for C.freem -extern int hcl_go_read_handler (hcl_t hcl, hcl_iocmd_t cmd, void* arg); -extern int hcl_go_scan_handler (hcl_t hcl, hcl_iocmd_t cmd, void* arg); -extern int hcl_go_print_handler (hcl_t hcl, hcl_iocmd_t cmd, void* arg); +extern int hcl_go_read_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg); +extern int hcl_go_scan_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg); +extern int hcl_go_print_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg); -int hcl_read_handler_for_go (hcl_t hcl, hcl_iocmd_t cmd, void* arg) { +int hcl_read_handler_for_go (hcl_t hcl, hcl_io_cmd_t cmd, void* arg) { return hcl_go_read_handler(hcl, cmd, arg); } -int hcl_scan_handler_for_go (hcl_t hcl, hcl_iocmd_t cmd, void* arg) { +int hcl_scan_handler_for_go (hcl_t hcl, hcl_io_cmd_t cmd, void* arg) { return hcl_go_scan_handler(hcl, cmd, arg); } -int hcl_print_handler_for_go (hcl_t hcl, hcl_iocmd_t cmd, void* arg) { +int hcl_print_handler_for_go (hcl_t hcl, hcl_io_cmd_t cmd, void* arg) { return hcl_go_print_handler(hcl, cmd, arg); } */ @@ -181,23 +181,42 @@ func (hcl *HCL) AddBuiltinPrims() error { return nil } -func (hcl *HCL) AttachIO(r IOReadImpl, s IOScanImpl, p IOPrintImpl) error { +func (hcl *HCL) AttachSCIO(r IOReadImpl) error { var x C.int - var io IOImplSet + var or IOReadImpl - io = hcl.io + or = hcl.io.r hcl.io.r = r + + x = C.hcl_attachscio(hcl.c, C.hcl_io_impl_t(C.hcl_read_handler_for_go)) + if x <= -1 { + // restore the io handler set due to attachment failure + hcl.io.r = or + return fmt.Errorf("unable to attach source input stream handler - %s", hcl.get_errmsg()) + } + return nil +} + +func (hcl *HCL) AttachUDIO(s IOScanImpl, p IOPrintImpl) error { + var x C.int + var os IOScanImpl + var op IOPrintImpl + + os = hcl.io.s + op = hcl.io.p + hcl.io.s = s hcl.io.p = p - x = C.hcl_attachio(hcl.c, - C.hcl_ioimpl_t(C.hcl_read_handler_for_go), - C.hcl_ioimpl_t(C.hcl_scan_handler_for_go), - C.hcl_ioimpl_t(C.hcl_print_handler_for_go)) + x = C.hcl_attachudio(hcl.c, + C.hcl_io_impl_t(C.hcl_scan_handler_for_go), + C.hcl_io_impl_t(C.hcl_print_handler_for_go)) if x <= -1 { - hcl.io = io // restore the io handler set due to attachment failure - return fmt.Errorf("unable to attach I/O handlers - %s", hcl.get_errmsg()) + //restore the io handlers set due to attachment failure + hcl.io.s = os + hcl.io.p = op + return fmt.Errorf("unable to attach user data stream handlers - %s", hcl.get_errmsg()) } return nil } diff --git a/lib/hcl-s.c b/lib/hcl-s.c index cced7c9..c0d3f05 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -718,7 +718,8 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_ if (hcl_ignite(proto->hcl, worker->server->cfg.actor_heap_size) <= -1) goto oops; if (hcl_addbuiltinprims(proto->hcl) <= -1) goto oops; - if (hcl_attachio(proto->hcl, read_handler, HCL_NULL, print_handler) <= -1) goto oops; + if (hcl_attachscio(proto->hcl, read_handler) <= -1) goto oops; + if (hcl_attachudio(proto->hcl, HCL_NULL, print_handler) <= -1) goto oops; return proto; oops: diff --git a/lib/hcl.c b/lib/hcl.c index f2ea42f..cf4146e 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -219,6 +219,10 @@ void hcl_fini (hcl_t* hcl) /* deregister all callbacks */ while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist); + + /* detach the user data io handlers just in case */ + hcl_detachudio (hcl); + if (hcl->sem_list) { hcl_freemem (hcl, hcl->sem_list); diff --git a/lib/hcl.h b/lib/hcl.h index 9bcc427..abe0c47 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -2240,36 +2240,54 @@ HCL_EXPORT hcl_ooch_t* hcl_readbasesrraw ( hcl_oow_t* xlen ); -HCL_EXPORT int hcl_attachio ( - hcl_t* hcl, - hcl_io_impl_t sci_rdr, /* source code input handler */ - hcl_io_impl_t udi_rdr, /* user data input handler */ - hcl_io_impl_t udo_wrtr /* user data output handler */ + +HCL_EXPORT int hcl_attachscio ( + hcl_t* hcl, + hcl_io_impl_t sci_rdr ); -HCL_EXPORT int hcl_attachiostdwithbcstr ( +HCL_EXPORT void hcl_detachscio ( + hcl_t* hcl +); + +HCL_EXPORT int hcl_attachudio ( + hcl_t* hcl, + hcl_io_impl_t udi_rdr, + hcl_io_impl_t udo_wrtr +); + +HCL_EXPORT void hcl_detachudio ( + hcl_t* hcl +); + + +HCL_EXPORT int hcl_attachsciostdwithucstr ( hcl_t* hcl, - const hcl_bch_t* read_file, - const hcl_bch_t* scan_file, - const hcl_bch_t* print_file + const hcl_uch_t* sci_file ); -HCL_EXPORT int hcl_attachiostdwithucstr ( +HCL_EXPORT int hcl_attachsciostdwithbcstr ( hcl_t* hcl, - const hcl_uch_t* read_file, - const hcl_uch_t* scan_file, - const hcl_uch_t* print_file + const hcl_bch_t* sci_file ); -HCL_EXPORT int hcl_isstdreadertty ( - hcl_t* hcl +HCL_EXPORT int hcl_attachudiostdwithucstr ( + hcl_t* hcl, + const hcl_uch_t* udi_file, + const hcl_uch_t* udo_file +); + +HCL_EXPORT int hcl_attachudiostdwithbcstr ( + hcl_t* hcl, + const hcl_bch_t* udi_file, + const hcl_bch_t* udo_file ); HCL_EXPORT void hcl_detachio ( hcl_t* hcl ); -HCL_EXPORT void hcl_flushio ( +HCL_EXPORT void hcl_flushudio ( hcl_t* hcl ); diff --git a/lib/read.c b/lib/read.c index 96a8c86..ca99df6 100644 --- a/lib/read.c +++ b/lib/read.c @@ -2413,7 +2413,7 @@ static int feed_from_includee (hcl_t* hcl) int hcl_beginfeed (hcl_t* hcl, hcl_on_cnode_t on_cnode) { - HCL_ASSERT (hcl, hcl->c != HCL_NULL); /* call hcl_attachio() or hcl_attachiostd() first */ + HCL_ASSERT (hcl, hcl->c != HCL_NULL); /* call hcl_attachscio() or hcl_attachsciostd() first */ init_feed (hcl); if (on_cnode) hcl->c->feed.on_cnode = on_cnode; @@ -2732,7 +2732,7 @@ static void fini_compiler_cb (hcl_t* hcl) clear_sr_names (hcl); if (hcl->c->tok.name.ptr) hcl_freemem (hcl, hcl->c->tok.name.ptr); - hcl_detachio (hcl); + hcl_detachscio (hcl); hcl_freemem (hcl, hcl->c); hcl->c = HCL_NULL; @@ -2786,13 +2786,11 @@ static int init_compiler (hcl_t* hcl) return 0; } -int hcl_attachio (hcl_t* hcl, hcl_io_impl_t sci_rdr, hcl_io_impl_t udi_rdr, hcl_io_impl_t udo_wrtr) +int hcl_attachscio (hcl_t* hcl, hcl_io_impl_t sci_rdr) { int n; int inited_compiler = 0; hcl_io_sciarg_t new_sciarg; - hcl_io_udiarg_t new_udiarg; - hcl_io_udoarg_t new_udoarg; if (!hcl->c) { @@ -2800,6 +2798,7 @@ int hcl_attachio (hcl_t* hcl, hcl_io_impl_t sci_rdr, hcl_io_impl_t udi_rdr, hcl_ inited_compiler = 1; } + if (sci_rdr) { /* The name field and the includer field are HCL_NULL @@ -2811,34 +2810,7 @@ int hcl_attachio (hcl_t* hcl, hcl_io_impl_t sci_rdr, hcl_io_impl_t udi_rdr, hcl_ /* open the top-level source input stream */ n = sci_rdr(hcl, HCL_IO_OPEN, &new_sciarg); if (n <= -1) goto oops; - } - if (udi_rdr) - { - HCL_MEMSET (&new_udiarg, 0, HCL_SIZEOF(new_udiarg)); - n = udi_rdr(hcl, HCL_IO_OPEN, &new_udiarg); - if (n <= -1) - { - sci_rdr (hcl, HCL_IO_CLOSE, &new_sciarg); - goto oops; - } - } - - if (udo_wrtr) - { - /* open the new output stream */ - HCL_MEMSET (&new_udoarg, 0, HCL_SIZEOF(new_udoarg)); - n = udo_wrtr(hcl, HCL_IO_OPEN, &new_udoarg); - if (n <= -1) - { - if (udi_rdr) udi_rdr (hcl, HCL_IO_CLOSE, &new_udiarg); - if (sci_rdr) sci_rdr (hcl, HCL_IO_CLOSE, &new_sciarg); - goto oops; - } - } - - if (sci_rdr) - { if (hcl->c->sci_rdr) { /* close the old source input stream */ @@ -2846,32 +2818,7 @@ int hcl_attachio (hcl_t* hcl, hcl_io_impl_t sci_rdr, hcl_io_impl_t udi_rdr, hcl_ } hcl->c->sci_rdr = sci_rdr; hcl->c->sci_arg = new_sciarg; - } - if (udi_rdr) - { - if (hcl->io.udi_rdr) - { - /* close the old input stream */ - hcl->io.udi_rdr (hcl, HCL_IO_CLOSE, &hcl->io.udi_arg); - } - hcl->io.udi_rdr = udi_rdr; - hcl->io.udi_arg = new_udiarg; - } - - if (udo_wrtr) - { - if (hcl->io.udo_wrtr) - { - /* close the old output stream */ - hcl->io.udo_wrtr (hcl, HCL_IO_CLOSE, &hcl->io.udo_arg); - } - hcl->io.udo_wrtr = udo_wrtr; - hcl->io.udo_arg = new_udoarg; - } - - if (sci_rdr) - { /* clear unneeded source stream names */ /*clear_sr_names (hcl); <---- TODO: tricky to clean up here */ @@ -2888,12 +2835,7 @@ oops: return -1; } -void hcl_flushio (hcl_t* hcl) -{ - if (hcl->io.udo_wrtr) hcl->io.udo_wrtr (hcl, HCL_IO_FLUSH, &hcl->io.udo_arg); -} - -void hcl_detachio (hcl_t* hcl) +void hcl_detachscio (hcl_t* hcl) { /* an error occurred and control has reached here * probably, some included files might not have been @@ -2919,9 +2861,68 @@ void hcl_detachio (hcl_t* hcl) hcl->c->sci_rdr (hcl, HCL_IO_CLOSE, hcl->c->curinp); hcl->c->sci_rdr = HCL_NULL; /* ready for another attachment */ } + } +} +int hcl_attachudio (hcl_t* hcl, hcl_io_impl_t udi_rdr, hcl_io_impl_t udo_wrtr) +{ + int n; + hcl_io_udiarg_t new_udiarg; + hcl_io_udoarg_t new_udoarg; + + if (udi_rdr) + { + HCL_MEMSET (&new_udiarg, 0, HCL_SIZEOF(new_udiarg)); + n = udi_rdr(hcl, HCL_IO_OPEN, &new_udiarg); + if (n <= -1) + { + goto oops; + } } + if (udo_wrtr) + { + /* open the new output stream */ + HCL_MEMSET (&new_udoarg, 0, HCL_SIZEOF(new_udoarg)); + n = udo_wrtr(hcl, HCL_IO_OPEN, &new_udoarg); + if (n <= -1) + { + if (udi_rdr) udi_rdr (hcl, HCL_IO_CLOSE, &new_udiarg); + goto oops; + } + } + + if (udi_rdr) + { + if (hcl->io.udi_rdr) + { + /* close the old input stream */ + hcl->io.udi_rdr (hcl, HCL_IO_CLOSE, &hcl->io.udi_arg); + } + hcl->io.udi_rdr = udi_rdr; + hcl->io.udi_arg = new_udiarg; + } + + if (udo_wrtr) + { + if (hcl->io.udo_wrtr) + { + /* close the old output stream */ + hcl->io.udo_wrtr (hcl, HCL_IO_CLOSE, &hcl->io.udo_arg); + } + hcl->io.udo_wrtr = udo_wrtr; + hcl->io.udo_arg = new_udoarg; + } + + return 0; + +oops: + return -1; +} + + +void hcl_detachudio (hcl_t* hcl) +{ if (hcl->io.udi_rdr) { hcl->io.udi_rdr (hcl, HCL_IO_CLOSE, &hcl->io.udi_arg); @@ -2935,6 +2936,11 @@ void hcl_detachio (hcl_t* hcl) } } +void hcl_flushudio (hcl_t* hcl) +{ + if (hcl->io.udo_wrtr) hcl->io.udo_wrtr (hcl, HCL_IO_FLUSH, &hcl->io.udo_arg); +} + void hcl_setbasesrloc (hcl_t* hcl, hcl_oow_t line, hcl_oow_t colm) { hcl->c->sci_arg.line = line; diff --git a/lib/std.c b/lib/std.c index 87813a4..fd53373 100644 --- a/lib/std.c +++ b/lib/std.c @@ -288,11 +288,9 @@ struct xtn_t * set these two field and reset them at the end. * since hcl_attachio() callls the open handler, these fields * are valid only inside the open handelr */ - const char* read_path; /* main source file */ - const char* scan_path; /* runtime input file */ - const char* print_path; /* runtime output file */ - - int reader_istty; + const char* sci_path; /* main source file */ + const char* udi_path; /* runtime input file */ + const char* udo_path; /* runtime output file */ int vm_running; int rcv_tick; @@ -3241,42 +3239,38 @@ static HCL_INLINE int open_sci_stream (hcl_t* hcl, hcl_io_sciarg_t* arg) #endif bb->fp = fopen(bb->fn, FOPEN_R_FLAGS); + if (!bb->fp) + { + hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", bb->fn); + goto oops; + } } else { - /* main stream */ + /* main stream */ hcl_oow_t pathlen; - pathlen = xtn->read_path? hcl_count_bcstr(xtn->read_path): 0; + pathlen = xtn->sci_path? hcl_count_bcstr(xtn->sci_path): 0; bb = (bb_t*)hcl_callocmem(hcl, HCL_SIZEOF(*bb) + (HCL_SIZEOF(hcl_bch_t) * (pathlen + 1))); if (!bb) goto oops; bb->fn = (hcl_bch_t*)(bb + 1); - if (pathlen > 0 && xtn->read_path) + if (pathlen > 0 && xtn->sci_path) { - hcl_copy_bcstr (bb->fn, pathlen + 1, xtn->read_path); - bb->fp = fopen(bb->fn, FOPEN_R_FLAGS); + hcl_copy_bcstr (bb->fn, pathlen + 1, xtn->sci_path); + /*bb->fp = fopen(bb->fn, FOPEN_R_FLAGS);*/ } else { bb->fn[0] = '\0'; - bb->fp = stdin; + /*bb->fp = stdin;*/ } } - if (!bb->fp) - { - hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", bb->fn); - goto oops; - } if (!arg->includer) /* if main stream */ { - #if defined(HAVE_ISATTY) - xtn->reader_istty = isatty(fileno(bb->fp)); - #endif - /* HACK */ HCL_ASSERT (hcl, arg->name == HCL_NULL); arg->name = hcl_dupbtooocstr(hcl, bb->fn, HCL_NULL); @@ -3304,17 +3298,18 @@ static HCL_INLINE int close_sci_stream (hcl_t* hcl, hcl_io_sciarg_t* arg) bb_t* bb; bb = (bb_t*)arg->handle; - HCL_ASSERT (hcl, bb != HCL_NULL && bb->fp != HCL_NULL); + HCL_ASSERT (hcl, bb != HCL_NULL /*&& bb->fp != HCL_NULL*/); /* HACK */ if (!arg->includer && arg->name) { + /* main stream closing */ hcl_freemem (hcl, arg->name); arg->name = HCL_NULL; } /* END HACK */ - if (bb->fp != stdin) fclose (bb->fp); + if (bb->fp /*&& bb->fp != stdin*/) fclose (bb->fp); hcl_freemem (hcl, bb); arg->handle = HCL_NULL; @@ -3403,15 +3398,15 @@ static HCL_INLINE int open_in_stream (hcl_t* hcl, hcl_io_udiarg_t* arg) hcl_oow_t pathlen; - pathlen = xtn->read_path? hcl_count_bcstr(xtn->read_path): 0; + pathlen = xtn->sci_path? hcl_count_bcstr(xtn->sci_path): 0; bb = (bb_t*)hcl_callocmem(hcl, HCL_SIZEOF(*bb) + (HCL_SIZEOF(hcl_bch_t) * (pathlen + 1))); if (!bb) goto oops; bb->fn = (hcl_bch_t*)(bb + 1); - if (pathlen > 0 && xtn->read_path) + if (pathlen > 0 && xtn->sci_path) { - hcl_copy_bcstr (bb->fn, pathlen + 1, xtn->read_path); + hcl_copy_bcstr (bb->fn, pathlen + 1, xtn->sci_path); bb->fp = fopen(bb->fn, FOPEN_R_FLAGS); } else @@ -3503,7 +3498,7 @@ static HCL_INLINE int read_in_stream (hcl_t* hcl, hcl_io_udiarg_t* arg) return 0; } -static int scan_handler (hcl_t* hcl, hcl_io_cmd_t cmd, void* arg) +static int udi_handler (hcl_t* hcl, hcl_io_cmd_t cmd, void* arg) { switch (cmd) { @@ -3538,11 +3533,11 @@ static HCL_INLINE int open_out_stream (hcl_t* hcl, hcl_io_udoarg_t* arg) #define FOPEN_W_FLAGS "w" #endif - fp = (xtn->print_path && xtn->print_path[0] != '\0'? fopen(xtn->print_path, FOPEN_W_FLAGS): stdout); + fp = (xtn->udo_path && xtn->udo_path[0] != '\0'? fopen(xtn->udo_path, FOPEN_W_FLAGS): stdout); if (!fp) { - if (xtn->print_path) - hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", xtn->print_path); + if (xtn->udo_path) + hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", xtn->udo_path); else hcl_seterrnum (hcl, HCL_EIOERR); return -1; @@ -3632,7 +3627,7 @@ static HCL_INLINE int flush_out_stream (hcl_t* hcl, hcl_io_udoarg_t* arg) return 0; } -static int print_handler (hcl_t* hcl, hcl_io_cmd_t cmd, void* arg) +static int udo_handler (hcl_t* hcl, hcl_io_cmd_t cmd, void* arg) { switch (cmd) { @@ -3659,73 +3654,96 @@ static int print_handler (hcl_t* hcl, hcl_io_cmd_t cmd, void* arg) /* --------------------------------------------------------------------- */ -int hcl_attachiostdwithbcstr (hcl_t* hcl, const hcl_bch_t* read_file, const hcl_bch_t* scan_file, const hcl_bch_t* print_file) +int hcl_attachsciostdwithbcstr (hcl_t* hcl, const hcl_bch_t* sci_file) { xtn_t* xtn = GET_XTN(hcl); int n; - HCL_ASSERT (hcl, xtn->read_path == HCL_NULL); - HCL_ASSERT (hcl, xtn->scan_path == HCL_NULL); - HCL_ASSERT (hcl, xtn->print_path == HCL_NULL); + HCL_ASSERT (hcl, xtn->sci_path == HCL_NULL); + + xtn->sci_path = sci_file; - xtn->read_path = read_file; - xtn->scan_path = scan_file; - xtn->print_path = print_file; + n = hcl_attachscio(hcl, sci_handler); - n = hcl_attachio(hcl, sci_handler, scan_handler, print_handler); - - xtn->read_path = HCL_NULL; - xtn->scan_path = HCL_NULL; - xtn->print_path = HCL_NULL; + xtn->sci_path = HCL_NULL; return n; } -int hcl_attachiostdwithucstr (hcl_t* hcl, const hcl_uch_t* read_file, const hcl_uch_t* scan_file, const hcl_uch_t* print_file) +int hcl_attachsciostdwithucstr (hcl_t* hcl, const hcl_uch_t* sci_file) { xtn_t* xtn = GET_XTN(hcl); int n; - HCL_ASSERT (hcl, xtn->read_path == HCL_NULL); - HCL_ASSERT (hcl, xtn->scan_path == HCL_NULL); - HCL_ASSERT (hcl, xtn->print_path == HCL_NULL); + HCL_ASSERT (hcl, xtn->sci_path == HCL_NULL); - xtn->read_path = hcl_duputobcstr(hcl, read_file, HCL_NULL); - if (HCL_UNLIKELY(!xtn->read_path)) return -1; + xtn->sci_path = hcl_duputobcstr(hcl, sci_file, HCL_NULL); + if (HCL_UNLIKELY(!xtn->sci_path)) return -1; + + n = hcl_attachscio(hcl, sci_handler); - xtn->scan_path = hcl_duputobcstr(hcl, scan_file, HCL_NULL); - if (HCL_UNLIKELY(!xtn->scan_path)) - { - hcl_freemem (hcl, (void*)xtn->read_path); - xtn->read_path = HCL_NULL; - return -1; - } - - xtn->print_path = hcl_duputobcstr(hcl, print_file, HCL_NULL); - if (HCL_UNLIKELY(!xtn->print_path)) - { - hcl_freemem (hcl, (void*)xtn->scan_path); - hcl_freemem (hcl, (void*)xtn->read_path); - xtn->scan_path = HCL_NULL; - xtn->read_path = HCL_NULL; - return -1; - } - - n = hcl_attachio(hcl, sci_handler, scan_handler, print_handler); - - hcl_freemem (hcl, (void*)xtn->read_path); - hcl_freemem (hcl, (void*)xtn->scan_path); - hcl_freemem (hcl, (void*)xtn->print_path); - - xtn->read_path = HCL_NULL; - xtn->scan_path = HCL_NULL; - xtn->print_path = HCL_NULL; + hcl_freemem (hcl, (void*)xtn->sci_path); + xtn->sci_path = HCL_NULL; return n; } -int hcl_isstdreadertty (hcl_t* hcl) +/* --------------------------------------------------------------------- */ + +int hcl_attachudiostdwithbcstr (hcl_t* hcl, const hcl_bch_t* udi_file, const hcl_bch_t* udo_file) { xtn_t* xtn = GET_XTN(hcl); - return xtn->reader_istty; + int n; + + HCL_ASSERT (hcl, xtn->udi_path == HCL_NULL); + HCL_ASSERT (hcl, xtn->udo_path == HCL_NULL); + + + xtn->udi_path = udi_file; + xtn->udo_path = udo_file; + + n = hcl_attachudio(hcl, udi_handler, udo_handler); + + + xtn->udi_path = HCL_NULL; + xtn->udo_path = HCL_NULL; + + return n; } + +int hcl_attachudiostdwithucstr (hcl_t* hcl, const hcl_uch_t* udi_file, const hcl_uch_t* udo_file) +{ + xtn_t* xtn = GET_XTN(hcl); + int n; + + HCL_ASSERT (hcl, xtn->udi_path == HCL_NULL); + HCL_ASSERT (hcl, xtn->udo_path == HCL_NULL); + + + xtn->udi_path = hcl_duputobcstr(hcl, udi_file, HCL_NULL); + if (HCL_UNLIKELY(!xtn->udi_path)) + { + hcl_freemem (hcl, (void*)xtn->sci_path); + return -1; + } + + xtn->udo_path = hcl_duputobcstr(hcl, udo_file, HCL_NULL); + if (HCL_UNLIKELY(!xtn->udo_path)) + { + hcl_freemem (hcl, (void*)xtn->udi_path); + xtn->udi_path = HCL_NULL; + return -1; + } + + n = hcl_attachudio(hcl, udi_handler, udo_handler); + + hcl_freemem (hcl, (void*)xtn->udi_path); + hcl_freemem (hcl, (void*)xtn->udo_path); + + xtn->udi_path = HCL_NULL; + xtn->udo_path = HCL_NULL; + + return n; +} + + diff --git a/main.go b/main.go index 9ae0d5d..60d2df5 100644 --- a/main.go +++ b/main.go @@ -87,7 +87,13 @@ func main() { goto oops } - err = x.AttachIO(&rfh, &sfh, &pfh) + err = x.AttachSCIO(&rfh) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + goto oops + } + + err = x.AttachUDIO(&sfh, &pfh) if err != nil { fmt.Printf("Error: %s\n", err.Error()) goto oops