enhanced the go wrapper by adding more methods and cleaning up code
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-11-01 16:06:28 +09:00
parent 85a2152be4
commit 7ccc1ce136
4 changed files with 210 additions and 118 deletions

View File

@ -7,15 +7,11 @@ package hcl
import "C"
import (
// "bufio"
// "io"
"bufio"
"io"
"os"
"sync"
"unsafe"
// "sync"
// "unsafe"
)
type IOHandle struct {
@ -115,7 +111,7 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in
fd, err = g.io.r.Open(g, name, includer_name)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
@ -139,7 +135,7 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in
buf = make([]rune, 1024) // TODO: different size...
n, err = g.io.r.Read(int(uintptr(ioarg.handle)), buf)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
@ -150,7 +146,7 @@ func hcl_go_read_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in
return 0
}
C.hcl_seterrnum(c, C.HCL_ENOIMPL)
C.hcl_seterrnum(c, C.HCL_EIOERR)
return -1
}
@ -167,7 +163,7 @@ func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in
case C.HCL_IO_OPEN:
err = g.io.s.Open(g)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
@ -191,14 +187,14 @@ func hcl_go_scan_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.in
buf = make([]rune, 1024) // TODO: different size...
n, err = g.io.s.Read(buf)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
ioarg.xlen = C.ulong(n)
return 0
}
C.hcl_seterrnum(c, C.HCL_ENOIMPL)
C.hcl_seterrnum(c, C.HCL_EIOERR)
return -1
}
@ -215,7 +211,7 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i
case C.HCL_IO_OPEN:
err = g.io.p.Open(g)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
@ -237,7 +233,7 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i
data = uchars_to_rune_slice((*C.hcl_uch_t)(ioarg.ptr), uintptr(ioarg.len))
err = g.io.p.Write(data)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
ioarg.xlen = C.hcl_oow_t(len(data))
@ -253,7 +249,7 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i
data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len)
err = g.io.p.WriteBytes(data)
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
ioarg.xlen = C.hcl_oow_t(len(data))
@ -262,13 +258,13 @@ func hcl_go_print_handler(c *C.hcl_t, cmd C.hcl_iocmd_t, arg unsafe.Pointer) C.i
case C.HCL_IO_FLUSH:
var err error = g.io.p.Flush()
if err != nil {
C.hcl_seterrbmsg(c, C.HCL_ENOIMPL, C.CString(err.Error()))
g.set_errmsg (C.HCL_EIOERR, err.Error())
return -1
}
return 0
}
C.hcl_seterrnum(c, C.HCL_ENOIMPL)
C.hcl_seterrnum(c, C.HCL_EIOERR)
return -1
}

178
go/hcl.go
View File

