separted the IO handlers to the source code handler and user stream handlers
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
hyung-hwan 2023-11-05 16:58:45 +09:00
parent bcfe69feda
commit 94a44f1fd7
9 changed files with 312 additions and 213 deletions

View File

@ -71,7 +71,12 @@
# if defined(HAVE_SIGNAL_H) # if defined(HAVE_SIGNAL_H)
# include <signal.h> # include <signal.h>
# endif # endif
#endif
#if defined(__DOS__) || defined(_WIN32) || defined(__OS2__)
#define FOPEN_R_FLAGS "rb"
#else
#define FOPEN_R_FLAGS "r"
#endif #endif
typedef struct bb_t bb_t; typedef struct bb_t bb_t;
@ -88,8 +93,8 @@ struct bb_t
typedef struct xtn_t xtn_t; typedef struct xtn_t xtn_t;
struct xtn_t struct xtn_t
{ {
const char* read_path; /* main source file */ const char* sci_path; /* main source file */
const char* print_path; const char* udo_path;
int vm_running; int vm_running;
/*hcl_oop_t sym_errstr;*/ /*hcl_oop_t sym_errstr;*/
@ -355,7 +360,7 @@ static void print_synerr (hcl_t* hcl)
} }
else 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", 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); retv = hcl_execute(hcl);
/* flush pending output data in the interactive mode(e.g. printf without a newline) */ /* flush pending output data in the interactive mode(e.g. printf without a newline) */
hcl_flushio (hcl); hcl_flushudio (hcl);
if (!retv) if (!retv)
{ {
@ -422,7 +427,7 @@ static hcl_oop_t execute_in_batch_mode (hcl_t* hcl, int verbose)
/*setup_tick ();*/ /*setup_tick ();*/
retv = hcl_execute(hcl); retv = hcl_execute(hcl);
hcl_flushio (hcl); hcl_flushudio (hcl);
if (!retv) if (!retv)
{ {
@ -447,11 +452,25 @@ static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj)
return 0; 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 /* override the default cnode handler. the default one simply
* compiles the expression node without execution */ * 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)); hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot begin feed - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl));
goto oops; 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() */ /* [NOTE] it isn't a very nice idea to get this internal data and use it with read_input() */
while (1) while (1)
{ {
hcl_ooch_t* ptr; xlen = fread(buf, HCL_SIZEOF(buf[0]), HCL_COUNTOF(buf), fp);
hcl_oow_t xlen; if (xlen > 0 && hcl_feedbchars(hcl, buf, xlen) <= -1) goto feed_error;
if (xlen < HCL_COUNTOF(buf))
ptr = hcl_readbasesrraw(hcl, &xlen); {
if (HCL_UNLIKELY(!ptr)) goto oops; if (ferror(fp))
if (xlen <= 0) break; {
if (hcl_feed(hcl, ptr, xlen) <= -1) goto feed_error; 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) if (hcl_endfeed(hcl) <= -1)
{ {
feed_error: 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)); 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? */ 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; return 0;
oops: oops:
if (fp) fclose (fp);
return -1; return -1;
} }
@ -511,7 +537,6 @@ int main (int argc, char* argv[])
const char* logopt = HCL_NULL; const char* logopt = HCL_NULL;
hcl_oow_t heapsize = DEFAULT_HEAPSIZE; hcl_oow_t heapsize = DEFAULT_HEAPSIZE;
int cflags;
int verbose = 0; int verbose = 0;
int show_info = 0; int show_info = 0;
/*int experimental = 0;*/ /*int experimental = 0;*/
@ -640,7 +665,6 @@ int main (int argc, char* argv[])
return 0; return 0;
} }
if (hcl_ignite(hcl, heapsize) <= -1) if (hcl_ignite(hcl, heapsize) <= -1)
{ {
hcl_logbfmt (hcl, HCL_LOG_STDERR, "cannot ignite hcl - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); 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; goto oops;
} }
xtn->read_path = argv[opt.ind++]; xtn->sci_path = argv[opt.ind++]; /* input source code file */
if (opt.ind < argc) xtn->print_path = argv[opt.ind++]; if (opt.ind < argc) xtn->udo_path = argv[opt.ind++];
/* TODO: add scan path */
if (hcl_attachiostdwithbcstr(hcl, xtn->read_path, "", xtn->print_path) <= -1) 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; goto oops;
} }
@ -691,10 +721,7 @@ int main (int argc, char* argv[])
} }
#endif #endif
cflags = 0; if (feed_loop(hcl, xtn, verbose) <= -1) goto oops;
if (hcl_isstdreadertty(hcl)) cflags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
if (feed_loop(hcl, xtn, cflags, verbose) <= -1) goto oops;
set_signal_to_default (SIGINT); set_signal_to_default (SIGINT);
hcl_close (hcl); hcl_close (hcl);

