andrei          Thu Jul 20 22:51:20 2006 UTC

  Modified files:              
    /php-src    unicode-progress.txt 
    /php-src/ext/standard       array.c 
  Log:
  Make all array_*diff* functions use params API (along with FCI cache)
  and mark them with U.
  
  # What a mess (before my changes of course) :)
  
  
http://cvs.php.net/viewvc.cgi/php-src/unicode-progress.txt?r1=1.27&r2=1.28&diff_format=u
Index: php-src/unicode-progress.txt
diff -u php-src/unicode-progress.txt:1.27 php-src/unicode-progress.txt:1.28
--- php-src/unicode-progress.txt:1.27   Thu Jul 20 20:54:22 2006
+++ php-src/unicode-progress.txt        Thu Jul 20 22:51:20 2006
@@ -10,12 +10,6 @@
     Need to fix string_compare_function() to compare Unicode strings
     directly in code point order
 
-    array_diff(), array_udiff()
-    array_diff_assoc(), array_diff_uassoc(), array_udiff_assoc(), 
array_udiff_uassoc()
-    array_diff_key(), array_diff_ukey()
-        Should work with minor cleanups provided that underlying comparison
-        functions are fixed, FCI cache, test
-
     array_intersect(), array_uintersect()
     array_intersect_assoc(), array_uintersect_assoc(), 
array_intersect_uassoc(), array_uintersect_uassoc()
     array_intersect_key(), array_intersect_ukey()
@@ -83,6 +77,10 @@
     ksort(), krsort() 
     usort(), uasort(), uksort()
 
+    array_diff(), array_udiff()
+    array_diff_assoc(), array_diff_uassoc(),
+    array_udiff_assoc(), array_udiff_uassoc()
+    array_diff_key(), array_diff_ukey()
 
   string.c
   --------
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.369&r2=1.370&diff_format=u
Index: php-src/ext/standard/array.c
diff -u php-src/ext/standard/array.c:1.369 php-src/ext/standard/array.c:1.370
--- php-src/ext/standard/array.c:1.369  Thu Jul 20 20:54:23 2006
+++ php-src/ext/standard/array.c        Thu Jul 20 22:51:20 2006
@@ -21,7 +21,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: array.c,v 1.369 2006/07/20 20:54:23 andrei Exp $ */
+/* $Id: array.c,v 1.370 2006/07/20 22:51:20 andrei Exp $ */
 
 #include "php.h"
 #include "php_ini.h"
@@ -3336,157 +3336,149 @@
 {
        zval ***args = NULL;
        HashTable *hash;
-       int argc, arr_argc, i, c;
+       int arr_argc, i, c;
        Bucket ***lists, **list, ***ptrs, *p;
-       zval callback_name;
+       int req_args;
+       char *param_spec;
+       zend_fcall_info fci1, fci2;
+       zend_fcall_info_cache fci1_cache = empty_fcall_info_cache, fci2_cache = 
empty_fcall_info_cache;
+       zend_fcall_info *fci_key, *fci_data;
+       zend_fcall_info_cache *fci_key_cache, *fci_data_cache;
        
        PHP_ARRAY_CMP_FUNC_VARS;
 
        int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC);
        int (*diff_data_compare_func)(const void *, const void * TSRMLS_DC);
        
-
-       /* Get the argument count */
-       argc = ZEND_NUM_ARGS();
-       /* Allocate arguments array and get the arguments, checking for errors. 
*/
-       args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
-       if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
-               efree(args);
-               WRONG_PARAM_COUNT;
-       }
-
        PHP_ARRAY_CMP_FUNC_BACKUP();
 
        if (behavior == DIFF_NORMAL) {
                diff_key_compare_func = array_key_compare;
+
                if (data_compare_type == DIFF_COMP_DATA_INTERNAL) {
                        /* array_diff */
                        
-                       if (argc < 2) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc;
+                       req_args = 2;
+                       param_spec = "+";
                        diff_data_compare_func = php_array_data_compare;
                } else if (data_compare_type == DIFF_COMP_DATA_USER) {
                        /* array_udiff */
-                       if (argc < 3) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc - 1;
-                       diff_data_compare_func = array_user_compare;
-                       if (!zend_is_callable(*args[arr_argc], 0, 
&callback_name)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Not a valid callback %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
-                               zval_dtor(&callback_name);
-                               efree(args);
-                               return;
-                       }
-                       zval_dtor(&callback_name);
 
-                       BG(user_compare_func_name) = args[arr_argc];
+                       req_args = 3;
+                       param_spec = "+f";
+                       diff_data_compare_func = array_user_compare;
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"data_compare_type is %d. This should never happen. Please report as a bug", 
data_compare_type);
                        return;         
                }
