change to read a line before starting to feed input in the interactive mode
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
fixed the union issue in go wrapper code
This commit is contained in:
parent
c260301db1
commit
308b39d50b
112
bin/main.c
112
bin/main.c
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include <hcl.h>
|
||||
#include <hcl-chr.h>
|
||||
#include <hcl-utl.h>
|
||||
#include <hcl-opt.h>
|
||||
|
||||
@ -103,6 +104,15 @@ struct xtn_t
|
||||
const char* udo_path;
|
||||
|
||||
int vm_running;
|
||||
|
||||
struct
|
||||
{
|
||||
hcl_bch_t buf[1024];
|
||||
hcl_oow_t len;
|
||||
hcl_oow_t pos;
|
||||
int eof;
|
||||
int ongoing;
|
||||
} feed;
|
||||
/*hcl_oop_t sym_errstr;*/
|
||||
};
|
||||
|
||||
@ -492,26 +502,82 @@ static hcl_oop_t execute_in_batch_mode(hcl_t* hcl, int verbose)
|
||||
static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
int flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
|
||||
int flags = 0;
|
||||
|
||||
/* in the interactive, the compile error must not break the input loop.
|
||||
* this function returns 0 to go on despite a compile-time error */
|
||||
* this function returns 0 to go on despite a compile-time error.
|
||||
*
|
||||
* if a single line or continued lines contain multiple expressions,
|
||||
* execution is delayed until the last expression is compiled. */
|
||||
|
||||
if (!xtn->feed.ongoing)
|
||||
{
|
||||
flags = HCL_COMPILE_CLEAR_CODE | HCL_COMPILE_CLEAR_FNBLK;
|
||||
xtn->feed.ongoing = 1;
|
||||
}
|
||||
|
||||
if (hcl_compile(hcl, obj, flags) <= -1)
|
||||
{
|
||||
print_error(hcl, "failed to compile");
|
||||
else
|
||||
execute_in_interactive_mode (hcl);
|
||||
|
||||
xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */
|
||||
show_prompt (hcl, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcl_oow_t i;
|
||||
for (i = xtn->feed.pos; i < xtn->feed.len; i++)
|
||||
{
|
||||
if (!hcl_is_bch_space(xtn->feed.buf[i])) break;
|
||||
}
|
||||
|
||||
if (i >= xtn->feed.len || xtn->feed.pos >= xtn->feed.len)
|
||||
{
|
||||
/* nothing more to feed */
|
||||
execute_in_interactive_mode (hcl);
|
||||
xtn->feed.ongoing = 0;
|
||||
show_prompt (hcl, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_fed_cnode_in_batch_mode (hcl_t* hcl, hcl_cnode_t* obj)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
|
||||
/*xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);*/
|
||||
return hcl_compile(hcl, obj, 0);
|
||||
}
|
||||
|
||||
static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp)
|
||||
{
|
||||
if (xtn->feed.eof) return 0;
|
||||
|
||||
xtn->feed.pos = 0;
|
||||
xtn->feed.len = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int ch = fgetc(fp);
|
||||
if (ch == EOF)
|
||||
{
|
||||
if (ferror(fp))
|
||||
{
|
||||
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: failed to read - %hs - %hs\n", xtn->cci_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
xtn->feed.eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TOTO: buffer check... */
|
||||
xtn->feed.buf[xtn->feed.len++] = (hcl_bch_t)(unsigned int)ch;
|
||||
if (ch == '\n') break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose)
|
||||
{
|
||||
FILE* fp = HCL_NULL;
|
||||
@ -548,32 +614,34 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose)
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (is_tty) show_prompt (hcl, 0);
|
||||
if (is_tty)
|
||||
{
|
||||
show_prompt (hcl, 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (is_tty)
|
||||
{
|
||||
hcl_bch_t bch;
|
||||
int ch = fgetc(fp);
|
||||
if (ch == EOF)
|
||||
{
|
||||
if (ferror(fp))
|
||||
{
|
||||
hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: failed to read - %hs - %hs\n", xtn->cci_path, strerror(errno));
|
||||
goto oops;
|
||||
}
|
||||
break;
|
||||
}
|
||||
int n;
|
||||
|
||||
bch = ch;
|
||||
if (hcl_feedbchars(hcl, &bch, 1) <= -1)
|
||||
/* read a while line regardless of the actual expression */
|
||||
n = get_line(hcl, xtn, fp);
|
||||
if (n <= -1) goto oops;
|
||||
if (n == 0) break;
|
||||
|
||||
/* feed the line */
|
||||
while (xtn->feed.pos < xtn->feed.len)
|
||||
{
|
||||
hcl_bch_t c = xtn->feed.buf[xtn->feed.pos++];
|
||||
if (hcl_feedbchars(hcl, &c, 1) <= -1)
|
||||
{
|
||||
print_error (hcl, "failed to feed");
|
||||
show_prompt (hcl, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
hcl_bch_t buf[1024];
|
||||
hcl_oow_t xlen;
|
||||
|
21
go/cb.go
21
go/cb.go
@ -3,6 +3,7 @@ package hcl
|
||||
/*
|
||||
#include <hcl.h>
|
||||
#include <hcl-utl.h>
|
||||
#include <string.h> // for memcpy
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@ -130,6 +131,7 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
||||
n int
|
||||
i int
|
||||
buf []rune
|
||||
dummy C.hcl_uch_t
|
||||
)
|
||||
ioarg = (*C.hcl_io_cciarg_t)(arg)
|
||||
|
||||
@ -140,9 +142,24 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
||||
return -1
|
||||
}
|
||||
|
||||
for i = 0; i < n; i++ { // TODO: use a proper conversion when the rune size is different from hio_uch_t
|
||||
ioarg.buf[i] = C.hcl_uch_t(buf[i])
|
||||
ioarg.is_bytes = 0
|
||||
if unsafe.Sizeof(buf[0]) == unsafe.Sizeof(dummy) {
|
||||
C.memcpy (
|
||||
unsafe.Pointer(&ioarg.buf[0]),
|
||||
unsafe.Pointer(&buf[0]),
|
||||
C.size_t(unsafe.Sizeof(buf[0]) * uintptr(n)))
|
||||
} else {
|
||||
var dst uintptr
|
||||
// work around cgo's union issue. not able to access individual union
|
||||
// member fields. cgo treats union as byte aggregates.
|
||||
dst = uintptr(unsafe.Pointer(&ioarg.buf[0]))
|
||||
for i = 0; i < n; i++ {
|
||||
//ioarg.buf.c[i] = C.hcl_uch_t(buf[i])
|
||||
*(*C.hcl_uch_t)(unsafe.Pointer(dst)) = C.hcl_uch_t(buf[i]);
|
||||
dst += unsafe.Sizeof(dummy)
|
||||
}
|
||||
}
|
||||
|
||||
ioarg.xlen = C.hcl_oow_t(n)
|
||||
return 0
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ static int init_compiler (hcl_t* hcl);
|
||||
|
||||
static HCL_INLINE int is_spacechar (hcl_ooci_t c)
|
||||
{
|
||||
/* TODO: handle other space unicode characters */
|
||||
#if 0
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
@ -181,6 +181,9 @@ static HCL_INLINE int is_spacechar (hcl_ooci_t c)
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return c != HCL_OOCI_EOF && hcl_is_ooch_space(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
static HCL_INLINE int is_linebreak (hcl_ooci_t c)
|
||||
@ -3507,7 +3510,6 @@ int hcl_attachccio (hcl_t* hcl, hcl_io_impl_t cci_rdr)
|
||||
inited_compiler = 1;
|
||||
}
|
||||
|
||||
|
||||
if (cci_rdr)
|
||||
{
|
||||
/* The name field and the includer field are HCL_NULL
|
||||
@ -3650,8 +3652,6 @@ void hcl_flushudio (hcl_t* hcl)
|
||||
if (hcl->io.udo_wrtr) hcl->io.udo_wrtr (hcl, HCL_IO_FLUSH, &hcl->io.udo_arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TODO: discard the fwollowing three functions - hcl_setbasesrloc, hcl_readbasesrchar */
|
||||
void hcl_setbasesrloc (hcl_t* hcl, hcl_oow_t line, hcl_oow_t colm)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user