View File

@ -77,7 +77,7 @@ func (io *IOHandleTable) slot_to_io_handle(slot int) IOHandle {
var io_tab IOHandleTable = IOHandleTable{} var io_tab IOHandleTable = IOHandleTable{}
//export hcl_go_read_handler //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 ( var (
g *HCL g *HCL
err error 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 { switch cmd {
case C.HCL_IO_OPEN: case C.HCL_IO_OPEN:
var ( var (
ioarg *C.hcl_iosrarg_t ioarg *C.hcl_io_sciarg_t
name string name string
includer_name string includer_name string
fd int 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. if ioarg.name == nil { // main stream when it's not feed based.
name = "" name = ""
} else { } 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 return 0
case C.HCL_IO_CLOSE: 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))) g.io.r.Close(int(uintptr(ioarg.handle)))
return 0 return 0
case C.HCL_IO_READ: case C.HCL_IO_READ:
var ( var (
ioarg *C.hcl_iosrarg_t ioarg *C.hcl_io_sciarg_t
n int n int
i int i int
buf []rune buf []rune
) )
ioarg = (*C.hcl_iosrarg_t)(arg) ioarg = (*C.hcl_io_sciarg_t)(arg)
buf = make([]rune, 1024) // TODO: different size... buf = make([]rune, 1024) // TODO: different size...
n, err = g.io.r.Read(int(uintptr(ioarg.handle)), buf) 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 //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 ( var (
g *HCL g *HCL
err error 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: case C.HCL_IO_READ:
var ( var (
ioarg *C.hcl_ioinarg_t ioarg *C.hcl_io_udiarg_t
n int n int
err error err error
buf []rune buf []rune
) )
ioarg = (*C.hcl_ioinarg_t)(arg) ioarg = (*C.hcl_io_udiarg_t)(arg)
buf = make([]rune, 1024) // TODO: different size... buf = make([]rune, 1024) // TODO: different size...
n, err = g.io.s.Read(buf) 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 //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 ( var (
g *HCL g *HCL
err error 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: case C.HCL_IO_WRITE:
var ( var (
ioarg *C.hcl_iooutarg_t ioarg *C.hcl_io_udoarg_t
data []rune data []rune
err error 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)) data = uchars_to_rune_slice((*C.hcl_uch_t)(ioarg.ptr), uintptr(ioarg.len))
err = g.io.p.Write(data) err = g.io.p.Write(data)
if err != nil { 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: case C.HCL_IO_WRITE_BYTES:
var ( var (
ioarg *C.hcl_iooutarg_t ioarg *C.hcl_io_udoarg_t
data []byte data []byte
err error err error
) )
ioarg = (*C.hcl_iooutarg_t)(arg) ioarg = (*C.hcl_io_udoarg_t)(arg)
data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len) data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len)
err = g.io.p.WriteBytes(data) err = g.io.p.WriteBytes(data)
if err != nil { if err != nil {

View File

@ -5,17 +5,17 @@ package hcl
#include <hcl-utl.h> #include <hcl-utl.h>
#include <stdlib.h> // for C.freem #include <stdlib.h> // for C.freem
extern int hcl_go_read_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_iocmd_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_iocmd_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); 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); 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); return hcl_go_print_handler(hcl, cmd, arg);
} }
*/ */
@ -181,23 +181,42 @@ func (hcl *HCL) AddBuiltinPrims() error {
return nil 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 x C.int
var io IOImplSet var or IOReadImpl
io = hcl.io or = hcl.io.r
hcl.io.r = 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.s = s
hcl.io.p = p hcl.io.p = p
x = C.hcl_attachio(hcl.c, x = C.hcl_attachudio(hcl.c,
C.hcl_ioimpl_t(C.hcl_read_handler_for_go), C.hcl_io_impl_t(C.hcl_scan_handler_for_go),
C.hcl_ioimpl_t(C.hcl_scan_handler_for_go), C.hcl_io_impl_t(C.hcl_print_handler_for_go))
C.hcl_ioimpl_t(C.hcl_print_handler_for_go))
if x <= -1 { if x <= -1 {
hcl.io = io // restore the io handler set due to attachment failure //restore the io handlers set due to attachment failure
return fmt.Errorf("unable to attach I/O handlers - %s", hcl.get_errmsg()) hcl.io.s = os
hcl.io.p = op
return fmt.Errorf("unable to attach user data stream handlers - %s", hcl.get_errmsg())
} }
return nil return nil
} }

