diff --git a/ph7.go b/ph7.go index d2a4bc7..20c4f37 100644 --- a/ph7.go +++ b/ph7.go @@ -53,8 +53,6 @@ type Error struct { Code ResultCode } -// TODO create a CompileError that contains the error log text - func newError(code C.int) error { if code == C.PH7_OK { return nil @@ -100,7 +98,12 @@ func (e *Engine) ErrLog() (string, error) { return C.GoStringN(s, n), nil } -// TODO All the ph7_config verbs +/* +We don't bother ph7_config verbs other than PH7_CONFIG_ERR_LOG. +PH7_CONFIG_ERR_OUTPUT is another way of getting compile error messages, +which we don't need separately from returning CompileError values. +PH7_CONFIG_ERR_ABORT doesn't do anything. +*/ func (e *Engine) compileError(code C.int) error { switch code { @@ -135,6 +138,23 @@ func (e *Engine) Compile(source []byte, phpOnly bool) (*VM, error) { return newVM(cvm), nil } +func (e *Engine) CompileFile(path string, phpOnly bool) (*VM, error) { + cpath := C.CString(path) + defer C.free(unsafe.Pointer(cpath)) + + var flags C.int + if phpOnly { + flags |= C.PH7_PHP_ONLY + } + var cvm *C.ph7_vm + err := e.compileError(C.ph7_compile_file((*C.ph7)(e), cpath, &cvm, flags)) + if err != nil { + return nil, err + } + + return newVM(cvm), nil +} + // TODO (*Engine).CompileFile func (e *Engine) Close() error { diff --git a/ph7_test.go b/ph7_test.go index 48ca19d..acdb7f3 100644 --- a/ph7_test.go +++ b/ph7_test.go @@ -84,6 +84,18 @@ func TestCore(t *testing.T) { } } +func TestCompileFile(t *testing.T) { + engine, err := ph7.NewEngine() + mustSucceed(t, err) + defer mustSucceedF(t, engine.Close) + + vm, err := engine.CompileFile("testdata/test_compile_file.php", false) + mustSucceed(t, err) + defer mustSucceedF(t, vm.Close) + + expectOutput(t, vm, "Hello world!") +} + func TestCompileError(t *testing.T) { engine, err := ph7.NewEngine() mustSucceed(t, err) diff --git a/testdata/test_compile_file.php b/testdata/test_compile_file.php new file mode 100644 index 0000000..b78b60b --- /dev/null +++ b/testdata/test_compile_file.php @@ -0,0 +1 @@ + \ No newline at end of file