Wrapped a bunch of stuff just because I could

This commit is contained in:
Brandon Dyck 2022-11-27 21:49:36 -07:00
parent 880c237e6d
commit 28e7040a09
4 changed files with 133 additions and 28 deletions

4
cgo.c
View File

@ -19,3 +19,7 @@ int vm_create_function(ph7_vm *pVm, const char *zName, void *pUserData) {
int vm_config_err_report(ph7_vm *pVm) { int vm_config_err_report(ph7_vm *pVm) {
return ph7_vm_config(pVm, PH7_VM_CONFIG_ERR_REPORT); return ph7_vm_config(pVm, PH7_VM_CONFIG_ERR_REPORT);
} }
int vm_output_length(ph7_vm *pVm, unsigned int *pLength) {
return ph7_vm_config(pVm, PH7_VM_OUTPUT_LENGTH, pLength);
}

1
cgo.h
View File

@ -4,6 +4,7 @@
int engine_config_err_log(ph7 *pEngine, const char **pzPtr, int *pLen); int engine_config_err_log(ph7 *pEngine, const char **pzPtr, int *pLen);
int vm_extract_output(ph7_vm *pVm, const char **pzPtr, int *pLen); int vm_extract_output(ph7_vm *pVm, const char **pzPtr, int *pLen);
int vm_config_err_report(ph7_vm *pVm); int vm_config_err_report(ph7_vm *pVm);
int vm_output_length(ph7_vm *pVm, unsigned int *pLength);
extern int write_vm_output(void*, unsigned int, void*); extern int write_vm_output(void*, unsigned int, void*);
int vm_set_output_callback(ph7_vm *pVm, void *pUserData); int vm_set_output_callback(ph7_vm *pVm, void *pUserData);

150
ph7.go
View File

@ -192,7 +192,26 @@ func (c *Context) ResultString(s string) error {
return newError(C.ph7_result_string((*C.ph7_context)(c), cs, C.int(len(s)))) return newError(C.ph7_result_string((*C.ph7_context)(c), cs, C.int(len(s))))
} }
// TODO (*Context).ResultStringFormat maybe? Or just use fmt.Sprint*. type resultWriter Context
func (rw *resultWriter) Write(p []byte) (int, error) {
cp := C.CBytes(p)
defer C.free(cp)
err := newError(C.ph7_result_string(
(*C.ph7_context)(rw),
(*C.char)(cp),
C.int(len(p))))
if err != nil {
return 0, err
}
return len(p), nil
}
func (c *Context) ResultWriter() io.Writer {
return (*resultWriter)(c)
}
// ph7_result_string_format is redundant when we have fmt.Sprintf and fmt.Fprintf.
func (c *Context) ResultValue(value *Value) error { func (c *Context) ResultValue(value *Value) error {
return newError(C.ph7_result_value((*C.ph7_context)(c), (*C.ph7_value)(value))) return newError(C.ph7_result_value((*C.ph7_context)(c), (*C.ph7_value)(value)))
@ -200,16 +219,25 @@ func (c *Context) ResultValue(value *Value) error {
// TODO (*Context).ResultResource // TODO (*Context).ResultResource
func (c *Context) Write(p []byte) (int, error) { type outputWriter Context
func (ow *outputWriter) Write(p []byte) (int, error) {
cp := C.CBytes(p) cp := C.CBytes(p)
defer C.free(cp) defer C.free(cp)
err := newError(C.ph7_context_output((*C.ph7_context)(c), (*C.char)(cp), C.int(len(p)))) err := newError(C.ph7_context_output(
(*C.ph7_context)(ow),
(*C.char)(cp),
C.int(len(p))))
if err != nil { if err != nil {
return 0, err return 0, err
} }
return len(p), nil return len(p), nil
} }
func (c *Context) OutputWriter() io.Writer {
return (*outputWriter)(c)
}
type Severity int type Severity int
const ( const (
@ -225,7 +253,7 @@ func (c *Context) ThrowError(severity Severity, msg string) error {
return newError(C.ph7_context_throw_error((*C.ph7_context)(c), C.int(severity), cmsg)) return newError(C.ph7_context_throw_error((*C.ph7_context)(c), C.int(severity), cmsg))
} }
// TODO (*Context).ThrowErrorFormat maybe? // ph7_context_throw_error_format is redundant when we have fmt.Sprintf.
func (c *Context) RandomNum() uint { func (c *Context) RandomNum() uint {
return uint(C.ph7_context_random_num((*C.ph7_context)(c))) return uint(C.ph7_context_random_num((*C.ph7_context)(c)))
@ -246,7 +274,10 @@ func (c *Context) RandomString(length int) (string, error) {
// TODO (*Context).PushAuxData // TODO (*Context).PushAuxData
// TODO (*Context).PeekAuxData // TODO (*Context).PeekAuxData
// TODO (*Context).PopAuxData // TODO (*Context).PopAuxData
// TODO (*Context).ResultBufLength
func (c *Context) ResultBufLength() uint {
return uint(C.ph7_context_result_buf_length((*C.ph7_context)(c)))
}
func (c *Context) FunctionName() string { func (c *Context) FunctionName() string {
return C.GoString(C.ph7_function_name((*C.ph7_context)(c))) return C.GoString(C.ph7_function_name((*C.ph7_context)(c)))
@ -258,6 +289,8 @@ func (c *Context) FunctionName() string {
type Value C.ph7_value type Value C.ph7_value
// TODO Make *Value a fmt.Formatter, or at least a Stringer.
func (v *Value) ToInt() int { func (v *Value) ToInt() int {
return int(C.ph7_value_to_int((*C.ph7_value)(v))) return int(C.ph7_value_to_int((*C.ph7_value)(v)))
} }
@ -290,16 +323,58 @@ func (v *Value) CompareStrict(v2 *Value) int {
return int(C.ph7_value_compare((*C.ph7_value)(v), (*C.ph7_value)(v2), 1)) return int(C.ph7_value_compare((*C.ph7_value)(v), (*C.ph7_value)(v2), 1))
} }
// TODO (*Value).Int func (v *Value) Int(n int) error {
// TODO (*Value).Int64 return newError(C.ph7_value_int((*C.ph7_value)(v), C.int(n)))
// TODO (*Value).Bool }
// TODO (*Value).Null
// TODO (*Value).Double func (v *Value) Int64(n int64) error {
// TODO (*Value).String return newError(C.ph7_value_int64((*C.ph7_value)(v), C.ph7_int64(n)))
// TODO (*Value).StringFormat maybe? }
// TODO (*Value).ResetStringCursor
func (v *Value) Bool(b bool) error {
var cb C.int
if b {
cb = 1
}
return newError(C.ph7_value_bool((*C.ph7_value)(v), cb))
}
func (v *Value) Null() error {
return newError(C.ph7_value_null((*C.ph7_value)(v)))
}
func (v *Value) Double(d float64) error {
return newError(C.ph7_value_double((*C.ph7_value)(v), C.double(d)))
}
func (v *Value) String(s string) error {
cstr := C.CString(s)
defer C.free(unsafe.Pointer(cstr))
return newError(C.ph7_value_string(
(*C.ph7_value)(v),
cstr,
C.int(len(s))))
}
func (v *Value) Write(p []byte) error {
cp := C.CBytes(p)
defer C.free(cp)
return newError(C.ph7_value_string(
(*C.ph7_value)(v),
(*C.char)(cp),
C.int(len(p))))
}
func (v *Value) ResetStringCursor() error {
return newError(C.ph7_value_reset_string_cursor((*C.ph7_value)(v)))
}
// TODO (*Value).Resource // TODO (*Value).Resource
// TODO (*Value).Release
func (v *Value) Release() error {
return newError(C.ph7_value_release((*C.ph7_value)(v)))
}
// TODO (*Value).ArrayFetch // TODO (*Value).ArrayFetch
// TODO (*Value).ArrayWalk // TODO (*Value).ArrayWalk
// TODO (*Value).ArrayAddElem // TODO (*Value).ArrayAddElem
@ -360,18 +435,36 @@ func (v *Value) IsEmpty() bool {
// ph7_lib_init is unnecessary when single-threaded, and possibly always. // ph7_lib_init is unnecessary when single-threaded, and possibly always.
// TODO Config // TODO Config
// TODO Shutdown
// TODO IsThreadsafe func Shutdown() error {
// TODO Version return newError(C.ph7_lib_shutdown())
// TODO Signature }
// TODO Ident
// TODO Copyright func IsThreadsafe() bool {
return C.ph7_lib_is_threadsafe() != 0
}
func Version() string {
return C.GoString(C.ph7_lib_version())
}
func Signature() string {
return C.GoString(C.ph7_lib_signature())
}
func Ident() string {
return C.GoString(C.ph7_lib_ident())
}
func Copyright() string {
return C.GoString(C.ph7_lib_copyright()) +
"\ngo-ph7 by Brandon Dyck. Do whatever the hell you want with it."
}
type VM struct { type VM struct {
ptr *C.ph7_vm ptr *C.ph7_vm
pointerKey unsafe.Pointer pointerKey unsafe.Pointer
outputWriter io.Writer outputWriter io.Writer
// TODO clear outputWriteError when resetting VM
outputWriteErr error outputWriteErr error
userFunctionKeys []unsafe.Pointer userFunctionKeys []unsafe.Pointer
} }
@ -401,6 +494,13 @@ func (vm *VM) SetOutputWriter(w io.Writer) error {
// TODO PH7_VM_CONFIG_IMPORT_PATH // TODO PH7_VM_CONFIG_IMPORT_PATH
// TODO PH7_VM_CONFIG_RECURSION_DEPTH // TODO PH7_VM_CONFIG_RECURSION_DEPTH
func (vm *VM) OutputLength() (uint, error) {
var n C.uint
err := newError(C.vm_output_length(vm.ptr, &n))
return uint(n), err
}
// TODO PH7_VM_CONFIG_CREATE_SUPER // TODO PH7_VM_CONFIG_CREATE_SUPER
// TODO PH7_VM_CONFIG_CREATE_VAR // TODO PH7_VM_CONFIG_CREATE_VAR
// TODO PH7_VM_CONFIG_HTTP_REQUEST // TODO PH7_VM_CONFIG_HTTP_REQUEST
@ -414,7 +514,6 @@ func (vm *VM) SetOutputWriter(w io.Writer) error {
// TODO PH7_VM_CONFIG_EXEC_VALUE // TODO PH7_VM_CONFIG_EXEC_VALUE
// TODO PH7_VM_CONFIG_IO_STREAM // TODO PH7_VM_CONFIG_IO_STREAM
// TODO PH7_VM_CONFIG_ARGV_ENTRY // TODO PH7_VM_CONFIG_ARGV_ENTRY
// TODO PH7_VM_CONFIG_EXTRACT_OUTPUT
// TODO PH7_VM_CONFIG_ERR_LOG_HANDLER // TODO PH7_VM_CONFIG_ERR_LOG_HANDLER
// TODO (*VM).Dump(w io.Writer) // TODO (*VM).Dump(w io.Writer)
@ -445,6 +544,7 @@ func (vm *VM) Exec() error {
} }
func (vm *VM) Reset() error { func (vm *VM) Reset() error {
vm.outputWriteErr = nil
return newError(C.ph7_vm_reset(vm.ptr)) return newError(C.ph7_vm_reset(vm.ptr))
} }

View File

@ -168,7 +168,7 @@ func TestContextWrite(t *testing.T) {
var written int var written int
f := func(ctx *ph7.Context) error { f := func(ctx *ph7.Context) error {
var err error var err error
written, err = ctx.Write([]byte(s)) written, err = ctx.OutputWriter().Write([]byte(s))
return err return err
} }
@ -204,7 +204,7 @@ func TestFunctionName(t *testing.T) {
defer close() defer close()
f := func(ctx *ph7.Context) error { f := func(ctx *ph7.Context) error {
_, err := fmt.Fprint(ctx, ctx.FunctionName()) _, err := fmt.Fprint(ctx.OutputWriter(), ctx.FunctionName())
return err return err
} }
mustSucceed(t, vm.CreateFunction("doStuff", CtxFunc(f))) mustSucceed(t, vm.CreateFunction("doStuff", CtxFunc(f)))