+
+               if (ZEND_NUM_ARGS() < req_args) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "at least 
%d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+                       PHP_ARRAY_CMP_FUNC_RESTORE();
+                       efree(args);
+                       return;
+               }
+
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
param_spec, &args,
+                                                                 &arr_argc, 
&fci1, &fci1_cache) == FAILURE) {
+                       PHP_ARRAY_CMP_FUNC_RESTORE();
+                       return;
+               }
+               fci_data = &fci1;
+               fci_data_cache = &fci1_cache;
+
        } else if (behavior & DIFF_ASSOC) { /* triggered also if DIFF_KEY */
                /*
                        DIFF_KEY is subset of DIFF_ASSOC. When having the former
                        no comparison of the data is done (part of DIFF_ASSOC)
                */
                diff_key_compare_func = array_key_compare;
+
                if (data_compare_type == DIFF_COMP_DATA_INTERNAL 
-                               && 
+                       && 
                        key_compare_type == DIFF_COMP_KEY_INTERNAL) {
                        /* array_diff_assoc() or array_diff_key() */
                        
-                       if (argc < 2) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc;
+                       req_args = 2;
+                       param_spec = "+";
+
                        diff_key_compare_func = array_key_compare;
                        diff_data_compare_func = php_array_data_compare;
                } else if (data_compare_type == DIFF_COMP_DATA_USER 
-                               && 
-                       key_compare_type == DIFF_COMP_KEY_INTERNAL) {
+                                  && 
+                                  key_compare_type == DIFF_COMP_KEY_INTERNAL) {
                        /* array_udiff_assoc() */
 
-                       if (argc < 3) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc - 1;
-                       if (!zend_is_callable(*args[arr_argc], 0, 
&callback_name)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Not a valid callback %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
-                               zval_dtor(&callback_name);
-                               efree(args);
-                               return;
-                       }
-                       zval_dtor(&callback_name);
+                       req_args = 3;
+                       param_spec = "+f";
+
                        diff_key_compare_func = array_key_compare;
                        diff_data_compare_func = array_user_compare;
+                       fci_data = &fci1;
+                       fci_data_cache = &fci1_cache;
                } else if (data_compare_type == DIFF_COMP_DATA_INTERNAL 
-                               && 
-                       key_compare_type == DIFF_COMP_KEY_USER) {
+                                  && 
+                                  key_compare_type == DIFF_COMP_KEY_USER) {
                        /* array_diff_uassoc() or array_diff_ukey() */
                        
-                       if (argc < 3) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc - 1;
-                       if (!zend_is_callable(*args[arr_argc], 0, 
&callback_name)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Not a valid callback %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
-                               zval_dtor(&callback_name);
-                               efree(args);
-                               return;
-                       }
-                       zval_dtor(&callback_name);
+                       req_args = 3;
+                       param_spec = "+f";
+
                        diff_key_compare_func = array_user_key_compare;
                        diff_data_compare_func = php_array_data_compare;
-                       BG(user_compare_func_name) = args[arr_argc];
+                       fci_key = &fci1;
+                       fci_key_cache = &fci1_cache;
                } else if (data_compare_type == DIFF_COMP_DATA_USER 
-                               && 
-                       key_compare_type == DIFF_COMP_KEY_USER) {
+                                  && 
+                                  key_compare_type == DIFF_COMP_KEY_USER) {
                        /* array_udiff_uassoc() */
                        
-                       if (argc < 4) {
-                               efree(args);
-                               WRONG_PARAM_COUNT;
-                       }
-                       arr_argc = argc - 2;
-                       if (!zend_is_callable(*args[arr_argc], 0, 
&callback_name)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Not a valid callback %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
-                               zval_dtor(&callback_name);
-                               efree(args);
-                               return;
-                       }
-                       zval_dtor(&callback_name);
-                       if (!zend_is_callable(*args[arr_argc + 1], 0, 
&callback_name)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Not a valid callback %R", Z_TYPE(callback_name), Z_UNIVAL(callback_name));
-                               zval_dtor(&callback_name);
-                               efree(args);
-                               return;
-                       }
-                       zval_dtor(&callback_name);
+                       req_args = 4;
+                       param_spec = "+ff";
+
                        diff_key_compare_func = array_user_key_compare;
                        diff_data_compare_func = array_user_compare;
-                       BG(user_compare_func_name) = args[arr_argc + 1];/* data 
- key*/
+                       fci_data = &fci1;
+                       fci_data_cache = &fci1_cache;
+                       fci_key = &fci2;
+                       fci_key_cache = &fci2_cache;
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"data_compare_type is %d. key_compare_type is %d. This should never happen. 
Please report as a bug", data_compare_type, key_compare_type);
                        return; 
                }                       
+
+               if (ZEND_NUM_ARGS() < req_args) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "at least 
%d parameters are required, %d given", req_args, ZEND_NUM_ARGS());
+                       PHP_ARRAY_CMP_FUNC_RESTORE();
+                       efree(args);
+                       return;
+               }
+
+               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
param_spec, &args, &arr_argc,
+                                                                 &fci1, 
&fci1_cache, &fci2, &fci2_cache) == FAILURE) {
+                       PHP_ARRAY_CMP_FUNC_RESTORE();
+                       efree(args);
+                       return;
+               }
+
        } else {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "behavior is %d. 
This should never happen. Please report as a bug", behavior);
                return; 
        }
 
