go-ph7/ph7.go

141 lines
2.6 KiB
Go

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