]> granicus.if.org Git - php/commitdiff
Add SplDoublyLinkedList::prev(), no point in having a DLL that only goes one way
authorScott MacVicar <scottmac@php.net>
Wed, 17 Jun 2009 12:57:38 +0000 (12:57 +0000)
committerScott MacVicar <scottmac@php.net>
Wed, 17 Jun 2009 12:57:38 +0000 (12:57 +0000)
ext/spl/spl_dllist.c
ext/spl/tests/dllist_010.phpt [new file with mode: 0644]
ext/spl/tests/dllist_memleak.phpt [new file with mode: 0644]

index dde49a875576310253db0e6bf6aa1da0272d6066..6783e24148efd04a77a27f8fca3c160db361a166 100644 (file)
@@ -350,6 +350,7 @@ static void spl_dllist_object_free_storage(void *object TSRMLS_DC) /* {{{ */
        }
 
        spl_ptr_llist_destroy(intern->llist TSRMLS_CC);
+       SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
        zval_ptr_dtor(&intern->retval);
 
        efree(object);
@@ -1033,6 +1034,16 @@ SPL_METHOD(SplDoublyLinkedList, key)
 }
 /* }}} */
 
+/* {{{ proto void SplDoublyLinkedList::prev() U
+   Move to next entry */
+SPL_METHOD(SplDoublyLinkedList, prev)
+{
+       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+       spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags ^ SPL_DLLIST_IT_LIFO TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ proto void SplDoublyLinkedList::next() U
    Move to next entry */
 SPL_METHOD(SplDoublyLinkedList, next)
@@ -1161,6 +1172,7 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = {
        SPL_ME(SplDoublyLinkedList, current,         NULL,                           ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, key,             NULL,                           ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, next,            NULL,                           ZEND_ACC_PUBLIC)
+       SPL_ME(SplDoublyLinkedList, prev,            NULL,                           ZEND_ACC_PUBLIC)
        SPL_ME(SplDoublyLinkedList, valid,           NULL,                           ZEND_ACC_PUBLIC)
        {NULL, NULL, NULL}
 };
diff --git a/ext/spl/tests/dllist_010.phpt b/ext/spl/tests/dllist_010.phpt
new file mode 100644 (file)
index 0000000..685f735
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+SPL: DoublyLinkedList: prev
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+$dll->push(1);
+$dll->push(2);
+$dll->push(3);
+$dll->push(4);
+
+
+$dll->rewind();
+echo $dll->current()."\n";
+$dll->next();
+$dll->next();
+echo $dll->current()."\n";
+$dll->prev();
+echo $dll->current()."\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+1
+3
+2
+===DONE===
diff --git a/ext/spl/tests/dllist_memleak.phpt b/ext/spl/tests/dllist_memleak.phpt
new file mode 100644 (file)
index 0000000..9bae68b
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+SPL: DoublyLinkedList: memory leak when iterator pointer isn't at the last element
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+$dll->push(1);
+$dll->push(2);
+$dll->push(3);
+$dll->push(4);
+
+
+$dll->rewind();
+echo $dll->current()."\n";
+$dll->next();
+$dll->next();
+echo $dll->current()."\n";
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+1
+3
+===DONE===