package ph7 /* #include "ph7.h" int engine_config_err_log(ph7 *pEngine, const char **pzPtr, int *pLen) { return ph7_config(pEngine, PH7_CONFIG_ERR_LOG, pzPtr, pLen); } int vm_extract_output(ph7_vm *pVm, const char **pzPtr, int *pLen) { return ph7_vm_config(pVm, PH7_VM_CONFIG_EXTRACT_OUTPUT, pzPtr, pLen); } */ import "C" import ( "fmt" ) type ResultCode int const ( ResultCodeOK = ResultCode(C.PH7_OK) ResultCodeNoMem = ResultCode(C.PH7_NOMEM) ResultCodeAbort = ResultCode(C.PH7_ABORT) ResultCodeIOErr = ResultCode(C.PH7_IO_ERR) ResultCodeLooked = ResultCode(C.PH7_LOOKED) ResultCodeCorrupt = ResultCode(C.PH7_CORRUPT) ResultCodeCompileErr = ResultCode(C.PH7_COMPILE_ERR) ResultCodeVMErr = ResultCode(C.PH7_VM_ERR) ) func (r ResultCode) String() string { switch r { case ResultCodeOK: return "PH7_OK" case ResultCodeNoMem: return "PH7_NOMEM" case ResultCodeAbort: return "PH7_ABORT" case ResultCodeIOErr: return "PH7_IO_ERR" case ResultCodeLooked: return "PH7_LOOKED" case ResultCodeCorrupt: return "PH7_CORRUPT" case ResultCodeCompileErr: return "PH7_COMPILE_ERR" case ResultCodeVMErr: return "PH7_VM_ERR" default: return "UNKNOWN" } } type Error struct { Code ResultCode } func newError(code C.int) error { if code != C.PH7_OK { return Error{ Code: ResultCode(code), } } return nil } func (e Error) Error() string { return fmt.Sprintf("ph7: %s", e.Code) } type Engine struct { ptr *C.ph7 } func NewEngine() (Engine, error) { var engine Engine result := C.ph7_init(&engine.ptr) if result != C.PH7_OK { return Engine{}, newError(result) } return engine, nil } func (e Engine) ErrLog() (string, error) { var s *C.char var n C.int err := newError(C.engine_config_err_log(e.ptr, &s, &n)) if err != nil { return "", err } return C.GoStringN(s, n), nil } func (e Engine) Compile(source []byte, phpOnly bool) (*VM, error) { csource := C.CBytes(source) vm := new(VM) var flags C.int if phpOnly { flags |= C.PH7_PHP_ONLY } err := newError(C.ph7_compile_v2(e.ptr, (*C.char)(csource), C.int(len(source)), &vm.ptr, flags)) if err != nil { return nil, err } // TODO free csource return vm, nil } func (e Engine) Close() error { return newError(C.ph7_release(e.ptr)) } type VM struct { ptr *C.ph7_vm } func (vm VM) ExtractOutput() (string, error) { var s *C.char var n C.int err := newError(C.vm_extract_output(vm.ptr, &s, &n)) if err != nil { return "", err } return C.GoStringN(s, n), nil } func (v VM) Exec() error { return newError(C.ph7_vm_exec(v.ptr, (*C.int)(nil))) } func (v VM) Close() error { return newError(C.ph7_vm_release(v.ptr)) }