@ -3,6 +3,7 @@ package hcl
/*
#include <hcl.h>
#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);
@ -62,6 +63,8 @@ type Ext struct {
inst_no int
}
type BitMask C.hcl_bitmask_t
var inst_table InstanceTable
func deregister_instance(g *HCL) {
@ -104,16 +107,73 @@ func (hcl *HCL) Close() {
deregister_instance(hcl)
}
func (hcl *HCL) GetLogMask () BitMask {
var x C.int
var log_mask BitMask = 0
x = C.hcl_getoption(hcl.c, C.HCL_LOG_MASK, unsafe.Pointer(&log_mask))
if x <= -1 {
// this must not happen
panic (fmt.Errorf("unable to get log mask - %s", hcl.get_errmsg()))
}
return log_mask
}
func (hcl *HCL) SetLogMask (log_mask BitMask) {
var x C.int
x = C.hcl_setoption(hcl.c, C.HCL_LOG_MASK, unsafe.Pointer(&log_mask));
if x <= -1 {
// this must not happen
panic (fmt.Errorf("unable to set log mask - %s", hcl.get_errmsg()))
}
}
func (hcl *HCL) GetLogTarget () string {
var x C.int
var tgt *C.char
x = C.hcl_getoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(&tgt));
if x <= -1 {
// this must not happen
panic (fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
}
return C.GoString(tgt)
}
func (hcl *HCL) SetLogTarget (target string) {
var x C.int
var tgt *C.char
tgt = C.CString(target)
defer C.free(unsafe.Pointer(tgt))
x = C.hcl_setoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(tgt));
if x <= -1 {
// thist must not happen
panic (fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
}
}
func (hcl *HCL) Ignite(memsize uintptr) error {
if C.hcl_ignite(hcl.c, C.hcl_oow_t(memsize)) <= -1 {
return fmt.Errorf("unable to ignite: %s", string(ucstr_to_rune_slice(C.hcl_geterrstr(hcl.c))))
var x C.int
x = C.hcl_ignite(hcl.c, C.hcl_oow_t(memsize))
if x <= -1 {
return fmt.Errorf("unable to ignite - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) AddBuiltinPrims() error {
if C.hcl_addbuiltinprims(hcl.c) <= -1 {
var x C.int
x = C.hcl_addbuiltinprims(hcl.c)
if x <= -1 {
return fmt.Errorf("unable to add built-in primitives - %s", hcl.get_errmsg())
}
return nil
}
@ -133,23 +193,91 @@ func (hcl *HCL) AttachIO(r IOReadImpl, s IOScanImpl, p IOPrintImpl) error {
C.hcl_ioimpl_t(C.hcl_scan_handler_for_go),
C.hcl_ioimpl_t(C.hcl_print_handler_for_go))
if x <= -1 {
hcl.io = io // restore the set
return fmt.Errorf("unable to attach I/O handlers: %s", string(ucstr_to_rune_slice(C.hcl_geterrstr(hcl.c))))
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())
}
return nil
}
func (hcl *HCL) FeedString(str []rune) error {
func (hcl *HCL) FeedString(str string) error {
var x C.int
var q []C.hcl_uch_t
q = string_to_uchars(str)
x = C.hcl_feed(hcl.c, &q[0], C.hcl_oow_t(len(q)))
if x <= -1 {
return fmt.Errorf("unable to feed string - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) BeginFeed() {
func (hcl *HCL) FeedRunes(str []rune) error {
var x C.int
var q []C.hcl_uch_t
q = rune_slice_to_uchars(str)
x = C.hcl_feed(hcl.c, &q[0], C.hcl_oow_t(len(q)))
if x <= -1 {
return fmt.Errorf("unable to feed runes - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) EndFeed() {
func (hcl *HCL) BeginFeed() error {
var x C.int
x = C.hcl_beginfeed(hcl.c, nil)
if x <= -1 {
return fmt.Errorf("unable to begin feeding - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) Execute() {
func (hcl *HCL) EndFeed() error {
var x C.int
x = C.hcl_endfeed(hcl.c)
if x <= -1 {
return fmt.Errorf("unable to end feeding - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) Execute() error {
var x C.hcl_oop_t
x = C.hcl_execute(hcl.c)
if x == nil {
return fmt.Errorf("unable to execute - %s", hcl.get_errmsg())
}
// TODO: wrap C.hcl_oop_t in a go type
// and make this function to return 'x' in the wrapper
return nil
}
func (hcl *HCL) Decode() error {
var x C.int
x = C.hcl_decode(hcl.c, 0, C.hcl_getbclen(hcl.c))
if x <= -1 {
return fmt.Errorf("unable to decode byte codes - %s", hcl.get_errmsg())
}
return nil
}
func (hcl *HCL) get_errmsg () string {
return C.GoString(C.hcl_geterrbmsg(hcl.c))
}
func (hcl* HCL) set_errmsg(num C.hcl_errnum_t, msg string) {
var ptr *C.char
ptr = C.CString(msg)
defer C.free(unsafe.Pointer(ptr))
C.hcl_seterrbmsg(hcl.c, num, ptr)
}
func ucstr_to_rune_slice(str *C.hcl_uch_t) []rune {
@ -159,15 +287,45 @@ func ucstr_to_rune_slice(str *C.hcl_uch_t) []rune {
func uchars_to_rune_slice(str *C.hcl_uch_t, len uintptr) []rune {
var res []rune
var i uintptr
var ptr uintptr
// TODO: proper encoding...
ptr = uintptr(unsafe.Pointer(str))
res = make([]rune, len)
for i = 0; i < len; i++ {
res[i] = *(*rune)(unsafe.Pointer(uintptr(unsafe.Pointer(str)) + unsafe.Sizeof(*str)*i))
res[i] = rune(*(*C.hcl_uch_t)(unsafe.Pointer(ptr)))
ptr += unsafe.Sizeof(*str)
}
return res
}
func string_to_uchars (str string) []C.hcl_uch_t {
var r []rune
var c []C.hcl_uch_t
var i int
// TODO: proper encoding
r = []rune(str);
c = make([]C.hcl_uch_t, len(r), len(r))
for i = 0; i < len(r); i++ {
c[i] = C.hcl_uch_t(r[i])
}
return c
}
func rune_slice_to_uchars (r []rune) []C.hcl_uch_t {
var c []C.hcl_uch_t
var i int
// TODO: proper encoding
c = make([]C.hcl_uch_t, len(r), len(r))
for i = 0; i < len(r); i++ {
c[i] = C.hcl_uch_t(r[i])
}
return c
}
func c_to_go(c *C.hcl_t) *HCL {
var ext *Ext
var inst Instance