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

fixed the union issue in go wrapper code
This commit is contained in:
hyung-hwan 2024-02-22 01:21:11 +09:00
parent c260301db1
commit 308b39d50b
3 changed files with 117 additions and 32 deletions

View File

@ -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");
xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */
show_prompt (hcl, 0);
}
else
execute_in_interactive_mode (hcl);
{
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);
}
}
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);
while (1)
if (is_tty)
{
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;
}
show_prompt (hcl, 0);
bch = ch;
if (hcl_feedbchars(hcl, &bch, 1) <= -1)
while (1)
{
int n;
/* 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)
{
print_error (hcl, "failed to feed");
show_prompt (hcl, 0);
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
}
else
{
while (1)
{
hcl_bch_t buf[1024];
hcl_oow_t xlen;

View File

@ -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
}

View File

@ -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)
{