pointer support
| From: | Steph Fox | Date: | Wed, 21 Jun 2006 04:48:39 +0000 |
| Subject: | pointer support | ||
| Groups: | php.gtk.dev | ||
| Request: | Send a blank email to php-gtk-dev+get-3126@lists.php.net to get a copy of this message | ||
- for your delectation and delight -
I've been testing this for the last three days here, it seems to work fine. Please mention if you find otherwise on your strange boxen.
- Steph
Index: main/php_gtk.h =================================================================== RCS file: /repository/php-gtk/main/php_gtk.h,v retrieving revision 1.131 diff -u -r1.131 php_gtk.h --- main/php_gtk.h 17 Jun 2006 16:59:05 -0000 1.131 +++ main/php_gtk.h 19 Jun 2006 12:56:26 -0000 @@ -160,6 +160,8 @@ #define PHPG_GBOXED(zobj) phpg_gboxed_get(zobj TSRMLS_CC)->boxed +#define PHPG_GPOINTER(zobj) phpg_gpointer_get(zobj TSRMLS_CC)->pointer + #define PHPG_GDKATOM(zobj) ((phpg_gdkatom_t*)PHPG_GET(zobj))->atom @@ -475,6 +477,15 @@ void phpg_gpointer_register_self(TSRMLS_D); PHP_GTK_API void phpg_gpointer_new(zval **zobj, GType gtype, gpointer pointer TSRMLS_DC); +static inline phpg_gpointer_t* phpg_gpointer_get(zval *zobj TSRMLS_DC) +{ + phpg_gpointer_t *pobj = zend_object_store_get_object(zobj TSRMLS_CC); + if (pobj->pointer == NULL) { + php_error(E_ERROR, "Internal object missing in %s wrapper", Z_OBJCE_P(zobj)->name); + } + return pobj; +} + /* GdkAtom */ void phpg_gdkatom_register_self(TSRMLS_D); PHP_GTK_API void phpg_gdkatom_new(zval **zobj, GdkAtom atom TSRMLS_DC); Index: generator/arg_types.php =================================================================== RCS file: /repository/php-gtk/generator/arg_types.php,v retrieving revision 1.80 diff -u -r1.80 arg_types.php --- generator/arg_types.php 3 Jun 2006 19:14:36 -0000 1.80 +++ generator/arg_types.php 19 Jun 2006 13:36:02 -0000 @@ -454,6 +454,51 @@ } /* }}} */ +/* {{{ Pointer_Arg */ +class Pointer_Arg extends Arg_Type { + + static $pointer_tpl = "\n\t%(name) = %(class)(PHPG_GPOINTER(php_%(name)));\n"; + var $type = null; + var $typecode = null; + + function __construct($type, $typecode) + { + $this->type = $type; + $this->typecode = $typecode; + } + + function write_param($type, $name, $default, $null_ok, $info) + { + $indir = strstr($type, '*'); + $type = str_replace($indir, '', $type); + $ce = strtolower($type."_ce"); + $class = str_replace('TYPE_', '', $this->typecode); + $info->var_list->add($type, $indir.$name); + $info->var_list->add('zval', '*php_'.$name." = NULL"); + $info->arg_list[] = $name; + $info->add_parse_list('N', array('&php_' . $name, $ce)); + $info->pre_code[] = aprintf(self::$pointer_tpl, + array('name' => $name, + 'class' => $class, + 'name' => $name)); + } + + function write_return($type, $owns_return, $info) + { + if (substr($type, -1) == '*') { + $info->var_list->add($this->type, '*php_retval'); + $ret = 'php_retval'; + } else { + $info->var_list->add($this->type, 'php_retval'); + $ret = '&php_retval'; + } + + $info->post_code[] = sprintf("\tphpg_gpointer_new(&return_value, %s, %s TSRMLS_CC);\n", + $this->typecode, $ret); + } +} +/* }}} */ + /* {{{ Object_Arg */ class Object_Arg extends Arg_Type { var $obj_name = null; @@ -974,6 +1019,14 @@ $this->register('const-' . $type . '*', $boxed_arg); } + function register_pointer($type, $typecode) + { + if (isset($this->arg_types[$type])) return; + $pointer_arg = new Pointer_Arg($type, $typecode); + $this->register($type, $pointer_arg); + $this->register($type . '*', $pointer_arg); + } + function get($type) { if (isset($this->arg_types[$type])) { Index: generator/generator.php =================================================================== RCS file: /repository/php-gtk/generator/generator.php,v retrieving revision 1.113 diff -u -r1.113 generator.php --- generator/generator.php 3 Jun 2006 18:07:41 -0000 1.113 +++ generator/generator.php 20 Jun 2006 15:00:52 -0000 @@ -152,6 +152,10 @@ foreach ($parser->boxed as $boxed) { $matcher->register_boxed($boxed->c_name, $boxed->typecode); } + + foreach ($parser->pointers as $pointer) { + $matcher->register_pointer($pointer->c_name, $pointer->typecode); + } } @@ -196,7 +200,7 @@ } $handler = $matcher->get($param_type); - $handler->write_param($param_type, $param_name, $param_default, $param_null, $info); + $handler->write_param($param_type, $param_name, $param_default, $param_null, $info, NULL); } $dict['return'] = ''; @@ -269,6 +273,7 @@ break; case 'boxed': + case 'pointer': $dict['cast'] = $object->c_name . ' *'; break; @@ -514,17 +519,30 @@ /* GBoxed */ $this->log_print("\n\n" . $this->make_header("Boxed Types", 50, '-')); - foreach ($this->parser->boxed as $object) { - $reg_info = $this->write_class($object); + foreach ($this->parser->boxed as $boxed) { + $reg_info = $this->write_class($boxed); $register_classes .= aprintf(Templates::register_boxed, $reg_info); - if ($this->overrides->have_post_registration($object->c_name)) { - $register_classes .= $this->overrides->get_post_registration($object->c_name); + if ($this->overrides->have_post_registration($boxed->c_name)) { + $register_classes .= $this->overrides->get_post_registration($boxed->c_name); } } if (!$this->parser->boxed) { $this->log_print(" -- none -- "); } + /* GPointer */ + $this->log_print("\n\n" . $this->make_header("Pointers", 50, '-')); + foreach ($this->parser->pointers as $pointer) { + $reg_info = $this->write_class($pointer); + $register_classes .= aprintf(Templates::register_pointer, $reg_info); + if ($this->overrides->have_post_registration($pointer->c_name)) { + $register_classes .= $this->overrides->get_post_registration($pointer->c_name); + } + } + if (!$this->parser->pointers) { + $this->log_print(" -- none -- "); + } + $this->fp->write(sprintf(Templates::register_classes, $this->lprefix, $register_classes)); @@ -677,6 +695,11 @@ $dict['orig_handlers'] = 'php_gtk_handlers'; break; + case 'pointer': + $dict['create_func'] = 'phpg_create_gpointer'; + $dict['orig_handlers'] = 'php_gtk_handlers'; + break; + default: throw new Exception("unhandled definition type"); break; @@ -746,8 +769,8 @@ $prop_info = 'NULL'; $ctor_arginfo = ''; - if ($class->def_type != 'interface') { - /* interfaces don't have these */ + if ($class->def_type != 'interface' && $class->def_type != 'pointer') { + /* interfaces and pointers don't have these */ list($ctor_defs, $ctor_arginfo) = $this->write_constructor($class); $prop_info = $this->write_prop_handlers($class); list($create_func, $extra_reg_info) = $this->write_object_handlers($class); @@ -951,8 +974,12 @@ } } - foreach ($this->parser->boxed as $object) { - $this->fp->write(sprintf(Templates::class_entry, $object->ce)); + foreach ($this->parser->boxed as $boxed) { + $this->fp->write(sprintf(Templates::class_entry, $boxed->ce)); + } + + foreach ($this->parser->pointers as $pointer) { + $this->fp->write(sprintf(Templates::class_entry, $pointer->ce)); } if ($this->parser->functions || $this->parser->enums) { @@ -1162,6 +1189,8 @@ 'guint32' => 'int', 'gint32' => 'int', + 'gsize' => 'int', + //all enumeration classes here //gtk enums 'GtkAccelFlags' => 'int', @@ -1311,7 +1340,6 @@ 'GError' => 'int', 'GSList' => 'int', 'GValue' => 'int', - 'gpointer' => 'int', 'gboolean' => 'bool', Index: generator/templates.php =================================================================== RCS file: /repository/php-gtk/generator/templates.php,v retrieving revision 1.50 diff -u -r1.50 templates.php --- generator/templates.php 3 Jun 2006 18:07:41 -0000 1.50 +++ generator/templates.php 19 Jun 2006 13:51:50 -0000 @@ -243,6 +243,9 @@ const register_boxed = " %(ce) = phpg_register_boxed(\"%(class)\", %(methods), %(propinfo), %(create_func), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; +const register_pointer = " + %(ce) = phpg_register_boxed(\"%(class)\", %(methods), NULL, %(create_func), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; + const register_interface = " %(ce) = phpg_register_interface(\"%(class)\", %(methods), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; @@ -278,6 +281,7 @@ %s }\n"; + const register_enum = "\tphpg_register_%s(%s, strip_prefix, %s);\n"; const reflection_arginfo_begin = "
Index: main/php_gtk.h =================================================================== RCS file: /repository/php-gtk/main/php_gtk.h,v retrieving revision 1.131 diff -u -r1.131 php_gtk.h --- main/php_gtk.h 17 Jun 2006 16:59:05 -0000 1.131 +++ main/php_gtk.h 19 Jun 2006 12:56:26 -0000 @@ -160,6 +160,8 @@ #define PHPG_GBOXED(zobj) phpg_gboxed_get(zobj TSRMLS_CC)->boxed +#define PHPG_GPOINTER(zobj) phpg_gpointer_get(zobj TSRMLS_CC)->pointer + #define PHPG_GDKATOM(zobj) ((phpg_gdkatom_t*)PHPG_GET(zobj))->atom @@ -475,6 +477,15 @@ void phpg_gpointer_register_self(TSRMLS_D); PHP_GTK_API void phpg_gpointer_new(zval **zobj, GType gtype, gpointer pointer TSRMLS_DC); +static inline phpg_gpointer_t* phpg_gpointer_get(zval *zobj TSRMLS_DC) +{ + phpg_gpointer_t *pobj = zend_object_store_get_object(zobj TSRMLS_CC); + if (pobj->pointer == NULL) { + php_error(E_ERROR, "Internal object missing in %s wrapper", Z_OBJCE_P(zobj)->name); + } + return pobj; +} + /* GdkAtom */ void phpg_gdkatom_register_self(TSRMLS_D); PHP_GTK_API void phpg_gdkatom_new(zval **zobj, GdkAtom atom TSRMLS_DC); Index: generator/arg_types.php =================================================================== RCS file: /repository/php-gtk/generator/arg_types.php,v retrieving revision 1.80 diff -u -r1.80 arg_types.php --- generator/arg_types.php 3 Jun 2006 19:14:36 -0000 1.80 +++ generator/arg_types.php 19 Jun 2006 13:36:02 -0000 @@ -454,6 +454,51 @@ } /* }}} */ +/* {{{ Pointer_Arg */ +class Pointer_Arg extends Arg_Type { + + static $pointer_tpl = "\n\t%(name) = %(class)(PHPG_GPOINTER(php_%(name)));\n"; + var $type = null; + var $typecode = null; + + function __construct($type, $typecode) + { + $this->type = $type; + $this->typecode = $typecode; + } + + function write_param($type, $name, $default, $null_ok, $info) + { + $indir = strstr($type, '*'); + $type = str_replace($indir, '', $type); + $ce = strtolower($type."_ce"); + $class = str_replace('TYPE_', '', $this->typecode); + $info->var_list->add($type, $indir.$name); + $info->var_list->add('zval', '*php_'.$name." = NULL"); + $info->arg_list[] = $name; + $info->add_parse_list('N', array('&php_' . $name, $ce)); + $info->pre_code[] = aprintf(self::$pointer_tpl, + array('name' => $name, + 'class' => $class, + 'name' => $name)); + } + + function write_return($type, $owns_return, $info) + { + if (substr($type, -1) == '*') { + $info->var_list->add($this->type, '*php_retval'); + $ret = 'php_retval'; + } else { + $info->var_list->add($this->type, 'php_retval'); + $ret = '&php_retval'; + } + + $info->post_code[] = sprintf("\tphpg_gpointer_new(&return_value, %s, %s TSRMLS_CC);\n", + $this->typecode, $ret); + } +} +/* }}} */ + /* {{{ Object_Arg */ class Object_Arg extends Arg_Type { var $obj_name = null; @@ -974,6 +1019,14 @@ $this->register('const-' . $type . '*', $boxed_arg); } + function register_pointer($type, $typecode) + { + if (isset($this->arg_types[$type])) return; + $pointer_arg = new Pointer_Arg($type, $typecode); + $this->register($type, $pointer_arg); + $this->register($type . '*', $pointer_arg); + } + function get($type) { if (isset($this->arg_types[$type])) { Index: generator/generator.php =================================================================== RCS file: /repository/php-gtk/generator/generator.php,v retrieving revision 1.113 diff -u -r1.113 generator.php --- generator/generator.php 3 Jun 2006 18:07:41 -0000 1.113 +++ generator/generator.php 20 Jun 2006 15:00:52 -0000 @@ -152,6 +152,10 @@ foreach ($parser->boxed as $boxed) { $matcher->register_boxed($boxed->c_name, $boxed->typecode); } + + foreach ($parser->pointers as $pointer) { + $matcher->register_pointer($pointer->c_name, $pointer->typecode); + } } @@ -196,7 +200,7 @@ } $handler = $matcher->get($param_type); - $handler->write_param($param_type, $param_name, $param_default, $param_null, $info); + $handler->write_param($param_type, $param_name, $param_default, $param_null, $info, NULL); } $dict['return'] = ''; @@ -269,6 +273,7 @@ break; case 'boxed': + case 'pointer': $dict['cast'] = $object->c_name . ' *'; break; @@ -514,17 +519,30 @@ /* GBoxed */ $this->log_print("\n\n" . $this->make_header("Boxed Types", 50, '-')); - foreach ($this->parser->boxed as $object) { - $reg_info = $this->write_class($object); + foreach ($this->parser->boxed as $boxed) { + $reg_info = $this->write_class($boxed); $register_classes .= aprintf(Templates::register_boxed, $reg_info); - if ($this->overrides->have_post_registration($object->c_name)) { - $register_classes .= $this->overrides->get_post_registration($object->c_name); + if ($this->overrides->have_post_registration($boxed->c_name)) { + $register_classes .= $this->overrides->get_post_registration($boxed->c_name); } } if (!$this->parser->boxed) { $this->log_print(" -- none -- "); } + /* GPointer */ + $this->log_print("\n\n" . $this->make_header("Pointers", 50, '-')); + foreach ($this->parser->pointers as $pointer) { + $reg_info = $this->write_class($pointer); + $register_classes .= aprintf(Templates::register_pointer, $reg_info); + if ($this->overrides->have_post_registration($pointer->c_name)) { + $register_classes .= $this->overrides->get_post_registration($pointer->c_name); + } + } + if (!$this->parser->pointers) { + $this->log_print(" -- none -- "); + } + $this->fp->write(sprintf(Templates::register_classes, $this->lprefix, $register_classes)); @@ -677,6 +695,11 @@ $dict['orig_handlers'] = 'php_gtk_handlers'; break; + case 'pointer': + $dict['create_func'] = 'phpg_create_gpointer'; + $dict['orig_handlers'] = 'php_gtk_handlers'; + break; + default: throw new Exception("unhandled definition type"); break; @@ -746,8 +769,8 @@ $prop_info = 'NULL'; $ctor_arginfo = ''; - if ($class->def_type != 'interface') { - /* interfaces don't have these */ + if ($class->def_type != 'interface' && $class->def_type != 'pointer') { + /* interfaces and pointers don't have these */ list($ctor_defs, $ctor_arginfo) = $this->write_constructor($class); $prop_info = $this->write_prop_handlers($class); list($create_func, $extra_reg_info) = $this->write_object_handlers($class); @@ -951,8 +974,12 @@ } } - foreach ($this->parser->boxed as $object) { - $this->fp->write(sprintf(Templates::class_entry, $object->ce)); + foreach ($this->parser->boxed as $boxed) { + $this->fp->write(sprintf(Templates::class_entry, $boxed->ce)); + } + + foreach ($this->parser->pointers as $pointer) { + $this->fp->write(sprintf(Templates::class_entry, $pointer->ce)); } if ($this->parser->functions || $this->parser->enums) { @@ -1162,6 +1189,8 @@ 'guint32' => 'int', 'gint32' => 'int', + 'gsize' => 'int', + //all enumeration classes here //gtk enums 'GtkAccelFlags' => 'int', @@ -1311,7 +1340,6 @@ 'GError' => 'int', 'GSList' => 'int', 'GValue' => 'int', - 'gpointer' => 'int', 'gboolean' => 'bool', Index: generator/templates.php =================================================================== RCS file: /repository/php-gtk/generator/templates.php,v retrieving revision 1.50 diff -u -r1.50 templates.php --- generator/templates.php 3 Jun 2006 18:07:41 -0000 1.50 +++ generator/templates.php 19 Jun 2006 13:51:50 -0000 @@ -243,6 +243,9 @@ const register_boxed = " %(ce) = phpg_register_boxed(\"%(class)\", %(methods), %(propinfo), %(create_func), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; +const register_pointer = " + %(ce) = phpg_register_boxed(\"%(class)\", %(methods), NULL, %(create_func), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; + const register_interface = " %(ce) = phpg_register_interface(\"%(class)\", %(methods), %(typecode) TSRMLS_CC);\n%(extra_reg_info)"; @@ -278,6 +281,7 @@ %s }\n"; + const register_enum = "\tphpg_register_%s(%s, strip_prefix, %s);\n"; const reflection_arginfo_begin = "