From 7ccc1ce136569d3bc1840fd8410db0b15f5def63 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 1 Nov 2023 16:06:28 +0900 Subject: [PATCH] enhanced the go wrapper by adding more methods and cleaning up code --- go/cb.go | 26 ++++---- go/hcl.go | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++--- lib/read.c | 2 +- main.go | 122 +++++++++--------------------------- 4 files changed, 210 insertions(+), 118 deletions(-) diff --git a/go/cb.go b/go/cb.go index 71f03be..b6e1a73 100644 --- a/go/cb.go +++ b/go/cb.go @@ -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 } diff --git a/go/hcl.go b/go/hcl.go index 6333e69..7cfa610 100644 --- a/go/hcl.go +++ b/go/hcl.go @@ -3,6 +3,7 @@ package hcl /* #include #include +#include // 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 diff --git a/lib/read.c b/lib/read.c index 2ad9d52..27823b8 100644 --- a/lib/read.c +++ b/lib/read.c @@ -896,7 +896,7 @@ static int feed_begin_include (hcl_t* hcl) if (hcl->c->reader(hcl, HCL_IO_OPEN, arg) <= -1) { const hcl_ooch_t* org_errmsg = hcl_backuperrmsg(hcl); - hcl_setsynerrbfmt (hcl, HCL_SYNERR_INCLUDE, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "unable to feed-include %js - %js", io_name, org_errmsg); + hcl_setsynerrbfmt (hcl, HCL_SYNERR_INCLUDE, TOKEN_LOC(hcl), TOKEN_NAME(hcl), "unable to include %js - %js", io_name, org_errmsg); goto oops; } diff --git a/main.go b/main.go index 659bf7e..ed76065 100644 --- a/main.go +++ b/main.go @@ -1,33 +1,5 @@ package main -/* -#cgo CFLAGS: -I/home/hyung-hwan/xxx/include -g -Wall -#cgo LDFLAGS: -L/home/hyung-hwan/xxx/lib -lhcl -ldl -lquadmath - -#include -#include - -extern int go_read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg); -extern int go_scan_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg); -extern int go_print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg); - -int read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) -{ - return go_read_handler(hcl, cmd, arg); -} - -int scan_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) -{ - return go_scan_handler(hcl, cmd, arg); -} - -int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg) -{ - return go_print_handler(hcl, cmd, arg); -} -*/ -//import "C" - import ( _ "cfg" "fmt" @@ -37,8 +9,6 @@ import ( ) /* - func run_hcl() { - var hcl *C.hcl_t = C.hcl_openstd(0, nil) var src []uint16 = utf16.Encode(([]rune)( `(printf ">>>>>>>>> [%d]\n" (+ 30 455)) @@ -46,62 +16,8 @@ import ( #include "a.hcl" (printf ">>>>>>>>> [%d]\n" (+ 20 455)) `)) - - if hcl == nil { - log.Printf("Unable to open HCL\n") - } else { - var ( - x C.int - logmask C.hcl_bitmask_t - tgt *C.char - empty *C.char - r C.hcl_oop_t - ) - - logmask = ^C.hcl_bitmask_t(0) - tgt = C.CString("/dev/stderr") - defer C.free(unsafe.Pointer(tgt)) - - empty = C.CString("") - defer C.free(unsafe.Pointer(empty)) - - C.hcl_setoption(hcl, C.HCL_LOG_MASK, unsafe.Pointer(&logmask)) - C.hcl_setoption(hcl, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(tgt)) - - _ = C.hcl_ignite(hcl, 1000000) - //fmt.Printf ("ignire %d\n", x) - _ = C.hcl_addbuiltinprims(hcl) - //fmt.Printf ("addbuiltinprims %d\n", x) - //_ = C.hcl_attachiostdwithbcstr(hcl, empty, empty, empty) - //x = C.hcl_attachio(hcl, (*[0]byte)(C.read_handler), (*[0]byte)(C.scan_handler), (*[0]byte)(C.print_handler)) - x = C.hcl_attachio(hcl, C.hcl_ioimpl_t(C.read_handler), C.hcl_ioimpl_t(C.scan_handler), C.hcl_ioimpl_t(C.print_handler)) - if x <= -1 { - log.Printf("unable to attach IO handlers - %d - %s\n", x, C.GoString(C.hcl_geterrbmsg(hcl))) - goto done - } - _ = C.hcl_beginfeed(hcl, nil) - //fmt.Printf ("beginfeed %d\n", x) - _ = C.hcl_feed(hcl, (*C.ushort)(&src[0]), (C.ulong)(len(src))) - //fmt.Printf ("feed %d\n", x) - _ = C.hcl_endfeed(hcl) - //fmt.Printf ("endfeed %d => bclen %d\n", x, C.hcl_getbclen(hcl)) - _ = x - - C.hcl_decode(hcl, 0, C.hcl_getbclen(hcl)) - logmask = 0 - C.hcl_setoption(hcl, C.HCL_LOG_MASK, unsafe.Pointer(&logmask)) - r = C.hcl_execute(hcl) - if r == nil { - fmt.Printf("Error - %s\n", C.GoString(C.hcl_geterrbmsg(hcl))) - } - - done: - C.hcl_close(hcl) - } - } */ func main() { - //run_hcl() var x *hcl.HCL = nil var err error = nil @@ -112,31 +28,53 @@ func main() { x, err = hcl.New() if err != nil { - fmt.Printf("ERROR failed to instantiate hcl - %s\n", err.Error()) + fmt.Printf("Error: failed to instantiate hcl - %s\n", err.Error()) os.Exit(1) } + + x.SetLogMask (^hcl.BitMask(0)) + x.SetLogTarget ("/dev/stderr") + err = x.Ignite(1000000) if err != nil { - fmt.Printf("ERROR failed to ignite - %s\n", err.Error()) + fmt.Printf("Error: failed to ignite - %s\n", err.Error()) goto oops } err = x.AddBuiltinPrims() if err != nil { - fmt.Printf("ERROR failed to add builtin primitives - %s\n", err.Error()) + fmt.Printf("Error: failed to add builtin primitives - %s\n", err.Error()) goto oops } err = x.AttachIO(&rfh, &sfh, &pfh) if err != nil { - fmt.Printf("Error - %s", err.Error()) + fmt.Printf("Error: %s\n", err.Error()) + goto oops } - x.FeedString([]rune(`(printf ">>>>>>>>> [%d]\n" (+ 30 455)) + + err = x.FeedString(`(printf ">>>>>>>>> [%d]\n" (+ 30 455)) (printf ">>>>>>>>> [%d]\n" (+ 11 455)) #include "a.hcl" - (printf ">>>>>>>>> [%d]\n" (+ 20 455))`)) + (printf ">>>>>>>>> [%d]\n" (+ 20 455))`) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + goto oops + } - x.EndFeed() - x.Execute() + err = x.EndFeed() + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + goto oops + } + + x.Decode() + x.SetLogMask (0) + + err = x.Execute() + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + goto oops + } x.Close()