From 012911683fb57ad3a5de5c4a143eff2819e3a5df Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 22 Feb 2013 14:11:38 +0000 Subject: [PATCH 1/5] Request #48358 insertBeforeOffset() and insertAfterOffset() methods for SplDoublyLinkedList Adds new methods to insert a node in the middle of the dll object --- ext/spl/spl_dllist.c | 126 ++++++++++++++++++++++++++++++---- ext/spl/tests/dllist_013.phpt | 49 +++++++++++++ 2 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 ext/spl/tests/dllist_013.phpt diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index a8417feada370..2cb125624e25e 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -502,7 +502,7 @@ static int spl_dllist_object_count_elements(zval *object, long *count TSRMLS_DC) *count = spl_ptr_llist_count(intern->llist); return SUCCESS; -} +} /* }}} */ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */ @@ -573,7 +573,7 @@ SPL_METHOD(SplDoublyLinkedList, push) spl_ptr_llist_push(intern->llist, value TSRMLS_CC); RETURN_TRUE; -} +} /* }}} */ /* {{{ proto bool SplDoublyLinkedList::unshift(mixed $value) U @@ -616,7 +616,7 @@ SPL_METHOD(SplDoublyLinkedList, pop) } RETURN_ZVAL(value, 1, 1); -} +} /* }}} */ /* {{{ proto mixed SplDoublyLinkedList::shift() U @@ -639,7 +639,7 @@ SPL_METHOD(SplDoublyLinkedList, shift) } RETURN_ZVAL(value, 1, 1); -} +} /* }}} */ /* {{{ proto mixed SplDoublyLinkedList::top() U @@ -1048,7 +1048,7 @@ static void spl_dllist_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* SPL_METHOD(SplDoublyLinkedList, key) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1062,7 +1062,7 @@ SPL_METHOD(SplDoublyLinkedList, key) SPL_METHOD(SplDoublyLinkedList, prev) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1076,7 +1076,7 @@ SPL_METHOD(SplDoublyLinkedList, prev) SPL_METHOD(SplDoublyLinkedList, next) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1090,7 +1090,7 @@ SPL_METHOD(SplDoublyLinkedList, next) SPL_METHOD(SplDoublyLinkedList, valid) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1104,7 +1104,7 @@ SPL_METHOD(SplDoublyLinkedList, valid) SPL_METHOD(SplDoublyLinkedList, rewind) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1119,7 +1119,7 @@ SPL_METHOD(SplDoublyLinkedList, current) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_ptr_llist_element *element = intern->traverse_pointer; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1174,7 +1174,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize) } else { RETURN_NULL(); } - + } /* }}} */ /* {{{ proto void SplDoublyLinkedList::unserialize(string serialized) @@ -1187,7 +1187,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) int buf_len; const unsigned char *p, *s; php_unserialize_data_t var_hash; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; } @@ -1235,6 +1235,104 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) } /* }}} */ +/* {{{ proto void SplDoublyLinkedList::insertBeforeOffset(mixed $index, mixed $newval) U + Inserts a new entry before the specified $index consisting of $newval. */ +SPL_METHOD(SplDoublyLinkedList, insertBeforeOffset) +{ + zval *zindex, *value; + spl_dllist_object *intern; + spl_ptr_llist_element *element; + long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) { + return; + } + SEPARATE_ARG_IF_REF(value); + + intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); + + if (index < 0 || index >= intern->llist->count) { + zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); + return; + } + + // Get the element we want to insert before + element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); + + // Create the new element we want to insert + spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); + + elem->data = value; + elem->rc = 1; + /* connect to the neighbours */ + elem->next = element; + elem->prev = element->prev; + + /* connect the neighbours to this new element */ + if (elem->prev == NULL) { + intern->llist->head = elem; + } else { + element->prev->next = elem; + } + element->prev = elem; + + intern->llist->count++; + + if (intern->llist->ctor) { + intern->llist->ctor(elem TSRMLS_CC); + } +} /* }}} */ + +/* {{{ proto void SplDoublyLinkedList::insertBeforeOffset(mixed $index, mixed $newval) U + Inserts a new entry before the specified $index consisting of $newval. */ +SPL_METHOD(SplDoublyLinkedList, insertAfterOffset) +{ + zval *zindex, *value; + spl_dllist_object *intern; + spl_ptr_llist_element *element; + long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) { + return; + } + SEPARATE_ARG_IF_REF(value); + + intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); + + if (index < 0 || index >= intern->llist->count) { + zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); + return; + } + + // Get the element we want to insert after + element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); + + // Create the new element we want to insert + spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); + + elem->data = value; + elem->rc = 1; + /* connect to the neighbours */ + elem->prev = element; + elem->next = element->next; + + /* connect the neighbours to this new element */ + if (elem->next == NULL) { + intern->llist->tail = elem; + } else { + element->next->prev = elem; + } + element->next = elem; + + intern->llist->count++; + + if (intern->llist->ctor) { + intern->llist->ctor(elem TSRMLS_CC); + } +} /* }}} */ + /* iterator handler table */ zend_object_iterator_funcs spl_dllist_it_funcs = { spl_dllist_it_dtor, @@ -1322,6 +1420,10 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = { SPL_ME(SplDoublyLinkedList, offsetGet, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetSet, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetUnset, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) + + SPL_ME(SplDoublyLinkedList, insertBeforeOffset, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, insertAfterOffset, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) + /* Iterator */ SPL_ME(SplDoublyLinkedList, rewind, arginfo_dllist_void, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, current, arginfo_dllist_void, ZEND_ACC_PUBLIC) diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt new file mode 100644 index 0000000000000..7572f8cac7978 --- /dev/null +++ b/ext/spl/tests/dllist_013.phpt @@ -0,0 +1,49 @@ +--TEST-- +SPL: DoublyLinkedList: insert operations +--FILE-- +insertBeforeOffset(1,5); +} catch (OutOfRangeException $e) { + echo "Exception: ".$e->getMessage()."\n"; +} +try { + $dll->insertBeforeOffset(2,1); +} catch (OutOfRangeException $e) { + echo "Exception: ".$e->getMessage()."\n"; +} + +$dll->push(3); +$dll->push(6); +$dll->insertBeforeOffset(1,4); +$dll->insertAfterOffset(1,5); +$dll->unshift(2); +$dll->insertBeforeOffset(0,1); +$dll->insertAfterOffset(5,7); + +echo count($dll)."\n"; + +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +echo $dll->pop()."\n"; +?> +===DONE=== + +--EXPECTF-- +Exception: Offset invalid or out of range +Exception: Offset invalid or out of range +7 +7 +6 +5 +4 +3 +2 +1 +===DONE=== From 0fb7e5c98f24049ec63f489f435e1a91e82c636e Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Fri, 22 Feb 2013 17:55:12 +0000 Subject: [PATCH 2/5] Fix #48358 insertBeforeOffset() and insertAfterOffset() methods for SplDoublyLinkedList Modify code to use correct /* */ commenting and ensure that all indents are tabs rather than spaces --- ext/spl/spl_dllist.c | 24 ++++++++++++------------ ext/spl/tests/dllist_013.phpt | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 2cb125624e25e..ed302f1981109 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -794,7 +794,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet) intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); index = spl_offset_convert_to_long(zindex TSRMLS_CC); - if (index < 0 || index >= intern->llist->count) { + if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); return; } @@ -881,9 +881,9 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset) intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); - llist = intern->llist; + llist = intern->llist; - if (index < 0 || index >= intern->llist->count) { + if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC); return; } @@ -1139,7 +1139,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize) spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); smart_str buf = {0}; spl_ptr_llist_element *current = intern->llist->head, *next; - zval *flags; + zval *flags; php_serialize_data_t var_hash; if (zend_parse_parameters_none() == FAILURE) { @@ -1252,15 +1252,15 @@ SPL_METHOD(SplDoublyLinkedList, insertBeforeOffset) intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); - if (index < 0 || index >= intern->llist->count) { + if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); return; } - // Get the element we want to insert before + /* Get the element we want to insert before */ element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); - // Create the new element we want to insert + /* Create the new element we want to insert */ spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); elem->data = value; @@ -1270,7 +1270,7 @@ SPL_METHOD(SplDoublyLinkedList, insertBeforeOffset) elem->prev = element->prev; /* connect the neighbours to this new element */ - if (elem->prev == NULL) { + if (elem->prev == NULL) { intern->llist->head = elem; } else { element->prev->next = elem; @@ -1301,15 +1301,15 @@ SPL_METHOD(SplDoublyLinkedList, insertAfterOffset) intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); - if (index < 0 || index >= intern->llist->count) { + if (index < 0 || index >= intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); return; } - // Get the element we want to insert after + /* Get the element we want to insert after */ element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); - // Create the new element we want to insert + /* Create the new element we want to insert */ spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); elem->data = value; @@ -1319,7 +1319,7 @@ SPL_METHOD(SplDoublyLinkedList, insertAfterOffset) elem->next = element->next; /* connect the neighbours to this new element */ - if (elem->next == NULL) { + if (elem->next == NULL) { intern->llist->tail = elem; } else { element->next->prev = elem; diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt index 7572f8cac7978..2fde7ef380fd8 100644 --- a/ext/spl/tests/dllist_013.phpt +++ b/ext/spl/tests/dllist_013.phpt @@ -5,14 +5,14 @@ SPL: DoublyLinkedList: insert operations $dll = new SplDoublyLinkedList(); // errors try { - $dll->insertBeforeOffset(1,5); + $dll->insertBeforeOffset(1,5); } catch (OutOfRangeException $e) { - echo "Exception: ".$e->getMessage()."\n"; + echo "Exception: ".$e->getMessage()."\n"; } try { - $dll->insertBeforeOffset(2,1); + $dll->insertBeforeOffset(2,1); } catch (OutOfRangeException $e) { - echo "Exception: ".$e->getMessage()."\n"; + echo "Exception: ".$e->getMessage()."\n"; } $dll->push(3); From ccc3bcbc23cc594fc0d3f7999dabff13ba9b5f65 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Mon, 25 Feb 2013 14:13:29 +0000 Subject: [PATCH 3/5] Fix #48358 insertBeforeOffset() and insertAfterOffset() methods for SplDoublyLinkedList Additional tests for function argument validation --- ...ist_insertAfterOffset_missing_parameter1.phpt | 11 +++++++++++ ...ist_insertAfterOffset_missing_parameter2.phpt | 11 +++++++++++ ...LinkedList_insertAfterOffset_null_offset.phpt | 13 +++++++++++++ ...st_insertBeforeOffset_missing_parameter1.phpt | 11 +++++++++++ ...st_insertBeforeOffset_missing_parameter2.phpt | 11 +++++++++++ ...inkedList_insertBeforeOffset_null_offset.phpt | 13 +++++++++++++ ext/spl/tests/dllist_013.phpt | 16 +++++++++------- 7 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt new file mode 100644 index 0000000000000..5f145950b08ff --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::insertAfterOffset generate a warning and returns a NULL with missing arguments +--FILE-- +insertAfterOffset()); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::insertAfterOffset() expects exactly 2 parameters, 0 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt new file mode 100644 index 0000000000000..d61553d29ed2d --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::insertAfterOffset generate a warning and returns a NULL with a missing value argument +--FILE-- +insertAfterOffset(2)); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::insertAfterOffset() expects exactly 2 parameters, 1 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt new file mode 100644 index 0000000000000..b4deae1368473 --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt @@ -0,0 +1,13 @@ +--TEST-- +Check that SplDoublyLinkedList::insertAfterOffset throws an exception with an invalid offset argument +--FILE-- +insertAfterOffset(NULL,2)); +} catch (OutOfRangeException $e) { + echo "Exception: ".$e->getMessage()."\n"; +} +?> +--EXPECTF-- +Exception: Offset invalid or out of range diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt new file mode 100644 index 0000000000000..ed241e35dbf3f --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::insertBeforeOffset generate a warning and returns a NULL with missing arguments +--FILE-- +insertBeforeOffset()); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::insertBeforeOffset() expects exactly 2 parameters, 0 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt new file mode 100644 index 0000000000000..73ffedd4aecc2 --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::insertBeforeOffset generate a warning and returns a NULL with a missing value argument +--FILE-- +insertBeforeOffset(2)); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::insertBeforeOffset() expects exactly 2 parameters, 1 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt new file mode 100644 index 0000000000000..63ea04889373c --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt @@ -0,0 +1,13 @@ +--TEST-- +Check that SplDoublyLinkedList::insertBeforeOffset throws an exception with an invalid offset argument +--FILE-- +insertBeforeOffset(NULL,2)); +} catch (OutOfRangeException $e) { + echo "Exception: ".$e->getMessage()."\n"; +} +?> +--EXPECTF-- +Exception: Offset invalid or out of range diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt index 2fde7ef380fd8..379860f2877ac 100644 --- a/ext/spl/tests/dllist_013.phpt +++ b/ext/spl/tests/dllist_013.phpt @@ -15,13 +15,15 @@ try { echo "Exception: ".$e->getMessage()."\n"; } -$dll->push(3); -$dll->push(6); -$dll->insertBeforeOffset(1,4); -$dll->insertAfterOffset(1,5); -$dll->unshift(2); -$dll->insertBeforeOffset(0,1); -$dll->insertAfterOffset(5,7); +$dll->push(3); // 3 +$dll->push(6); // 3 6 +// Insert in the middle of the DLL +$dll->insertBeforeOffset(1,4); // 3 4 6 +$dll->insertAfterOffset(1,5); // 3 4 5 6 +$dll->unshift(2); // 2 3 4 5 6 +// Insert at the beginning and end of the DLL +$dll->insertBeforeOffset(0,1); // 1 2 3 4 5 6 +$dll->insertAfterOffset(5,7); // 1 2 3 4 5 6 7 echo count($dll)."\n"; From c7268b1bce6a704fc7bf6c2dc890d049166dcc94 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 10 Mar 2013 13:07:26 +0000 Subject: [PATCH 4/5] Fix #48358 insertBeforeOffset() and insertAfterOffset() methods for SplDoublyLinkedList Removed DLL insertAfterOffset() method; and renamed insertBeforeOffset() as add() Modified add() to handle a push if specified index = count of elements already in the DLL, while still adding before the specified index otherwise Adjusted tests accordingly to reflect the changes --- ext/spl/spl_dllist.c | 100 +++++------------- ...lDoublyLinkedList_add_invalid_offset.phpt} | 4 +- ...ublyLinkedList_add_missing_parameter1.phpt | 11 ++ ...ublyLinkedList_add_missing_parameter2.phpt | 11 ++ ... SplDoublyLinkedList_add_null_offset.phpt} | 4 +- ..._insertAfterOffset_missing_parameter1.phpt | 11 -- ..._insertAfterOffset_missing_parameter2.phpt | 11 -- ...insertBeforeOffset_missing_parameter1.phpt | 11 -- ...insertBeforeOffset_missing_parameter2.phpt | 11 -- ext/spl/tests/dllist_013.phpt | 22 ++-- 10 files changed, 62 insertions(+), 134 deletions(-) rename ext/spl/tests/{SplDoublyLinkedList_insertAfterOffset_null_offset.phpt => SplDoublyLinkedList_add_invalid_offset.phpt} (58%) create mode 100644 ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt create mode 100644 ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt rename ext/spl/tests/{SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt => SplDoublyLinkedList_add_null_offset.phpt} (57%) delete mode 100644 ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt delete mode 100644 ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt delete mode 100644 ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt delete mode 100644 ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index ed302f1981109..8a55a42379234 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1235,9 +1235,9 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) } /* }}} */ -/* {{{ proto void SplDoublyLinkedList::insertBeforeOffset(mixed $index, mixed $newval) U +/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval) U Inserts a new entry before the specified $index consisting of $newval. */ -SPL_METHOD(SplDoublyLinkedList, insertBeforeOffset) +SPL_METHOD(SplDoublyLinkedList, add) { zval *zindex, *value; spl_dllist_object *intern; @@ -1252,87 +1252,44 @@ SPL_METHOD(SplDoublyLinkedList, insertBeforeOffset) intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); - if (index < 0 || index >= intern->llist->count) { + if (index < 0 || index > intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); return; } - /* Get the element we want to insert before */ - element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); - - /* Create the new element we want to insert */ - spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); - - elem->data = value; - elem->rc = 1; - /* connect to the neighbours */ - elem->next = element; - elem->prev = element->prev; - - /* connect the neighbours to this new element */ - if (elem->prev == NULL) { - intern->llist->head = elem; + if (index == intern->llist->count) { + /* If index is the last entry+1 then we do a push because we're not inserting before any entry */ + spl_ptr_llist_push(intern->llist, value TSRMLS_CC); } else { - element->prev->next = elem; - } - element->prev = elem; - - intern->llist->count++; - - if (intern->llist->ctor) { - intern->llist->ctor(elem TSRMLS_CC); - } -} /* }}} */ - -/* {{{ proto void SplDoublyLinkedList::insertBeforeOffset(mixed $index, mixed $newval) U - Inserts a new entry before the specified $index consisting of $newval. */ -SPL_METHOD(SplDoublyLinkedList, insertAfterOffset) -{ - zval *zindex, *value; - spl_dllist_object *intern; - spl_ptr_llist_element *element; - long index; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) { - return; - } - SEPARATE_ARG_IF_REF(value); - - intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); - - if (index < 0 || index >= intern->llist->count) { - zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC); - return; - } - - /* Get the element we want to insert after */ - element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); + /* Get the element we want to insert before */ + element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); - /* Create the new element we want to insert */ - spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); + /* Create the new element we want to insert */ + spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element)); - elem->data = value; - elem->rc = 1; - /* connect to the neighbours */ - elem->prev = element; - elem->next = element->next; + elem->data = value; + elem->rc = 1; + /* connect to the neighbours */ + elem->next = element; + elem->prev = element->prev; - /* connect the neighbours to this new element */ - if (elem->next == NULL) { - intern->llist->tail = elem; - } else { - element->next->prev = elem; - } - element->next = elem; + /* connect the neighbours to this new element */ + if (elem->prev == NULL) { + intern->llist->head = elem; + } else { + element->prev->next = elem; + } + element->prev = elem; - intern->llist->count++; + intern->llist->count++; - if (intern->llist->ctor) { - intern->llist->ctor(elem TSRMLS_CC); + if (intern->llist->ctor) { + intern->llist->ctor(elem TSRMLS_CC); + } } } /* }}} */ + /* iterator handler table */ zend_object_iterator_funcs spl_dllist_it_funcs = { spl_dllist_it_dtor, @@ -1421,8 +1378,7 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = { SPL_ME(SplDoublyLinkedList, offsetSet, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetUnset, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, insertBeforeOffset, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, insertAfterOffset, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, add, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) /* Iterator */ SPL_ME(SplDoublyLinkedList, rewind, arginfo_dllist_void, ZEND_ACC_PUBLIC) diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt similarity index 58% rename from ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt rename to ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt index b4deae1368473..b94b067f4d818 100644 --- a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_null_offset.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt @@ -1,10 +1,10 @@ --TEST-- -Check that SplDoublyLinkedList::insertAfterOffset throws an exception with an invalid offset argument +Check that SplDoublyLinkedList::add throws an exception with an invalid offset argument --FILE-- insertAfterOffset(NULL,2)); + var_dump($dll->add(12,'Offset 12 should not exist')); } catch (OutOfRangeException $e) { echo "Exception: ".$e->getMessage()."\n"; } diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt new file mode 100644 index 0000000000000..12cfe40008b63 --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::add generate a warning and returns a NULL with missing arguments +--FILE-- +add()); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 0 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt new file mode 100644 index 0000000000000..c9c319316fdfc --- /dev/null +++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt @@ -0,0 +1,11 @@ +--TEST-- +Check that SplDoublyLinkedList::add generate a warning and returns a NULL with a missing value argument +--FILE-- +add(2)); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 1 given in %s on line %d +NULL + diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt similarity index 57% rename from ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt rename to ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt index 63ea04889373c..396f89b491e31 100644 --- a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_null_offset.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt @@ -1,10 +1,10 @@ --TEST-- -Check that SplDoublyLinkedList::insertBeforeOffset throws an exception with an invalid offset argument +Check that SplDoublyLinkedList::add throws an exception with an invalid offset argument --FILE-- insertBeforeOffset(NULL,2)); + var_dump($dll->add(NULL,2)); } catch (OutOfRangeException $e) { echo "Exception: ".$e->getMessage()."\n"; } diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt deleted file mode 100644 index 5f145950b08ff..0000000000000 --- a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter1.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -Check that SplDoublyLinkedList::insertAfterOffset generate a warning and returns a NULL with missing arguments ---FILE-- -insertAfterOffset()); -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::insertAfterOffset() expects exactly 2 parameters, 0 given in %s on line %d -NULL - diff --git a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt deleted file mode 100644 index d61553d29ed2d..0000000000000 --- a/ext/spl/tests/SplDoublyLinkedList_insertAfterOffset_missing_parameter2.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -Check that SplDoublyLinkedList::insertAfterOffset generate a warning and returns a NULL with a missing value argument ---FILE-- -insertAfterOffset(2)); -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::insertAfterOffset() expects exactly 2 parameters, 1 given in %s on line %d -NULL - diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt deleted file mode 100644 index ed241e35dbf3f..0000000000000 --- a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter1.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -Check that SplDoublyLinkedList::insertBeforeOffset generate a warning and returns a NULL with missing arguments ---FILE-- -insertBeforeOffset()); -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::insertBeforeOffset() expects exactly 2 parameters, 0 given in %s on line %d -NULL - diff --git a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt deleted file mode 100644 index 73ffedd4aecc2..0000000000000 --- a/ext/spl/tests/SplDoublyLinkedList_insertBeforeOffset_missing_parameter2.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -Check that SplDoublyLinkedList::insertBeforeOffset generate a warning and returns a NULL with a missing value argument ---FILE-- -insertBeforeOffset(2)); -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::insertBeforeOffset() expects exactly 2 parameters, 1 given in %s on line %d -NULL - diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt index 379860f2877ac..b60f06392494f 100644 --- a/ext/spl/tests/dllist_013.phpt +++ b/ext/spl/tests/dllist_013.phpt @@ -5,25 +5,20 @@ SPL: DoublyLinkedList: insert operations $dll = new SplDoublyLinkedList(); // errors try { - $dll->insertBeforeOffset(1,5); -} catch (OutOfRangeException $e) { - echo "Exception: ".$e->getMessage()."\n"; -} -try { - $dll->insertBeforeOffset(2,1); + $dll->add(2,5); } catch (OutOfRangeException $e) { echo "Exception: ".$e->getMessage()."\n"; } -$dll->push(3); // 3 -$dll->push(6); // 3 6 +$dll->add(0,6); // 6 +$dll->add(0,3); // 3 6 // Insert in the middle of the DLL -$dll->insertBeforeOffset(1,4); // 3 4 6 -$dll->insertAfterOffset(1,5); // 3 4 5 6 -$dll->unshift(2); // 2 3 4 5 6 +$dll->add(1,4); // 3 4 6 +$dll->add(2,5); // 3 4 5 6 +$dll->unshift(2); // 2 3 5 4 6 // Insert at the beginning and end of the DLL -$dll->insertBeforeOffset(0,1); // 1 2 3 4 5 6 -$dll->insertAfterOffset(5,7); // 1 2 3 4 5 6 7 +$dll->add(0,1); // 1 2 3 4 5 6 +$dll->add(6,7); // 1 2 3 4 5 6 7 echo count($dll)."\n"; @@ -39,7 +34,6 @@ echo $dll->pop()."\n"; --EXPECTF-- Exception: Offset invalid or out of range -Exception: Offset invalid or out of range 7 7 6 From 39e785e83762b08d8c2441270dc375fd331c476a Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 16 Mar 2013 18:11:27 +0000 Subject: [PATCH 5/5] Fix #48358 add() method for SplDoublyLinkedList Don't cast index to an int, leave it as a long --- ext/spl/spl_dllist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 8a55a42379234..5d3d65fccc2ae 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1250,7 +1250,7 @@ SPL_METHOD(SplDoublyLinkedList, add) SEPARATE_ARG_IF_REF(value); intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - index = (int)spl_offset_convert_to_long(zindex TSRMLS_CC); + index = spl_offset_convert_to_long(zindex TSRMLS_CC); if (index < 0 || index > intern->llist->count) { zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);