diff options
Diffstat (limited to 'ext/standard/array.c')
| -rw-r--r-- | ext/standard/array.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index 1398d45b7e..b5caf090fe 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1555,7 +1555,7 @@ PHP_FUNCTION(array_fill_keys) Create an array containing the range of integers or characters from low to high (inclusive) */ PHP_FUNCTION(range) { - zval *zlow, *zhigh, *zstep = NULL; + zval *zlow, *zhigh, *zstep = NULL, tmp; int err = 0, is_step_double = 0; double step = 1.0; @@ -1584,7 +1584,7 @@ PHP_FUNCTION(range) /* If the range is given as strings, generate an array of characters. */ if (Z_TYPE_P(zlow) == IS_STRING && Z_TYPE_P(zhigh) == IS_STRING && Z_STRLEN_P(zlow) >= 1 && Z_STRLEN_P(zhigh) >= 1) { int type1, type2; - unsigned char *low, *high; + unsigned char low, high; long lstep = (long) step; type1 = is_numeric_string(Z_STRVAL_P(zlow), Z_STRLEN_P(zlow), NULL, NULL, 0); @@ -1596,37 +1596,48 @@ PHP_FUNCTION(range) goto long_str; } - low = (unsigned char *)Z_STRVAL_P(zlow); - high = (unsigned char *)Z_STRVAL_P(zhigh); - - if (*low > *high) { /* Negative Steps */ - unsigned char ch = *low; + low = (unsigned char *)Z_STRVAL_P(zlow)[0]; + high = (unsigned char *)Z_STRVAL_P(zhigh)[0]; + if (low > high) { /* Negative Steps */ if (lstep <= 0) { err = 1; goto err; } - for (; ch >= *high; ch -= (unsigned int)lstep) { - add_next_index_stringl(return_value, (const char *)&ch, 1); - if (((signed int)ch - lstep) < 0) { + for (; low >= high; low -= (unsigned int)lstep) { + if (CG(one_char_string)[low]) { + ZVAL_INT_STR(&tmp, CG(one_char_string)[low]); + } else { + ZVAL_STRINGL(&tmp, &low, 1); + } + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); + if (((signed int)low - lstep) < 0) { break; } } - } else if (*high > *low) { /* Positive Steps */ - unsigned char ch = *low; - + } else if (high > low) { /* Positive Steps */ if (lstep <= 0) { err = 1; goto err; } - for (; ch <= *high; ch += (unsigned int)lstep) { - add_next_index_stringl(return_value, (const char *)&ch, 1); - if (((signed int)ch + lstep) > 255) { + for (; low <= high; low += (unsigned int)lstep) { + if (CG(one_char_string)[low]) { + ZVAL_INT_STR(&tmp, CG(one_char_string)[low]); + } else { + ZVAL_STRINGL(&tmp, &low, 1); + } + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); + if (((signed int)low + lstep) > 255) { break; } } } else { - add_next_index_stringl(return_value, (const char *)low, 1); + if (CG(one_char_string)[low]) { + ZVAL_INT_STR(&tmp, CG(one_char_string)[low]); + } else { + ZVAL_STRINGL(&tmp, (char*)&low, 1); + } + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else if (Z_TYPE_P(zlow) == IS_DOUBLE || Z_TYPE_P(zhigh) == IS_DOUBLE || is_step_double) { @@ -1637,6 +1648,7 @@ double_str: high = zval_get_double(zhigh); i = 0; + Z_TYPE_INFO(tmp) = IS_DOUBLE; if (low > high) { /* Negative steps */ if (low - high < step || step <= 0) { err = 1; @@ -1644,7 +1656,8 @@ double_str: } for (value = low; value >= (high - DOUBLE_DRIFT_FIX); value = low - (++i * step)) { - add_next_index_double(return_value, value); + Z_DVAL(tmp) = value; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else if (high > low) { /* Positive steps */ if (high - low < step || step <= 0) { @@ -1653,10 +1666,12 @@ double_str: } for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) { - add_next_index_double(return_value, value); + Z_DVAL(tmp) = value; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else { - add_next_index_double(return_value, low); + Z_DVAL(tmp) = low; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else { double low, high; @@ -1666,13 +1681,15 @@ long_str: high = zval_get_double(zhigh); lstep = (long) step; + Z_TYPE_INFO(tmp) = IS_LONG; if (low > high) { /* Negative steps */ if (low - high < lstep || lstep <= 0) { err = 1; goto err; } for (; low >= high; low -= lstep) { - add_next_index_long(return_value, (long)low); + Z_LVAL(tmp) = (long)low; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else if (high > low) { /* Positive steps */ if (high - low < lstep || lstep <= 0) { @@ -1680,10 +1697,12 @@ long_str: goto err; } for (; low <= high; low += lstep) { - add_next_index_long(return_value, (long)low); + Z_LVAL(tmp) = (long)low; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } else { - add_next_index_long(return_value, (long)low); + Z_LVAL(tmp) = (long)low; + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp); } } err: |
