Attached is a patch that adds an optional "step" parameter to the
range() function.  This allows the generation of ranges based on a
non-one increment.  For example:

    range(0, 10, 2);

... would yield an array containing (0, 2, 4, 6, 8, 10).

The change is entirely backwards-compatible with the existing
behavior of range().

I've also attached a test script for the new functionality.

I haven't committed the changes in the interest of getting PHP 4.3.0
out the door, but I will if no one sees a problem.  Otherwise, I can
hang onto this until after the release.

Documentation updates will accompany with the commit.

-- 
Jon Parise ([EMAIL PROTECTED]) :: The PHP Project (http://www.php.net/)
Index: array.c
===================================================================
RCS file: /repository/php4/ext/standard/array.c,v
retrieving revision 1.198
diff -u -r1.198 array.c
--- array.c     5 Nov 2002 16:19:19 -0000       1.198
+++ array.c     11 Nov 2002 05:31:16 -0000
@@ -1411,48 +1411,60 @@
 }
 /* }}} */
 
-/* {{{ proto array range(mixed low, mixed high)
+/* {{{ proto array range(mixed low, mixed high[, int step])
    Create an array containing the range of integers or characters from low to high 
(inclusive) */
 PHP_FUNCTION(range)
 {
-       zval **zlow, **zhigh;
-       
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zlow, &zhigh) == 
FAILURE) {
-               WRONG_PARAM_COUNT;
+       zval *zlow, *zhigh;
+       long step = 1;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &zlow,
+                                                         &zhigh, &step) == FAILURE) {
+               RETURN_FALSE;
        }
 
-       /* allocate an array for return */
+       /* We only want positive step values. */
+       if (step < 0) {
+               step *= -1;
+       }
+
+       /* Initialize the return_value as an array. */
        if (array_init(return_value) == FAILURE) {
                RETURN_FALSE;
        }
 
-       if (Z_TYPE_PP(zlow)==IS_STRING && Z_TYPE_PP(zhigh)==IS_STRING) {
+       /* 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) {
                char *low, *high;
-               convert_to_string_ex(zlow);
-               convert_to_string_ex(zhigh);
-               low = Z_STRVAL_PP(zlow);
-               high = Z_STRVAL_PP(zhigh);
-               if (*low>*high) {
-                       for (; *low >= *high; (*low)--) {
+
+               convert_to_string_ex(&zlow);
+               convert_to_string_ex(&zhigh);
+               low = Z_STRVAL_P(zlow);
+               high = Z_STRVAL_P(zhigh);
+
+               if (*low > *high) {             /* Negative increments */
+                       for (; *low >= *high; (*low) -= step) {
                                add_next_index_stringl(return_value, low, 1, 1);
-                       }       
-               } else {
-                       for (; *low <= *high; (*low)++) {
+                       }
+               } else {                                /* Positive increments */
+                       for (; *low <= *high; (*low) += step) {
                                add_next_index_stringl(return_value, low, 1, 1);
-                       }       
+                       }
                }
        } else {
                int low, high;
-               convert_to_long_ex(zlow);
-               convert_to_long_ex(zhigh);
-               low = Z_LVAL_PP(zlow);
-               high = Z_LVAL_PP(zhigh);
-               if (low > high) { 
-                       for (; low >= high; low--) {
+
+               convert_to_long_ex(&zlow);
+               convert_to_long_ex(&zhigh);
+               low = Z_LVAL_P(zlow);
+               high = Z_LVAL_P(zhigh);
+
+               if (low > high) {               /* Negative increments */
+                       for (; low >= high; low -= step) {
                                add_next_index_long(return_value, low);
                        }       
-               } else {
-                       for (; low <= high; low++) {
+               } else {                                /* Positive increments */
+                       for (; low <= high; low += step) {
                                add_next_index_long(return_value, low);
                        }       
                }
--TEST--
range()
--FILE--
<?php 

print_r(range(0, 10));
print_r(range(10, 0));
print_r(range(0, 10, 2));
print_r(range(10, 0, 2));

?>
--EXPECT--
Array
(
    [0] => 0
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 4
    [5] => 5
    [6] => 6
    [7] => 7
    [8] => 8
    [9] => 9
    [10] => 10
)
Array
(
    [0] => 10
    [1] => 9
    [2] => 8
    [3] => 7
    [4] => 6
    [5] => 5
    [6] => 4
    [7] => 3
    [8] => 2
    [9] => 1
    [10] => 0
)
Array
(
    [0] => 0
    [1] => 2
    [2] => 4
    [3] => 6
    [4] => 8
    [5] => 10
)
Array
(
    [0] => 10
    [1] => 8
    [2] => 6
    [3] => 4
    [4] => 2
    [5] => 0
)

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to