summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2006-11-03 19:02:16 +0000
committerMarcus Boerger <helly@php.net>2006-11-03 19:02:16 +0000
commitda8b00a5e44bcefe03782395aee7389160a68bbe (patch)
treea1f26ab6cf5a3354bdfd8b49d15abc4b8b579079 /Zend
parent978dd0fdd9b2101d56eea09c6039e7d9bfc7c8d3 (diff)
downloadphp-git-da8b00a5e44bcefe03782395aee7389160a68bbe.tar.gz
- MFH: Fixed bug #39320
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_hash.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index e5e127f0f5..ee92abc2df 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -647,12 +647,15 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
SET_INCONSISTENT(HT_DESTROYED);
}
-/* This is used to selectively delete certain entries from a hashtable.
- * destruct() receives the data and decides if the entry should be deleted
- * or not
+/* This is used to recurse elements and selectively delete certain entries
+ * from a hashtable. apply_func() receives the data and decides if the entry
+ * should be deleted or recursion should be stopped. The following three
+ * return codes are possible:
+ * ZEND_HASH_APPLY_KEEP - continue
+ * ZEND_HASH_APPLY_STOP - stop iteration
+ * ZEND_HASH_APPLY_REMOVE - delete the element, combineable with the former
*/
-
ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
{
Bucket *p;
@@ -662,11 +665,16 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
HASH_PROTECT_RECURSION(ht);
p = ht->pListHead;
while (p != NULL) {
- if (apply_func(p->pData TSRMLS_CC)) {
+ int result = apply_func(p->pData TSRMLS_CC);
+
+ if (result & ZEND_HASH_APPLY_REMOVE) {
p = zend_hash_apply_deleter(ht, p);
} else {
p = p->pListNext;
}
+ if (result & ZEND_HASH_APPLY_STOP) {
+ break;
+ }
}
HASH_UNPROTECT_RECURSION(ht);
}
@@ -681,17 +689,22 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
HASH_PROTECT_RECURSION(ht);
p = ht->pListHead;
while (p != NULL) {
- if (apply_func(p->pData, argument TSRMLS_CC)) {
+ int result = apply_func(p->pData, argument TSRMLS_CC);
+
+ if (result & ZEND_HASH_APPLY_REMOVE) {
p = zend_hash_apply_deleter(ht, p);
} else {
p = p->pListNext;
}
+ if (result & ZEND_HASH_APPLY_STOP) {
+ break;
+ }
}
HASH_UNPROTECT_RECURSION(ht);
}
-ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t destruct, int num_args, ...)
+ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int num_args, ...)
{
Bucket *p;
va_list args;
@@ -703,15 +716,21 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t de
p = ht->pListHead;
while (p != NULL) {
+ int result;
va_start(args, num_args);
hash_key.arKey = p->arKey;
hash_key.nKeyLength = p->nKeyLength;
hash_key.h = p->h;
- if (destruct(p->pData, num_args, args, &hash_key)) {
+ result = apply_func(p->pData, num_args, args, &hash_key);
+
+ if (result & ZEND_HASH_APPLY_REMOVE) {
p = zend_hash_apply_deleter(ht, p);
} else {
p = p->pListNext;
}
+ if (result & ZEND_HASH_APPLY_STOP) {
+ break;
+ }
va_end(args);
}