Aren't these RIT constants against our coding standards? Might be too late now if it's in 5.0.x but we should stick to plan. Something like RECURSIVE_ITERATOR_SELF_FIRST

Andi

At 10:19 PM 7/27/2005 +0000, Marcus Boerger wrote:
helly           Wed Jul 27 18:19:02 2005 EDT

  Modified files:
    /php-src/ext/spl    spl_iterators.c
    /php-src/ext/spl/internal   recursiveiteratoriterator.inc
  Log:
  - Fix issues with iterators and excpetions
  # update documentation
  #
  # In 5.2 we need to implement an event handler onException() to be invoked
  # on exceptions during getChildren() calls. Its default implementation
  # would simply rethrow the exception if the flag is not set and delete if
  # if it was set. To do so the exceptions refcount needs to be increased
  # before calling zend_clear_exception() to keep the exception alive but
  # clear the control information.
  #
  # As a side note this is alos the easy solution to allow multi exception
  # handling: Simply clear the engine's exception info and add a property
  # called $previousException to the base exception and assign it from the
  # already pending one.


http://cvs.php.net/diff.php/php-src/ext/spl/spl_iterators.c?r1=1.70&r2=1.71&ty=u
Index: php-src/ext/spl/spl_iterators.c
diff -u php-src/ext/spl/spl_iterators.c:1.70 php-src/ext/spl/spl_iterators.c:1.71
--- php-src/ext/spl/spl_iterators.c:1.70        Thu Jun 16 10:56:13 2005
+++ php-src/ext/spl/spl_iterators.c     Wed Jul 27 18:19:00 2005
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */

-/* $Id: spl_iterators.c,v 1.70 2005/06/16 14:56:13 dmitry Exp $ */
+/* $Id: spl_iterators.c,v 1.71 2005/07/27 22:19:00 helly Exp $ */

 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -65,6 +65,9 @@
        RIT_CHILD_FIRST = 2
 } RecursiveIteratorMode;

+#define RIT_MODE_MASK       0x000000FF
+#define RIT_CATCH_GET_CHILD 0x00000100
+
 typedef enum {
        RS_NEXT  = 0,
        RS_TEST  = 1,
@@ -85,6 +88,7 @@
        spl_sub_iterator         *iterators;
        int                      level;
        RecursiveIteratorMode    mode;
+       int                      flags;
        zend_function            *callHasChildren;
        zend_function            *callGetChildren;
        zend_function            *beginChildren;
@@ -222,6 +226,20 @@
                                } else {

zend_call_method_with_0_params(&zobject, ce, NULL, "getchildren", &child);
                                }
