From d675326a220a83acfd5e348dbbaedd012a08b681 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Tue, 31 Oct 2006 22:05:56 +0000 Subject: [PATCH] - Consistency of apply funcs, #39320 --- Zend/zend_hash.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 07fbd4393c..67a13cc5ef 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -872,12 +872,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; @@ -887,11 +890,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); } @@ -906,17 +914,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; @@ -928,16 +941,20 @@ 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.nKeyLength = p->nKeyLength; hash_key.h = p->h; - hash_key.type = p->key.type; - hash_key.arKey.s = p->key.arKey.s; - 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); } -- 2.40.0