Diff for /embedaddon/php/ext/standard/array.c between versions 1.1 and 1.1.1.5

version 1.1, 2012/02/21 23:48:02 version 1.1.1.5, 2014/06/15 20:03:57
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2014 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | This source file is subject to version 3.01 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 118  PHP_MINIT_FUNCTION(array) /* {{{ */ Line 118  PHP_MINIT_FUNCTION(array) /* {{{ */
         REGISTER_LONG_CONSTANT("SORT_NUMERIC", PHP_SORT_NUMERIC, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("SORT_NUMERIC", PHP_SORT_NUMERIC, CONST_CS | CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("SORT_STRING", PHP_SORT_STRING, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("SORT_STRING", PHP_SORT_STRING, CONST_CS | CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("SORT_LOCALE_STRING", PHP_SORT_LOCALE_STRING, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("SORT_LOCALE_STRING", PHP_SORT_LOCALE_STRING, CONST_CS | CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("SORT_NATURAL", PHP_SORT_NATURAL, CONST_CS | CONST_PERSISTENT);
           REGISTER_LONG_CONSTANT("SORT_FLAG_CASE", PHP_SORT_FLAG_CASE, CONST_CS | CONST_PERSISTENT);
   
         REGISTER_LONG_CONSTANT("CASE_LOWER", CASE_LOWER, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("CASE_LOWER", CASE_LOWER, CONST_CS | CONST_PERSISTENT);
         REGISTER_LONG_CONSTANT("CASE_UPPER", CASE_UPPER, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("CASE_UPPER", CASE_UPPER, CONST_CS | CONST_PERSISTENT);
Line 141  PHP_MSHUTDOWN_FUNCTION(array) /* {{{ */ Line 143  PHP_MSHUTDOWN_FUNCTION(array) /* {{{ */
   
 static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */  static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */
 {  {
        switch (sort_type) {        switch (sort_type & ~PHP_SORT_FLAG_CASE) {
                 case PHP_SORT_NUMERIC:                  case PHP_SORT_NUMERIC:
                         ARRAYG(compare_func) = numeric_compare_function;                          ARRAYG(compare_func) = numeric_compare_function;
                         break;                          break;
   
                 case PHP_SORT_STRING:                  case PHP_SORT_STRING:
                        ARRAYG(compare_func) = string_compare_function;                        ARRAYG(compare_func) = sort_type & PHP_SORT_FLAG_CASE ? string_case_compare_function : string_compare_function;
                         break;                          break;
   
                   case PHP_SORT_NATURAL:
                           ARRAYG(compare_func) = sort_type & PHP_SORT_FLAG_CASE ? string_natural_case_compare_function : string_natural_compare_function;
                           break;
   
 #if HAVE_STRCOLL  #if HAVE_STRCOLL
                 case PHP_SORT_LOCALE_STRING:                  case PHP_SORT_LOCALE_STRING:
                         ARRAYG(compare_func) = string_locale_compare_function;                          ARRAYG(compare_func) = string_locale_compare_function;
Line 180  static int php_array_key_compare(const void *a, const  Line 186  static int php_array_key_compare(const void *a, const 
                 Z_LVAL(first) = f->h;                  Z_LVAL(first) = f->h;
         } else {          } else {
                 Z_TYPE(first) = IS_STRING;                  Z_TYPE(first) = IS_STRING;
                Z_STRVAL(first) = f->arKey;                Z_STRVAL(first) = (char*)f->arKey;
                 Z_STRLEN(first) = f->nKeyLength - 1;                  Z_STRLEN(first) = f->nKeyLength - 1;
         }          }
   
Line 189  static int php_array_key_compare(const void *a, const  Line 195  static int php_array_key_compare(const void *a, const 
                 Z_LVAL(second) = s->h;                  Z_LVAL(second) = s->h;
         } else {          } else {
                 Z_TYPE(second) = IS_STRING;                  Z_TYPE(second) = IS_STRING;
                Z_STRVAL(second) = s->arKey;                Z_STRVAL(second) = (char*)s->arKey;
                 Z_STRLEN(second) = s->nKeyLength - 1;                  Z_STRLEN(second) = s->nKeyLength - 1;
         }          }
   
Line 346  PHP_FUNCTION(count) Line 352  PHP_FUNCTION(count)
   
 /* Numbers are always smaller than strings int this function as it  /* Numbers are always smaller than strings int this function as it
  * anyway doesn't make much sense to compare two different data types.   * anyway doesn't make much sense to compare two different data types.
 * This keeps it consistant and simple. * This keeps it consistent and simple.
  *   *
  * This is not correct any more, depends on what compare_func is set to.   * This is not correct any more, depends on what compare_func is set to.
  */   */
Line 629  static int php_array_user_compare(const void *a, const Line 635  static int php_array_user_compare(const void *a, const
 PHP_FUNCTION(usort)  PHP_FUNCTION(usort)
 {  {
         zval *array;          zval *array;
        int refcount;        unsigned int refcount;
         PHP_ARRAY_CMP_FUNC_VARS;          PHP_ARRAY_CMP_FUNC_VARS;
   
         PHP_ARRAY_CMP_FUNC_BACKUP();          PHP_ARRAY_CMP_FUNC_BACKUP();
Line 672  PHP_FUNCTION(usort) Line 678  PHP_FUNCTION(usort)
 PHP_FUNCTION(uasort)  PHP_FUNCTION(uasort)
 {  {
         zval *array;          zval *array;
        int refcount;        unsigned int refcount;
         PHP_ARRAY_CMP_FUNC_VARS;          PHP_ARRAY_CMP_FUNC_VARS;
   
         PHP_ARRAY_CMP_FUNC_BACKUP();          PHP_ARRAY_CMP_FUNC_BACKUP();
Line 768  static int php_array_user_key_compare(const void *a, c Line 774  static int php_array_user_key_compare(const void *a, c
 PHP_FUNCTION(uksort)  PHP_FUNCTION(uksort)
 {  {
         zval *array;          zval *array;
        int refcount;        unsigned int refcount;
         PHP_ARRAY_CMP_FUNC_VARS;          PHP_ARRAY_CMP_FUNC_VARS;
   
         PHP_ARRAY_CMP_FUNC_BACKUP();          PHP_ARRAY_CMP_FUNC_BACKUP();
Line 1044  PHP_FUNCTION(max) Line 1050  PHP_FUNCTION(max)
 }  }
 /* }}} */  /* }}} */
   
static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive TSRMLS_DC) /* {{{ */static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive TSRMLS_DC) /* {{{ */
 {  {
         zval **args[3],                 /* Arguments to userland function */          zval **args[3],                 /* Arguments to userland function */
                  *retval_ptr,               /* Return value - unused */                  *retval_ptr = NULL,               /* Return value - unused */
                   *key=NULL;            /* Entry key */                    *key=NULL;            /* Entry key */
         char  *string_key;          char  *string_key;
         uint   string_key_len;          uint   string_key_len;
         ulong  num_key;          ulong  num_key;
         HashPosition pos;  
   
         /* Set up known arguments */          /* Set up known arguments */
         args[1] = &key;          args[1] = &key;
        args[2] = userdata;        args[2] = &userdata;
         if (userdata) {          if (userdata) {
                Z_ADDREF_PP(userdata);                Z_ADDREF_P(userdata);
         }          }
   
         zend_hash_internal_pointer_reset_ex(target_hash, &pos);  
   
         BG(array_walk_fci).retval_ptr_ptr = &retval_ptr;          BG(array_walk_fci).retval_ptr_ptr = &retval_ptr;
         BG(array_walk_fci).param_count = userdata ? 3 : 2;          BG(array_walk_fci).param_count = userdata ? 3 : 2;
         BG(array_walk_fci).params = args;          BG(array_walk_fci).params = args;
         BG(array_walk_fci).no_separation = 0;          BG(array_walk_fci).no_separation = 0;
        
         /* Iterate through hash */          /* Iterate through hash */
        while (!EG(exception) && zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) {        zend_hash_internal_pointer_reset(target_hash);
         while (!EG(exception) && zend_hash_get_current_data(target_hash, (void **)&args[0]) == SUCCESS) {
                 if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {                  if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {
                         HashTable *thash;                          HashTable *thash;
                         zend_fcall_info orig_array_walk_fci;                          zend_fcall_info orig_array_walk_fci;
Line 1080  static int php_array_walk(HashTable *target_hash, zval Line 1084  static int php_array_walk(HashTable *target_hash, zval
                         if (thash->nApplyCount > 1) {                          if (thash->nApplyCount > 1) {
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
                                 if (userdata) {                                  if (userdata) {
                                        zval_ptr_dtor(userdata);                                        zval_ptr_dtor(&userdata);
                                 }                                  }
                                 return 0;                                  return 0;
                         }                          }
Line 1101  static int php_array_walk(HashTable *target_hash, zval Line 1105  static int php_array_walk(HashTable *target_hash, zval
                         MAKE_STD_ZVAL(key);                          MAKE_STD_ZVAL(key);
   
                         /* Set up the key */                          /* Set up the key */
                        switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos)) {                        switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
                                 case HASH_KEY_IS_LONG:                                  case HASH_KEY_IS_LONG:
                                         Z_TYPE_P(key) = IS_LONG;                                          Z_TYPE_P(key) = IS_LONG;
                                         Z_LVAL_P(key) = num_key;                                          Z_LVAL_P(key) = num_key;
Line 1129  static int php_array_walk(HashTable *target_hash, zval Line 1133  static int php_array_walk(HashTable *target_hash, zval
                         zval_ptr_dtor(&key);                          zval_ptr_dtor(&key);
                         key = NULL;                          key = NULL;
                 }                  }
                zend_hash_move_forward_ex(target_hash, &pos);                zend_hash_move_forward(target_hash);
         }          }
   
         if (userdata) {          if (userdata) {
                zval_ptr_dtor(userdata);                zval_ptr_dtor(&userdata);
         }          }
         return 0;          return 0;
 }  }
Line 1157  PHP_FUNCTION(array_walk) Line 1161  PHP_FUNCTION(array_walk)
                 return;                  return;
         }          }
   
        php_array_walk(array, userdata ? &userdata : NULL, 0 TSRMLS_CC);        php_array_walk(array, userdata, 0 TSRMLS_CC);
         BG(array_walk_fci) = orig_array_walk_fci;          BG(array_walk_fci) = orig_array_walk_fci;
         BG(array_walk_fci_cache) = orig_array_walk_fci_cache;          BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
         RETURN_TRUE;          RETURN_TRUE;
Line 1182  PHP_FUNCTION(array_walk_recursive) Line 1186  PHP_FUNCTION(array_walk_recursive)
                 return;                  return;
         }          }
   
        php_array_walk(array, userdata ? &userdata : NULL, 1 TSRMLS_CC);        php_array_walk(array, userdata, 1 TSRMLS_CC);
         BG(array_walk_fci) = orig_array_walk_fci;          BG(array_walk_fci) = orig_array_walk_fci;
         BG(array_walk_fci_cache) = orig_array_walk_fci_cache;          BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
         RETURN_TRUE;          RETURN_TRUE;
Line 1557  PHP_FUNCTION(array_fill) Line 1561  PHP_FUNCTION(array_fill)
         array_init_size(return_value, num);          array_init_size(return_value, num);
   
         num--;          num--;
         zval_add_ref(&val);  
         zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, &val, sizeof(zval *), NULL);          zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, &val, sizeof(zval *), NULL);
           zval_add_ref(&val);
   
         while (num--) {          while (num--) {
                zval_add_ref(&val);                if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &val, sizeof(zval *), NULL) == SUCCESS) {
                zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &val, sizeof(zval *), NULL);                        zval_add_ref(&val);
                 } else {
                         zval_dtor(return_value);
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to the array as the next element is already occupied");
                         RETURN_FALSE;
                 }
         }          }
 }  }
 /* }}} */  /* }}} */
Line 1662  PHP_FUNCTION(range) Line 1671  PHP_FUNCTION(range)
                 high = (unsigned char *)Z_STRVAL_P(zhigh);                  high = (unsigned char *)Z_STRVAL_P(zhigh);
   
                 if (*low > *high) {             /* Negative Steps */                  if (*low > *high) {             /* Negative Steps */
                           unsigned char ch = *low;
   
                         if (lstep <= 0) {                          if (lstep <= 0) {
                                 err = 1;                                  err = 1;
                                 goto err;                                  goto err;
                         }                          }
                        for (; *low >= *high; (*low) -= (unsigned int)lstep) {                        for (; ch >= *high; ch -= (unsigned int)lstep) {
                                add_next_index_stringl(return_value, (const char *)low, 1, 1);                                add_next_index_stringl(return_value, (const char *)&ch, 1, 1);
                                if (((signed int)*low - lstep) < 0) {                                if (((signed int)ch - lstep) < 0) {
                                         break;                                          break;
                                 }                                  }
                         }                          }
                 } else if (*high > *low) {      /* Positive Steps */                  } else if (*high > *low) {      /* Positive Steps */
                           unsigned char ch = *low;
   
                         if (lstep <= 0) {                          if (lstep <= 0) {
                                 err = 1;                                  err = 1;
                                 goto err;                                  goto err;
                         }                          }
                        for (; *low <= *high; (*low) += (unsigned int)lstep) {                        for (; ch <= *high; ch += (unsigned int)lstep) {
                                add_next_index_stringl(return_value, (const char *)low, 1, 1);                                add_next_index_stringl(return_value, (const char *)&ch, 1, 1);
                                if (((signed int)*low + lstep) > 255) {                                if (((signed int)ch + lstep) > 255) {
                                         break;                                          break;
                                 }                                  }
                         }                          }
Line 2864  static int zval_compare(zval **a, zval **b TSRMLS_DC)  Line 2877  static int zval_compare(zval **a, zval **b TSRMLS_DC) 
 static int zval_user_compare(zval **a, zval **b TSRMLS_DC) /* {{{ */  static int zval_user_compare(zval **a, zval **b TSRMLS_DC) /* {{{ */
 {  {
         zval **args[2];          zval **args[2];
        zval *retval_ptr;        zval *retval_ptr = NULL;
   
         args[0] = (zval **) a;          args[0] = (zval **) a;
         args[1] = (zval **) b;          args[1] = (zval **) b;
Line 2983  static void php_array_intersect(INTERNAL_FUNCTION_PARA Line 2996  static void php_array_intersect(INTERNAL_FUNCTION_PARA
         char *param_spec;          char *param_spec;
         zend_fcall_info fci1, fci2;          zend_fcall_info fci1, fci2;
         zend_fcall_info_cache fci1_cache = empty_fcall_info_cache, fci2_cache = empty_fcall_info_cache;          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 *fci_key = NULL, *fci_data;
        zend_fcall_info_cache *fci_key_cache, *fci_data_cache;        zend_fcall_info_cache *fci_key_cache = NULL, *fci_data_cache;
         PHP_ARRAY_CMP_FUNC_VARS;          PHP_ARRAY_CMP_FUNC_VARS;
   
         int (*intersect_key_compare_func)(const void *, const void * TSRMLS_DC);          int (*intersect_key_compare_func)(const void *, const void * TSRMLS_DC);
Line 3401  static void php_array_diff(INTERNAL_FUNCTION_PARAMETER Line 3414  static void php_array_diff(INTERNAL_FUNCTION_PARAMETER
         char *param_spec;          char *param_spec;
         zend_fcall_info fci1, fci2;          zend_fcall_info fci1, fci2;
         zend_fcall_info_cache fci1_cache = empty_fcall_info_cache, fci2_cache = empty_fcall_info_cache;          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 *fci_key = NULL, *fci_data;
        zend_fcall_info_cache *fci_key_cache, *fci_data_cache;        zend_fcall_info_cache *fci_key_cache = NULL, *fci_data_cache;
         PHP_ARRAY_CMP_FUNC_VARS;          PHP_ARRAY_CMP_FUNC_VARS;
   
         int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC);          int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC);
Line 3758  PHPAPI int php_multisort_compare(const void *a, const  Line 3771  PHPAPI int php_multisort_compare(const void *a, const 
         efree(args);                                                    \          efree(args);                                                    \
         RETURN_FALSE;          RETURN_FALSE;
   
/* {{{ proto bool array_multisort(array ar1 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING]], ...])/* {{{ proto bool array_multisort(array ar1 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_FLAG_CASE]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_FLAG_CASE]], ...])
    Sort multiple arrays at once similar to how ORDER BY clause works in SQL */     Sort multiple arrays at once similar to how ORDER BY clause works in SQL */
 PHP_FUNCTION(array_multisort)  PHP_FUNCTION(array_multisort)
 {  {
Line 3808  PHP_FUNCTION(array_multisort) Line 3821  PHP_FUNCTION(array_multisort)
                                 parse_state[k] = 1;                                  parse_state[k] = 1;
                         }                          }
                 } else if (Z_TYPE_PP(args[i]) == IS_LONG) {                  } else if (Z_TYPE_PP(args[i]) == IS_LONG) {
                        switch (Z_LVAL_PP(args[i])) {                        switch (Z_LVAL_PP(args[i]) & ~PHP_SORT_FLAG_CASE) {
                                 case PHP_SORT_ASC:                                  case PHP_SORT_ASC:
                                 case PHP_SORT_DESC:                                  case PHP_SORT_DESC:
                                         /* flag allowed here */                                          /* flag allowed here */
Line 3825  PHP_FUNCTION(array_multisort) Line 3838  PHP_FUNCTION(array_multisort)
                                 case PHP_SORT_REGULAR:                                  case PHP_SORT_REGULAR:
                                 case PHP_SORT_NUMERIC:                                  case PHP_SORT_NUMERIC:
                                 case PHP_SORT_STRING:                                  case PHP_SORT_STRING:
                                   case PHP_SORT_NATURAL:
 #if HAVE_STRCOLL  #if HAVE_STRCOLL
                                 case PHP_SORT_LOCALE_STRING:                                  case PHP_SORT_LOCALE_STRING:
 #endif  #endif
Line 4005  PHP_FUNCTION(array_sum) Line 4019  PHP_FUNCTION(array_sum)
                  **entry,                   **entry,
                  entry_n;                   entry_n;
         HashPosition pos;          HashPosition pos;
         double dval;  
   
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) {
                 return;                  return;
Line 4023  PHP_FUNCTION(array_sum) Line 4036  PHP_FUNCTION(array_sum)
                 entry_n = **entry;                  entry_n = **entry;
                 zval_copy_ctor(&entry_n);                  zval_copy_ctor(&entry_n);
                 convert_scalar_to_number(&entry_n TSRMLS_CC);                  convert_scalar_to_number(&entry_n TSRMLS_CC);
                fast_add_function(return_value, return_value, &entry_n TSRMLS_CC);
                if (Z_TYPE(entry_n) == IS_LONG && Z_TYPE_P(return_value) == IS_LONG) { 
                        dval = (double)Z_LVAL_P(return_value) + (double)Z_LVAL(entry_n); 
                        if ( (double)LONG_MIN <= dval && dval <= (double)LONG_MAX ) { 
                                Z_LVAL_P(return_value) += Z_LVAL(entry_n); 
                                continue; 
                        } 
                } 
                convert_to_double(return_value); 
                convert_to_double(&entry_n); 
                Z_DVAL_P(return_value) += Z_DVAL(entry_n); 
         }          }
 }  }
 /* }}} */  /* }}} */
Line 4481  PHP_FUNCTION(array_combine) Line 4484  PHP_FUNCTION(array_combine)
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   
           array_init_size(return_value, num_keys);
   
         if (!num_keys) {          if (!num_keys) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Both parameters should have at least 1 element");                return;
                RETURN_FALSE; 
         }          }
   
         array_init_size(return_value, num_keys);  
   
         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos_keys);          zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos_keys);
         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);          zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);

Removed from v.1.1  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>