From 49ca034b321a03882b79e4e71adfa0f8f8a40ba6 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" <mlp@thesmartpolitenerd.com> Date: Sun, 24 Nov 2013 19:26:14 -0600 Subject: [PATCH] typemap for HParseResult is returning the appropriate zval, but why does PHP think it's null? --- src/bindings/php/SConscript | 2 +- src/bindings/php/Tests/TokenTest.php | 22 ++++----- src/bindings/swig/hammer.i | 72 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 30391c26..919677bc 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -22,7 +22,7 @@ phpextprefix = os.popen("php-config --extension-dir").read().rstrip() phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE")) AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() -phpincl = phptestenv.Command(os.path.join(phpprefix, "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) +phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php index 6a9cad5b..720b74c2 100644 --- a/src/bindings/php/Tests/TokenTest.php +++ b/src/bindings/php/Tests/TokenTest.php @@ -1,6 +1,6 @@ <?php -include 'hammer.php'; +include_once 'hammer.php'; class TokenTest extends PHPUnit_Framework_TestCase { @@ -8,24 +8,18 @@ class TokenTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_token("95\xa2"); + $this->parser = hammer::h_token("95\xa2"); } - public function testSuccess() + public function testSuccess() { - $result = h_parse($this->parser, "95\xa2"); - //var_dump($result); - $ast = hparseresult_ast_get($result); - //var_dump($ast); - $token_data = hparsedtoken_token_data_get($ast); - //var_dump($token_data); - $bytes = htokendata_bytes_get($token_data); - //var_dump($bytes); - $this->assertEquals($bytes, "95\xa2"); - } + $result = hammer::h_parse($this->parser, "95\xa2"); + var_dump($result); + $this->assertEquals("95\xa2", $result); + } public function testFailure() { $result = h_parse($this->parser, "95"); - $this->assertEquals($result, NULL); + $this->assertEquals(NULL, $result); } } ?> \ No newline at end of file diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index ead3c3fd..ccd5bf9e 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -140,22 +140,52 @@ $1 = (uint8_t*)(*$input)->value.str.val; $2 = (*$input)->value.str.len; } + //%typemap(out) (const uint8_t* str, const size_t len) { // RETVAL_STRINGL((char*)$1, $2, 1); // } %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } + %typemap(in) void*[] { } + %typemap(in) uint8_t { } + %typemap(out) HBytes* { RETVAL_STRINGL((char*)$1->token, $1->len, 1); } + %typemap(out) struct HCountedArray_* { } +%typemap(out) struct HParseResult_* { + if ($1 == NULL) { + // TODO: raise parse failure + RETVAL_NULL(); + } else { + $result = hpt_to_php($1->ast); + printf("Being returned: %s\n", Z_STRVAL_P($result)); + } + } +%inline %{ + static int h_tt_php; + %} + +%init %{ + h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + %} + +%inline { + struct HParsedToken_; + struct HParseResult_; + static zval* hpt_to_php(const struct HParsedToken_ *token); + + //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); + } + #else #warning no Hammer typemaps defined #endif @@ -375,4 +405,46 @@ def int64(): return _h_int64() #endif //%apply const char* { const uint8_t* } +#if defined(SWIGPHP) +%inline { + static zval* hpt_to_php(const HParsedToken *token) { + zval *ret; + ALLOC_INIT_ZVAL(ret); + if (token == NULL) { + ZVAL_NULL(ret); + return ret; + } + switch (token->token_type) { + case TT_NONE: + ZVAL_NULL(ret); + return ret; + case TT_BYTES: + ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); + return ret; + case TT_SINT: + ZVAL_LONG(ret, token->token_data.sint); + return ret; + case TT_UINT: + ZVAL_LONG(ret, token->token_data.uint); + return ret; + case TT_SEQUENCE: + array_init(ret); + for (int i=0; i < token->token_data.seq->used; i++) { + add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); + } + return ret; + default: + /* if (token->token_type == h_tt_php) { */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ + /* return return_value; */ + /* } else { */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ + /* } */ + break; + } + } + } +#endif -- GitLab