View File

@ -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_ignite(proto->hcl, worker->server->cfg.actor_heap_size) <= -1) goto oops;
if (hcl_addbuiltinprims(proto->hcl) <= -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; return proto;
oops: oops:

View File

@ -219,6 +219,10 @@ void hcl_fini (hcl_t* hcl)
/* deregister all callbacks */ /* deregister all callbacks */
while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist); while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist);
/* detach the user data io handlers just in case */
hcl_detachudio (hcl);
if (hcl->sem_list) if (hcl->sem_list)
{ {
hcl_freemem (hcl, hcl->sem_list); hcl_freemem (hcl, hcl->sem_list);

View File

@ -2240,36 +2240,54 @@ HCL_EXPORT hcl_ooch_t* hcl_readbasesrraw (
hcl_oow_t* xlen hcl_oow_t* xlen
); );
HCL_EXPORT int hcl_attachio (
HCL_EXPORT int hcl_attachscio (
hcl_t* hcl, hcl_t* hcl,
hcl_io_impl_t sci_rdr, /* source code input handler */ hcl_io_impl_t sci_rdr
hcl_io_impl_t udi_rdr, /* user data input handler */
hcl_io_impl_t udo_wrtr /* user data output handler */
); );
HCL_EXPORT int hcl_attachiostdwithbcstr ( HCL_EXPORT void hcl_detachscio (
hcl_t* hcl,
const hcl_bch_t* read_file,
const hcl_bch_t* scan_file,
const hcl_bch_t* print_file
);
HCL_EXPORT int hcl_attachiostdwithucstr (
hcl_t* hcl,
const hcl_uch_t* read_file,
const hcl_uch_t* scan_file,
const hcl_uch_t* print_file
);
HCL_EXPORT int hcl_isstdreadertty (
hcl_t* hcl 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_uch_t* sci_file
);
HCL_EXPORT int hcl_attachsciostdwithbcstr (
hcl_t* hcl,
const hcl_bch_t* sci_file
);
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_EXPORT void hcl_detachio (
hcl_t* hcl hcl_t* hcl
); );
HCL_EXPORT void hcl_flushio ( HCL_EXPORT void hcl_flushudio (
hcl_t* hcl hcl_t* hcl
); );

View File

@ -2413,7 +2413,7 @@ static int feed_from_includee (hcl_t* hcl)
int hcl_beginfeed (hcl_t* hcl, hcl_on_cnode_t on_cnode) 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); init_feed (hcl);
if (on_cnode) hcl->c->feed.on_cnode = on_cnode; 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); clear_sr_names (hcl);
if (hcl->c->tok.name.ptr) hcl_freemem (hcl, hcl->c->tok.name.ptr); 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_freemem (hcl, hcl->c);
hcl->c = HCL_NULL; hcl->c = HCL_NULL;
@ -2786,13 +2786,11 @@ static int init_compiler (hcl_t* hcl)
return 0; 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 n;
int inited_compiler = 0; int inited_compiler = 0;
hcl_io_sciarg_t new_sciarg; hcl_io_sciarg_t new_sciarg;
hcl_io_udiarg_t new_udiarg;
hcl_io_udoarg_t new_udoarg;
if (!hcl->c) 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; inited_compiler = 1;
} }
if (sci_rdr) if (sci_rdr)
{ {
/* The name field and the includer field are HCL_NULL /* 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 */ /* open the top-level source input stream */
n = sci_rdr(hcl, HCL_IO_OPEN, &new_sciarg); n = sci_rdr(hcl, HCL_IO_OPEN, &new_sciarg);
if (n <= -1) goto oops; 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) if (hcl->c->sci_rdr)
{ {
/* close the old source input stream */ /* 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_rdr = sci_rdr;
hcl->c->sci_arg = new_sciarg; 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 unneeded source stream names */
/*clear_sr_names (hcl); <---- TODO: tricky to clean up here */ /*clear_sr_names (hcl); <---- TODO: tricky to clean up here */
@ -2888,12 +2835,7 @@ oops:
return -1; return -1;
} }
void hcl_flushio (hcl_t* hcl) void hcl_detachscio (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)
{ {
/* an error occurred and control has reached here /* an error occurred and control has reached here
* probably, some included files might not have been * 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, HCL_IO_CLOSE, hcl->c->curinp);
hcl->c->sci_rdr = HCL_NULL; /* ready for another attachment */ 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) if (hcl->io.udi_rdr)
{ {
hcl->io.udi_rdr (hcl, HCL_IO_CLOSE, &hcl->io.udi_arg); 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) void hcl_setbasesrloc (hcl_t* hcl, hcl_oow_t line, hcl_oow_t colm)
{ {
hcl->c->sci_arg.line = line; hcl->c->sci_arg.line = line;

166
lib/std.c
View File

@ -288,11 +288,9 @@ struct xtn_t
* set these two field and reset them at the end. * set these two field and reset them at the end.
* since hcl_attachio() callls the open handler, these fields * since hcl_attachio() callls the open handler, these fields
* are valid only inside the open handelr */ * are valid only inside the open handelr */
const char* read_path; /* main source file */ const char* sci_path; /* main source file */
const char* scan_path; /* runtime input file */ const char* udi_path; /* runtime input file */
const char* print_path; /* runtime output file */ const char* udo_path; /* runtime output file */
int reader_istty;
int vm_running; int vm_running;
int rcv_tick; int rcv_tick;
@ -3241,42 +3239,38 @@ static HCL_INLINE int open_sci_stream (hcl_t* hcl, hcl_io_sciarg_t* arg)
#endif #endif
bb->fp = fopen(bb->fn, FOPEN_R_FLAGS); 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 else
{ {
/* main stream */ /* main stream */
hcl_oow_t pathlen; 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))); bb = (bb_t*)hcl_callocmem(hcl, HCL_SIZEOF(*bb) + (HCL_SIZEOF(hcl_bch_t) * (pathlen + 1)));
if (!bb) goto oops; if (!bb) goto oops;
bb->fn = (hcl_bch_t*)(bb + 1); 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); /*bb->fp = fopen(bb->fn, FOPEN_R_FLAGS);*/
} }
else else
{ {
bb->fn[0] = '\0'; 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 (!arg->includer) /* if main stream */
{ {
#if defined(HAVE_ISATTY)
xtn->reader_istty = isatty(fileno(bb->fp));
#endif
/* HACK */ /* HACK */
HCL_ASSERT (hcl, arg->name == HCL_NULL); HCL_ASSERT (hcl, arg->name == HCL_NULL);
arg->name = hcl_dupbtooocstr(hcl, bb->fn, 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_t* bb;
bb = (bb_t*)arg->handle; 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 */ /* HACK */
if (!arg->includer && arg->name) if (!arg->includer && arg->name)
{ {
/* main stream closing */
hcl_freemem (hcl, arg->name); hcl_freemem (hcl, arg->name);
arg->name = HCL_NULL; arg->name = HCL_NULL;
} }
/* END HACK */ /* END HACK */
if (bb->fp != stdin) fclose (bb->fp); if (bb->fp /*&& bb->fp != stdin*/) fclose (bb->fp);
hcl_freemem (hcl, bb); hcl_freemem (hcl, bb);
arg->handle = HCL_NULL; 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; 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))); bb = (bb_t*)hcl_callocmem(hcl, HCL_SIZEOF(*bb) + (HCL_SIZEOF(hcl_bch_t) * (pathlen + 1)));
if (!bb) goto oops; if (!bb) goto oops;
bb->fn = (hcl_bch_t*)(bb + 1); 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); bb->fp = fopen(bb->fn, FOPEN_R_FLAGS);
} }
else else
@ -3503,7 +3498,7 @@ static HCL_INLINE int read_in_stream (hcl_t* hcl, hcl_io_udiarg_t* arg)
return 0; 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) 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" #define FOPEN_W_FLAGS "w"
#endif #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 (!fp)
{ {
if (xtn->print_path) if (xtn->udo_path)
hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", xtn->print_path); hcl_seterrbfmt (hcl, HCL_EIOERR, "unable to open %hs", xtn->udo_path);
else else
hcl_seterrnum (hcl, HCL_EIOERR); hcl_seterrnum (hcl, HCL_EIOERR);
return -1; return -1;
@ -3632,7 +3627,7 @@ static HCL_INLINE int flush_out_stream (hcl_t* hcl, hcl_io_udoarg_t* arg)
return 0; 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) 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); xtn_t* xtn = GET_XTN(hcl);
int n; int n;
HCL_ASSERT (hcl, xtn->read_path == HCL_NULL); HCL_ASSERT (hcl, xtn->sci_path == HCL_NULL);
HCL_ASSERT (hcl, xtn->scan_path == HCL_NULL);
HCL_ASSERT (hcl, xtn->print_path == HCL_NULL);
xtn->read_path = read_file; xtn->sci_path = sci_file;
xtn->scan_path = scan_file;
xtn->print_path = print_file;
n = hcl_attachio(hcl, sci_handler, scan_handler, print_handler); n = hcl_attachscio(hcl, sci_handler);
xtn->read_path = HCL_NULL; xtn->sci_path = HCL_NULL;
xtn->scan_path = HCL_NULL;
xtn->print_path = HCL_NULL;
return n; 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); xtn_t* xtn = GET_XTN(hcl);
int n; int n;
HCL_ASSERT (hcl, xtn->read_path == HCL_NULL); HCL_ASSERT (hcl, xtn->sci_path == HCL_NULL);
HCL_ASSERT (hcl, xtn->scan_path == HCL_NULL);
HCL_ASSERT (hcl, xtn->print_path == HCL_NULL);
xtn->read_path = hcl_duputobcstr(hcl, read_file, HCL_NULL); xtn->sci_path = hcl_duputobcstr(hcl, sci_file, HCL_NULL);
if (HCL_UNLIKELY(!xtn->read_path)) return -1; if (HCL_UNLIKELY(!xtn->sci_path)) return -1;
xtn->scan_path = hcl_duputobcstr(hcl, scan_file, HCL_NULL); n = hcl_attachscio(hcl, sci_handler);
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); hcl_freemem (hcl, (void*)xtn->sci_path);
if (HCL_UNLIKELY(!xtn->print_path)) xtn->sci_path = HCL_NULL;
{
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;
return n; 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); 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;
}

View File

@ -87,7 +87,13 @@ func main() {
goto oops 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 { if err != nil {
fmt.Printf("Error: %s\n", err.Error()) fmt.Printf("Error: %s\n", err.Error())
goto oops goto oops