-       
        /* for each argument, create and sort list with pointers to the hash 
buckets */
        lists = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0);
        ptrs = (Bucket ***)safe_emalloc(arr_argc, sizeof(Bucket **), 0);
        php_set_compare_func(SORT_STRING TSRMLS_CC);
+
+       if (behavior == DIFF_NORMAL && data_compare_type == 
DIFF_COMP_DATA_USER) {
+               BG(user_compare_fci) = *fci_data;
+               BG(user_compare_fci_cache) = *fci_data_cache;
+       } else if (behavior & DIFF_ASSOC && key_compare_type == 
DIFF_COMP_KEY_USER) {
+               BG(user_compare_fci) = *fci_key;
+               BG(user_compare_fci_cache) = *fci_key_cache;
+       }
+
        for (i = 0; i < arr_argc; i++) {
                if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument 
#%d is not an array", i + 1);
@@ -3496,6 +3488,11 @@
                hash = HASH_OF(*args[i]);
                list = (Bucket **) pemalloc((hash->nNumOfElements + 1) * 
sizeof(Bucket *), hash->persistent);
                if (!list) {
+                       PHP_ARRAY_CMP_FUNC_RESTORE();
+
+                       efree(ptrs);
+                       efree(lists);
+                       efree(args);
                        RETURN_FALSE;
                }
                lists[i] = list;
@@ -3523,18 +3520,14 @@
                return_value->value.ht = ht;            
        }
 
