separted the IO handlers to the source code handler and user stream handlers
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
bcfe69feda
commit
94a44f1fd7
79
bin/main.c
79
bin/main.c
@ -71,7 +71,12 @@
|
||||
# if defined(HAVE_SIGNAL_H)
|
||||
# include <signal.h>
|
||||
# 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);
|
||||
|
28
go/cb.go
28
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 {
|
||||
|
49
go/hcl.go
49
go/hcl.go
@ -5,17 +5,17 @@ package hcl
|
||||
#include <hcl-utl.h>
|
||||
#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_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
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
58
lib/hcl.h
58
lib/hcl.h
@ -2240,36 +2240,54 @@ HCL_EXPORT hcl_ooch_t* hcl_readbasesrraw (
|
||||
hcl_oow_t* xlen
|
||||
);
|
||||
|
||||
HCL_EXPORT int hcl_attachio (
|
||||
|
||||
HCL_EXPORT int hcl_attachscio (
|
||||
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_io_impl_t sci_rdr
|
||||
);
|
||||
|
||||
HCL_EXPORT int hcl_attachiostdwithbcstr (
|
||||
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_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_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_t* hcl
|
||||
);
|
||||
|
||||
HCL_EXPORT void hcl_flushio (
|
||||
HCL_EXPORT void hcl_flushudio (
|
||||
hcl_t* hcl
|
||||
);
|
||||
|
||||
|
134
lib/read.c
134
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;
|
||||
|
166
lib/std.c
166
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 */
|
||||
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->read_path = read_file;
|
||||
xtn->scan_path = scan_file;
|
||||
xtn->print_path = print_file;
|
||||
xtn->sci_path = sci_file;
|
||||
|
||||
n = hcl_attachio(hcl, sci_handler, scan_handler, print_handler);
|
||||
n = hcl_attachscio(hcl, sci_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;
|
||||
|
||||
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;
|
||||
}
|
||||
n = hcl_attachscio(hcl, sci_handler);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user