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)
 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.