Patch for array.c - if user wants array_search will move internal pointer
| From: | Andrey | Date: | Sun, 04 Aug 2002 13:45:53 +0000 |
| Subject: | Patch for array.c - if user wants array_search will move internal pointer | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-86507@lists.php.net to get a copy of this message | ||
Hi,
pasted in and attached to this mail is patch which gives the opportunity for programmer to move the
internal pointer of the array when searching with array_search(). Fourth parameter (move_pointer) of
type bool is added.
Why I did that? Few days ago I was asked by a man on #php how when he finds what he wants using
array_search to traverse the array forwards and backwards starting from the key returned by
array_search.
The only way for him to do that was to use integers as keys and additional variable. Using this new
feature the user will not be limited to integer indeces.
Andrey
The diff follows (it is against /* $Id: array.c,v 1.181 2002/08/03 00:40:46 rodif_bl Exp $ */):
--- array.c Sat Aug 3 03:48:15 2002
+++ ../array.c Sun Aug 4 16:12:17 2002
@@ -1030,10 +1030,19 @@
*/
static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
{
+#define SEARCH_MOVE_POINTER(___move_pointer,___hash,___how) \
+if (___move_pointer){\
+ zend_hash_internal_pointer_reset(___hash);\
+ while ((--___how) >0){\
+ zend_hash_move_forward(___hash);\
+ }\
+}
+
zval **value, /* value to check for */
**array, /* array to check in */
**strict, /* strict comparison or not */
**entry, /* pointer to array entry */
+ **move_pointer, /* whether to move internal pointer or not */
res; /* comparison result */
HashTable *target_hash; /* array hashtable */
HashPosition pos; /* hash iterator */
@@ -1041,9 +1050,11 @@
uint str_key_len;
char *string_key;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
+ int iterations = 0;
+ int mv_pointer = 0;
- if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
- zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) {
+ if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 ||
+ zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, &move_pointer)
== FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1057,27 +1068,38 @@
RETURN_FALSE;
}
- if (ZEND_NUM_ARGS() == 3) {
+ if (ZEND_NUM_ARGS() >= 3) {
convert_to_boolean_ex(strict);
if (Z_LVAL_PP(strict)) {
is_equal_func = is_identical_function;
}
}
+
+ if (ZEND_NUM_ARGS() == 4) {
+ convert_to_boolean_ex(move_pointer);
+ if (Z_LVAL_PP(move_pointer)){
+ mv_pointer = 1;
+ }
+ }
target_hash = HASH_OF(*array);
zend_hash_internal_pointer_reset_ex(target_hash, &pos);
while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) {
+ iterations++;
is_equal_func(&res, *value, *entry TSRMLS_CC);
if (Z_LVAL(res)) {
if (behavior==0) {
+ SEARCH_MOVE_POINTER(mv_pointer,target_hash, iterations);
RETURN_TRUE;
} else {
/* Return current key */
switch (zend_hash_get_current_key_ex(target_hash, &string_key, &str_key_len,
&num_key, 0, &pos)) {
case HASH_KEY_IS_STRING:
+ SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations);
RETURN_STRINGL(string_key, str_key_len-1, 1);
break;
case HASH_KEY_IS_LONG:
+ SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations);
RETURN_LONG(num_key);
break;
}
@@ -1088,6 +1110,7 @@
}
RETURN_FALSE;
+#undef SEARCH_MOVE_POINTER
}
@@ -1099,7 +1122,7 @@
}
/* }}} */
-/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict])
+/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool move_pointer]])
Searches the array for a given value and returns the corresponding key if successful */
PHP_FUNCTION(array_search)
{
Attachment: [text/x-diff] array.diff
Attachment: [text/x-diff] array.diff