diff --git a/go/cb.go b/go/cb.go index 9ddfbd8..76311ea 100644 --- a/go/cb.go +++ b/go/cb.go @@ -10,6 +10,7 @@ import ( "bufio" "io" "os" + "path" "sync" "unsafe" ) @@ -103,15 +104,15 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in } if ioarg.includer == nil || ioarg.includer.name == nil { - includer_name = "" + includer_name = g.io.cci_main } else { var k []rune = ucstr_to_rune_slice(ioarg.includer.name) includer_name = string(k) } - fd, err = g.io.r.Open(g, name, includer_name) + fd, err = g.io.cci.Open(g, name, includer_name) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } @@ -120,7 +121,7 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in case C.HCL_IO_CLOSE: var ioarg *C.hcl_io_cciarg_t = (*C.hcl_io_cciarg_t)(arg) - g.io.r.Close(int(uintptr(ioarg.handle))) + g.io.cci.Close(int(uintptr(ioarg.handle))) return 0 case C.HCL_IO_READ: @@ -133,9 +134,9 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in ioarg = (*C.hcl_io_cciarg_t)(arg) buf = make([]rune, 1024) // TODO: different size... - n, err = g.io.r.Read(int(uintptr(ioarg.handle)), buf) + n, err = g.io.cci.Read(int(uintptr(ioarg.handle)), buf) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } @@ -161,9 +162,9 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in switch cmd { case C.HCL_IO_OPEN: - err = g.io.s.Open(g) + err = g.io.udi.Open(g) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } @@ -172,7 +173,7 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in return 0 case C.HCL_IO_CLOSE: - g.io.s.Close() + g.io.udi.Close() return 0 case C.HCL_IO_READ: @@ -185,9 +186,9 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in ioarg = (*C.hcl_io_udiarg_t)(arg) buf = make([]rune, 1024) // TODO: different size... - n, err = g.io.s.Read(buf) + n, err = g.io.udi.Read(buf) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } ioarg.xlen = C.ulong(n) @@ -209,9 +210,9 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in switch cmd { case C.HCL_IO_OPEN: - err = g.io.p.Open(g) + err = g.io.udo.Open(g) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } @@ -220,7 +221,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in return 0 case C.HCL_IO_CLOSE: - g.io.p.Close() + g.io.udo.Close() return 0 case C.HCL_IO_WRITE: @@ -231,9 +232,9 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in ) 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) + err = g.io.udo.Write(data) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } ioarg.xlen = C.hcl_oow_t(len(data)) @@ -247,18 +248,18 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in ) ioarg = (*C.hcl_io_udoarg_t)(arg) data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len) - err = g.io.p.WriteBytes(data) + err = g.io.udo.WriteBytes(data) if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } ioarg.xlen = C.hcl_oow_t(len(data)) return 0 case C.HCL_IO_FLUSH: - var err error = g.io.p.Flush() + var err error = g.io.udo.Flush() if err != nil { - g.set_errmsg (C.HCL_EIOERR, err.Error()) + g.set_errmsg(C.HCL_EIOERR, err.Error()) return -1 } return 0 @@ -284,7 +285,14 @@ func (p *CciFileHandler) Open(g *HCL, name string, includer_name string) (int, e if name == "" { f = os.Stdin } else { - f, err = os.Open(name) + var dir string + + dir = path.Dir(includer_name) + if dir != "/" && dir != "" { + dir = dir + "/" + } + + f, err = os.Open(dir + name) if err != nil { return -1, err } @@ -377,7 +385,7 @@ func (p *UdiFileHandler) Read(buf []rune) (int, error) { ) // flush all pending print out before reading - p.g.io.p.Flush() + p.g.io.udo.Flush() for i = 0; i < len(buf); i++ { c, _, err = p.r.ReadRune() diff --git a/go/hcl.go b/go/hcl.go index 18f625f..5ca8e2c 100644 --- a/go/hcl.go +++ b/go/hcl.go @@ -3,7 +3,7 @@ package hcl /* #include #include -#include // for C.freem +#include // for C.free extern int hcl_go_cci_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg); extern int hcl_go_udi_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg); @@ -30,19 +30,19 @@ import ( "unsafe" ) -type IOReadImpl interface { +type CciImpl interface { Open(g *HCL, name string, includer_name string) (int, error) Close(fd int) Read(fd int, buf []rune) (int, error) } -type IOScanImpl interface { +type UdiImpl interface { Open(g *HCL) error Close() Read(buf []rune) (int, error) } -type IOPrintImpl interface { +type UdoImpl interface { Open(g *HCL) error Close() Write(data []rune) error @@ -50,16 +50,15 @@ type IOPrintImpl interface { Flush() error } -type IOImplSet struct { - r IOReadImpl - s IOScanImpl - p IOPrintImpl -} - type HCL struct { c *C.hcl_t inst_no int - io IOImplSet + io struct { + cci CciImpl + cci_main string + udi UdiImpl + udo UdoImpl + } } type Ext struct { @@ -110,53 +109,53 @@ func (hcl *HCL) Close() { deregister_instance(hcl) } -func (hcl *HCL) GetLogMask () BitMask { +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())) + panic(fmt.Errorf("unable to get log mask - %s", hcl.get_errmsg())) } return log_mask } -func (hcl *HCL) SetLogMask (log_mask BitMask) { +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)); + 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())) + panic(fmt.Errorf("unable to set log mask - %s", hcl.get_errmsg())) } } -func (hcl *HCL) GetLogTarget () string { +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)); + 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())) + panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg())) } return C.GoString(tgt) } -func (hcl *HCL) SetLogTarget (target string) { +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)); + 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())) + panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg())) } } @@ -181,41 +180,49 @@ func (hcl *HCL) AddBuiltinPrims() error { return nil } -func (hcl *HCL) AttachCCIO(r IOReadImpl) error { +// the name of the main cci stream is required because: +// - the main stream is not handled by this IO handler +// - the feeder must read the main stream and pass data. +// - the inclusion of another file from the main stream requires the path information of the main strea. +func (hcl *HCL) AttachCCIO(cci CciImpl, main_cci_name string) error { var x C.int - var or IOReadImpl + var old_cci CciImpl + var old_cci_name string - or = hcl.io.r + old_cci = hcl.io.cci + old_cci_name = hcl.io.cci_main - hcl.io.r = r + hcl.io.cci = cci + hcl.io.cci_main = main_cci_name x = C.hcl_attachccio(hcl.c, C.hcl_io_impl_t(C.hcl_cci_Handler_for_go)) if x <= -1 { // restore the io handler set due to attachment failure - hcl.io.r = or + hcl.io.cci_main = old_cci_name + hcl.io.cci = old_cci 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 { +func (hcl *HCL) AttachUDIO(udi UdiImpl, udo UdoImpl) error { var x C.int - var os IOScanImpl - var op IOPrintImpl + var os UdiImpl + var op UdoImpl - os = hcl.io.s - op = hcl.io.p + os = hcl.io.udi + op = hcl.io.udo - hcl.io.s = s - hcl.io.p = p + hcl.io.udi = udi + hcl.io.udo = udo x = C.hcl_attachudio(hcl.c, C.hcl_io_impl_t(C.hcl_udi_handler_for_go), C.hcl_io_impl_t(C.hcl_udo_handler_for_go)) if x <= -1 { //restore the io handlers set due to attachment failure - hcl.io.s = os - hcl.io.p = op + hcl.io.udi = os + hcl.io.udo = op return fmt.Errorf("unable to attach user data stream handlers - %s", hcl.get_errmsg()) } return nil @@ -281,7 +288,7 @@ func (hcl *HCL) FeedFromReader(rdr io.Reader) error { return fmt.Errorf("unable to read bytes - %s", err.Error()) } - x = C.hcl_feedbchars(hcl.c, (*C.hcl_bch_t)(unsafe.Pointer(&buf[0])), C.hcl_oow_t(n)); + x = C.hcl_feedbchars(hcl.c, (*C.hcl_bch_t)(unsafe.Pointer(&buf[0])), C.hcl_oow_t(n)) if x <= -1 { return fmt.Errorf("unable to feed bytes - %s", hcl.get_errmsg()) } @@ -290,11 +297,11 @@ func (hcl *HCL) FeedFromReader(rdr io.Reader) error { return nil } -func (hcl *HCL) FeedFromFile (file string) error { +func (hcl *HCL) FeedFromFile(file string) error { var f *os.File var err error - f, err = os.Open(file); + f, err = os.Open(file) if err != nil { return fmt.Errorf("unable to open %s - %s", file, err.Error()) } @@ -327,11 +334,11 @@ func (hcl *HCL) Decode() error { return nil } -func (hcl *HCL) get_errmsg () string { +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) { +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)) @@ -357,13 +364,13 @@ func uchars_to_rune_slice(str *C.hcl_uch_t, len uintptr) []rune { return res } -func string_to_uchars (str string) []C.hcl_uch_t { +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); + 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]) @@ -372,7 +379,7 @@ func string_to_uchars (str string) []C.hcl_uch_t { return c } -func rune_slice_to_uchars (r []rune) []C.hcl_uch_t { +func rune_slice_to_uchars(r []rune) []C.hcl_uch_t { var c []C.hcl_uch_t var i int diff --git a/main.go b/main.go index bda9b3d..e620468 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ import ( */ type Param struct { - log_file string + log_file string input_file string } @@ -29,9 +29,9 @@ func handle_arguments(param *Param) error { var i int for i = 1; i < nargs; i++ { - if strings.HasPrefix(os.Args[i], "--log=") { + if strings.HasPrefix(os.Args[i], "--log=") { param.log_file = os.Args[i][6:] - } else if (os.Args[i] == "--log") { + } else if os.Args[i] == "--log" { i++ param.log_file = os.Args[i] } else if strings.HasPrefix(os.Args[i], "--") || strings.HasPrefix(os.Args[i], "-") { @@ -59,7 +59,7 @@ func main() { var sfh hcl.UdiFileHandler var pfh hcl.UdoFileHandler - err = handle_arguments(¶m); + err = handle_arguments(¶m) if err != nil { fmt.Printf("Error: %s\n", err.Error()) os.Exit(1) @@ -72,8 +72,8 @@ func main() { } if param.log_file != "" { - x.SetLogMask (^hcl.BitMask(0)) - x.SetLogTarget ("/dev/stderr") + x.SetLogMask(^hcl.BitMask(0)) + x.SetLogTarget("/dev/stderr") } err = x.Ignite(1000000) @@ -87,7 +87,7 @@ func main() { goto oops } - err = x.AttachCCIO(&rfh) + err = x.AttachCCIO(&rfh, param.input_file) if err != nil { fmt.Printf("Error: %s\n", err.Error()) goto oops @@ -99,7 +99,7 @@ func main() { goto oops } - err = x.BeginFeed(); + err = x.BeginFeed() if err != nil { fmt.Printf("Error: %s\n", err.Error()) goto oops @@ -122,7 +122,7 @@ func main() { } x.Decode() - x.SetLogMask (0) + x.SetLogMask(0) err = x.Execute() if err != nil {