+
+                               if (EG(exception)) {
+ if (!(object->flags & RIT_CATCH_GET_CHILD)) {
+                                               return;
+                                       } else {
+ zend_clear_exception(TSRMLS_C);
+                                               if (child) {
+                                                       zval_ptr_dtor(&child);
+                                               }
+ object->iterators[object->level].state = RS_NEXT;
+                                               goto next_step;
+                                       }
+                               }
+
ce = child && Z_TYPE_P(child) == IS_OBJECT ? Z_OBJCE_P(child) : NULL; if (!ce || !instanceof_function(ce, spl_ce_RecursiveIterator TSRMLS_CC)) {
                                        if (child) {
@@ -344,7 +362,8 @@
intern = (spl_recursive_it_object*)zend_object_store_get_object(object TSRMLS_CC);
        intern->iterators = emalloc(sizeof(spl_sub_iterator));
        intern->level = 0;
-       intern->mode = mode;
+       intern->mode = mode & RIT_MODE_MASK;
+       intern->flags = mode & ~RIT_MODE_MASK;
        intern->ce = Z_OBJCE_P(object);
zend_hash_find(&intern->ce->function_table, "callhaschildren", sizeof("callHasChildren"), (void **) &intern->callHasChildren); if (intern->callHasChildren->common.scope == spl_ce_RecursiveIteratorIterator) {
@@ -1308,8 +1327,7 @@
                        if (zend_is_true(retval)) {

zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); if (EG(exception) && intern->u.caching.flags & CIT_CATCH_GET_CHILD) {
-                                       zval_ptr_dtor(&EG(exception));
-                                       EG(exception) = NULL;
+                                       zend_clear_exception(TSRMLS_C);
                                        if (zchildren) {
                                                zval_ptr_dtor(&zchildren);
                                        }
@@ -1914,9 +1932,10 @@
spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator; spl_ce_RecursiveIteratorIterator->iterator_funcs.funcs = &spl_recursive_it_iterator_funcs;

- REGISTER_LONG_CONSTANT("RIT_LEAVES_ONLY", (long)RIT_LEAVES_ONLY, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("RIT_SELF_FIRST", (long)RIT_SELF_FIRST, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("RIT_CHILD_FIRST", (long)RIT_CHILD_FIRST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("RIT_LEAVES_ONLY", (long)RIT_LEAVES_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("RIT_SELF_FIRST", (long)RIT_SELF_FIRST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("RIT_CHILD_FIRST", (long)RIT_CHILD_FIRST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("RIT_CATCH_GET_CHILD", (long)RIT_CATCH_GET_CHILD, CONST_CS | CONST_PERSISTENT);

REGISTER_SPL_STD_CLASS_EX(FilterIterator, spl_dual_it_new, spl_funcs_FilterIterator);
        REGISTER_SPL_ITERATOR(FilterIterator);
http://cvs.php.net/diff.php/php-src/ext/spl/internal/recursiveiteratoriterator.inc?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/spl/internal/recursiveiteratoriterator.inc
diff -u php-src/ext/spl/internal/recursiveiteratoriterator.inc:1.11 php-src/ext/spl/internal/recursiveiteratoriterator.inc:1.12 --- php-src/ext/spl/internal/recursiveiteratoriterator.inc:1.11 Sat May 14 12:40:58 2005 +++ php-src/ext/spl/internal/recursiveiteratoriterator.inc Wed Jul 27 18:19:01 2005
@@ -12,6 +12,7 @@
 define('RIT_LEAVES_ONLY', 0);
 define('RIT_SELF_FIRST',  1);
 define('RIT_CHILD_FIRST', 2);
+define('RIT_CATCH_GET_CHILD', 256);

 /**
  * @brief   Iterates through recursive iterators
@@ -27,18 +28,26 @@
 {
        private $ait = array();
        private $count = 0;
+       private $mode  = RIT_LEAVES_ONLY;
+       private $flags = 0;

        /** Construct from RecursiveIterator
        *
        * @param it     RecursiveIterator to iterate
-       * @param flags  Operation mode:
+       * @param flags  Operation mode (one of):
        *               - RIT_LEAVES_ONLY only show leaves
        *               - RIT_SELF_FIRST  show parents prior to their childs
* - RIT_CHILD_FIRST show all childs prior to their parent
+       *               or'ed with the following flags:
+       *               - RIT_CATCH_GET_CHILD which catches exceptions during
+       *                 getChildren() calls and simply jumps to the next
+       *                 element.
        */
        function __construct(RecursiveIterator $it, $flags)
        {
                $this->ait[0] = $it;
+               $this->mode   = $flags & 0xFF;
+               $this->flags  = $flags & ~0xFF;
        }

        /** Rewind to top iterator as set in constructor
@@ -94,7 +103,19 @@
                        if ($it->valid()) {
                                if (!$it->recursed && callHasChildren()) {
                                        $it->recursed = true;
-                                       $sub = callGetChildren();
+                                       try
+                                       {
+                                               $sub = callGetChildren();
+                                       }
+                                       catch (Exception $e)
+                                       {
+ if (!($this->flags & RIT_CATCH_GET_CHILD))
+                                               {
+                                                       throw $e;
+                                               }
+                                               $it->next();
+                                               continue;
+                                       }
                                        $sub->recursed = false;
                                        $sub->rewind();
                                        if ($sub->valid()) {

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to