com gtk/php-gtk: Rework Steph's pointer generation patch so that it works like boxed type.: generator/arg_types.php generator/gener ator.php generator/templates.php main/php_gtk.h m ain/phpg_gpointer.c
[email protected] (David Soria Parra)
| Newsgroups | php.gtk.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: 9a4af2eb699cc69a5331f930f1d94e0f24b32e9a Author: Andrei Zmievski <[email protected]> Fri, 23 Jun 2006 04:11:49 +0000 Parents: bf1b1f016483c8bd88cd9a2babe4f5651f00335e Branches: master Link: http://git.php.net/?p=gtk/php-gtk.git;a=commitdiff;h=9a4af2eb699cc69a5331f930f1d94e0f24b32e9a Log: Rework Steph's pointer generation patch so that it works like boxed type. Changed paths: M generator/arg_types.php M generator/generator.php M generator/templates.php M main/php_gtk.h M main/phpg_gpointer.c
diff_9a4af2eb699cc69a5331f930f1d94e0f24b32e9a.txt
(text/plain, 10.4 KB)
9a4af2eb699cc69a5331f930f1d94e0f24b32e9a
diff --git a/generator/arg_types.php b/generator/arg_types.php
index 94e1bc0..1291b6c 100644
--- a/generator/arg_types.php
+++ b/generator/arg_types.php
@@ -454,6 +454,74 @@ class Struct_Arg extends Arg_Type {
}
/* }}} */
+/* {{{ Pointer_Arg */
+class Pointer_Arg extends Arg_Type {
+
+ const check_tpl = "
+ if (phpg_gpointer_check(php_%(name), %(typecode), FALSE TSRMLS_CC)) {
+ %(name) = (%(type) *) PHPG_GPOINTER(php_%(name));
+ } else {
+ php_error(E_WARNING, \"%s::%s() expects %(name) argument to be a valid %(type) object\", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
+ %(on_error);
+ }\n";
+
+ const check_null_tpl = "
+ if (Z_TYPE_P(php_%(name)) != IS_NULL) {
+ if (phpg_gpointer_check(php_%(name), %(typecode), FALSE TSRMLS_CC)) {
+ %(name) = (%(type) *) PHPG_GPOINTER(php_%(name));
+ } else {
+ php_error(E_WARNING, \"%s::%s() expects %(name) argument to be a valid %(type) object or null\", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
+ %(on_error);
+ }
+ }\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)
+ {
+ if ($null_ok) {
+ $info->var_list->add($this->type, '*' . $name . ' = NULL');
+ $info->var_list->add('zval', '*php_' . $name . ' = NULL');
+ $info->pre_code[] = aprintf(self::check_null_tpl, array('typecode' => $this->typecode,
+ 'type' => $this->type,
+ 'on_error' => $info->error_action,
+ 'name' => $name));
+ } else {
+ $info->var_list->add($this->type, '*' . $name . ' = NULL');
+ $info->var_list->add('zval', '*php_' . $name);
+ $info->pre_code[] = aprintf(self::check_tpl, array('typecode' => $this->typecode,
+ 'type' => $this->type,
+ 'on_error' => $info->error_action,
+ 'name' => $name));
+ }
+
+ $info->add_parse_list('O', array('&php_' . $name, 'gpointer_ce'));
+ $info->arg_list[] = $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 +1042,15 @@ class Arg_Matcher {
$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);
+ $this->register('const-'.$type.'*', $pointer_arg);
+ }
+
function get($type)
{
if (isset($this->arg_types[$type])) {
diff --git a/generator/generator.php b/generator/generator.php
index d3057c4..ea46406 100644
--- a/generator/generator.php
+++ b/generator/generator.php
@@ -67,6 +67,7 @@ class Generator {
'method' => Templates::boxed_method_body,
'prop' => Templates::boxed_prop_access),
'interface' => array('method' => Templates::method_body),
+ 'pointer' => array('method' => Templates::pointer_method_body),
);
var $handlers = array('read_property', 'write_property', 'get_properties',
'read_dimension', 'write_dimension', 'has_dimension',
@@ -152,6 +153,10 @@ class Generator {
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);
+ }
}
@@ -269,6 +274,7 @@ class Generator {
break;
case 'boxed':
+ case 'pointer':
$dict['cast'] = $object->c_name . ' *';
break;
@@ -525,6 +531,19 @@ class Generator {
$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 -- ");
+ }
+
/* register all classes */
$this->fp->write(sprintf(Templates::register_classes,
$this->lprefix,
@@ -553,6 +572,7 @@ class Generator {
break;
case 'boxed':
+ case 'pointer':
$dict['cast'] = $object->c_name . ' *';
break;
@@ -678,6 +698,11 @@ class Generator {
$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;
@@ -721,7 +746,7 @@ class Generator {
}
}
}
- } else if ($class->def_type == 'boxed') {
+ } else if ($class->def_type == 'boxed' || $class->def_type == 'pointer') {
foreach ($method_entries as $me) {
$method_defs[] = vsprintf(Templates::method_entry, $me);
}
@@ -956,6 +981,10 @@ class Generator {
$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) {
$this->fp->write(sprintf(Templates::class_entry, $this->lprefix . '_ce'));
}
diff --git a/generator/templates.php b/generator/templates.php
index abf08f2..f8c93a5 100644
--- a/generator/templates.php
+++ b/generator/templates.php
@@ -133,6 +133,19 @@ static PHP_METHOD(%(class), %(name))
%(post_code)
}\n\n";
+const pointer_method_body = "
+static PHP_METHOD(%(class), %(name))
+{
+%(var_list)
+ NOT_STATIC_METHOD();
+
+ if (!php_gtk_parse_args(ZEND_NUM_ARGS(), \"%(specs)\"%(parse_list)))
+ return;
+%(pre_code)
+ %(return)%(cname)((%(cast))PHPG_GPOINTER(this_ptr)%(arg_list));
+%(post_code)
+e\n\n";
+
const constructor_with_props = "
static PHP_METHOD(%(class), %(name))
{
@@ -243,6 +256,10 @@ const register_class = "
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_class(\"%(class)\", %(methods), NULL, 0, NULL, phpg_create_gpointer, %(typecode) TSRMLS_CC);\n%(extra_reg_info)";
+
+
const register_interface = "
%(ce) = phpg_register_interface(\"%(class)\", %(methods), %(typecode) TSRMLS_CC);\n%(extra_reg_info)";
diff --git a/main/php_gtk.h b/main/php_gtk.h
index 99a78e9..fcdf94f 100644
--- a/main/php_gtk.h
+++ b/main/php_gtk.h
@@ -160,6 +160,8 @@ enum {
#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
@@ -474,6 +476,17 @@ static inline phpg_gboxed_t* phpg_gboxed_get(zval *zobj TSRMLS_DC)
/* GPointer */
void phpg_gpointer_register_self(TSRMLS_D);
PHP_GTK_API void phpg_gpointer_new(zval **zobj, GType gtype, gpointer pointer TSRMLS_DC);
+PHP_GTK_API zend_object_value phpg_create_gpointer(zend_class_entry *ce TSRMLS_DC);
+PHP_GTK_API zend_bool phpg_gpointer_check(zval *zobj, GType gtype, zend_bool full_check 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);
diff --git a/main/phpg_gpointer.c b/main/phpg_gpointer.c
index f040f7e..6a88d6c 100644
--- a/main/phpg_gpointer.c
+++ b/main/phpg_gpointer.c
@@ -68,6 +68,23 @@ PHP_GTK_API zend_object_value phpg_create_gpointer(zend_class_entry *ce TSRMLS_D
}
/* }}} */
+/* {{{ PHP_GTK_API phpg_gpointer_check() */
+PHP_GTK_API zend_bool phpg_gpointer_check(zval *zobj, GType gtype, zend_bool full_check TSRMLS_DC)
+{
+ phpg_gpointer_t *pobj;
+
+ phpg_return_val_if_fail(zobj != NULL, FALSE);
+ if (full_check) {
+ phpg_return_val_if_fail_quiet(Z_TYPE_P(zobj) == IS_OBJECT
+ && instanceof_function(Z_OBJCE_P(zobj), gpointer_ce TSRMLS_CC), FALSE);
+ }
+
+ pobj = phpg_gpointer_get(zobj TSRMLS_CC);
+
+ return (pobj->gtype == gtype);
+}
+/* }}} */
+
/* {{{ PHP_GTK_API phpg_gpointer_new() */
PHP_GTK_API void phpg_gpointer_new(zval **zobj, GType gtype, gpointer pointer TSRMLS_DC)
{