-       if (behavior == DIFF_NORMAL && data_compare_type == 
DIFF_COMP_DATA_USER) {
-               /* array_udiff() */
-               BG(user_compare_func_name) = args[arr_argc];
-       }
-       
        /* go through the lists and look for values of ptr[0] that are not in 
the others */
        while (*ptrs[0]) {
                if ((behavior & DIFF_ASSOC) /* triggered also when DIFF_KEY */
-                               &&
+                       &&
                        key_compare_type == DIFF_COMP_KEY_USER) {
                        
-                       BG(user_compare_func_name) = args[argc - 1];
+                       BG(user_compare_fci) = *fci_key;
+                       BG(user_compare_fci_cache) = *fci_key_cache;
                }
                c = 1;
                for (i = 1; i < arr_argc; i++) {
@@ -3560,13 +3553,15 @@
                                        */
                                        if (*ptrs[i]) {
                                                if (data_compare_type == 
DIFF_COMP_DATA_USER) {
-                                                       
BG(user_compare_func_name) = args[arr_argc];
+                                                       BG(user_compare_fci) = 
*fci_data;
+                                                       
BG(user_compare_fci_cache) = *fci_data_cache;
                                                }
                                                if 
(diff_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
                                                        /* the data is not the 
same */
                                                        c = -1;
                                                        if (key_compare_type == 
DIFF_COMP_KEY_USER) {
-                                                               
BG(user_compare_func_name) = args[argc - 1];
+                                                               
BG(user_compare_fci) = *fci_key;
+                                                               
BG(user_compare_fci_cache) = *fci_key_cache;
                                                        }
                                                } else {
                                                        break;
@@ -3635,14 +3630,13 @@
 
        PHP_ARRAY_CMP_FUNC_RESTORE();
 
-       
        efree(ptrs);
        efree(lists);
        efree(args);
 }
 
 
-/* {{{ proto array array_diff_key(array arr1, array arr2 [, array ...])
+/* {{{ proto array array_diff_key(array arr1, array arr2 [, array ...]) U
    Returns the entries of arr1 that have keys which are not present in any of 
the others arguments. This function is like array_diff() but works on the keys 
instead of the values. The associativity is preserved. */
 PHP_FUNCTION(array_diff_key)
 {
@@ -3651,7 +3645,7 @@
 }
 /* }}} */
 
-/* {{{ proto array array_diff_ukey(array arr1, array arr2 [, array ...], 
callback key_comp_func)
+/* {{{ proto array array_diff_ukey(array arr1, array arr2 [, array ...], 
callback key_comp_func) U
    Returns the entries of arr1 that have keys which are not present in any of 
the others arguments. User supplied function is used for comparing the keys. 
This function is like array_udiff() but works on the keys instead of the 
values. The associativity is preserved. */
 PHP_FUNCTION(array_diff_ukey)
 {
@@ -3661,7 +3655,7 @@
 /* }}} */
 
 
-/* {{{ proto array array_diff(array arr1, array arr2 [, array ...])
+/* {{{ proto array array_diff(array arr1, array arr2 [, array ...]) U
    Returns the entries of arr1 that have values which are not present in any 
of the others arguments. */
 PHP_FUNCTION(array_diff)
 {
@@ -3670,7 +3664,7 @@
 }
 /* }}} */
 
-/* {{{ proto array array_udiff(array arr1, array arr2 [, array ...], callback 
data_comp_func)
+/* {{{ proto array array_udiff(array arr1, array arr2 [, array ...], callback 
data_comp_func) U
    Returns the entries of arr1 that have values which are not present in any 
of the others arguments. Elements are compared by user supplied function. */
 PHP_FUNCTION(array_udiff)
 {
@@ -3680,7 +3674,7 @@
 /* }}} */
 
 
-/* {{{ proto array array_diff_assoc(array arr1, array arr2 [, array ...])
+/* {{{ proto array array_diff_assoc(array arr1, array arr2 [, array ...]) U
    Returns the entries of arr1 that have values which are not present in any 
of the others arguments but do additional checks whether the keys are equal */
 PHP_FUNCTION(array_diff_assoc)
 {
@@ -3689,7 +3683,7 @@
 }
 /* }}} */
 
-/* {{{ proto array array_diff_uassoc(array arr1, array arr2 [, array ...], 
callback data_comp_func)
+/* {{{ proto array array_diff_uassoc(array arr1, array arr2 [, array ...], 
callback key_comp_func) U
    Returns the entries of arr1 that have values which are not present in any 
of the others arguments but do additional checks whether the keys are equal. 
Elements are compared by user supplied function. */
 PHP_FUNCTION(array_diff_uassoc)
 {
@@ -3699,8 +3693,8 @@
 /* }}} */
 
 
-/* {{{ proto array array_udiff_assoc(array arr1, array arr2 [, array ...], 
callback key_comp_func)
-   Returns the entries of arr1 that have values which are not present in any 
of the others arguments but do additional checks whether the keys are equal. 
Keys are compared by user supplied function. */
+/* {{{ proto array array_udiff_assoc(array arr1, array arr2 [, array ...], 
callback data_comp_func) U
+   Returns the entries of arr1 that have values which are not present in any 
of the others arguments but do additional checks whether the keys are equal. 
Entries are compared by user supplied function. */
 PHP_FUNCTION(array_udiff_assoc)
 {
        php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_ASSOC,
@@ -3708,7 +3702,7 @@
 }
 /* }}} */
 
-/* {{{ proto array array_udiff_uassoc(array arr1, array arr2 [, array ...], 
callback data_comp_func, callback key_comp_func)
+/* {{{ proto array array_udiff_uassoc(array arr1, array arr2 [, array ...], 
callback data_comp_func, callback key_comp_func) U
    Returns the entries of arr1 that have values which are not present in any 
of the others arguments but do additional checks whether the keys are equal. 
Keys and elements are compared by user supplied functions. */
 PHP_FUNCTION(array_udiff_uassoc)
 {

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to