Hi all,

I didn't receive any feedback about the first patch I sent (against
PHP_5_1), but have since realized that I should just use the MAIN branch, is
that correct?  Will someone then take care of backporting to older versions
if needed...?  (Also, from looking at http://cvs.php.net it looks like
PHP_5_1 was branched to 5_2 -- sorry about the 5_1 patch. :-/)

So here's the patch to extend array_fill() for MAIN.  Did I get it right
this time? :-)


Thanks,
Matt


----- Original Message ----- 


> Hi all,
>
> I'm on Windows and haven't tried submitting a patch before, so I JUST now
> installed WinCvs since I don't think you want just a diff of my local
file.
> I used PHP_5_1 since: 5.1's the "regular" download I started working on;
if
> you use it, I assume this can go in 5.1; and I don't know what to do. :-)
>
> I've been casually browsing through the PHP source for a while, but never
> modified it or used C.  Just found out about VC++ Express, etc. and set it
> up to try messing with PHP.  Had some missing file errors while building
> (don't know if that's my problem, or a bug...), but got it done after
> changing a few files that were causing them.  Just some background... ;-)
>
> Awhile ago I wished array_fill could also be used like array_fill(array
> keys, mixed value), which would work like:
> foreach ($keys as $k) { $array[$k] = $val; }
> OR
> $array = array_combine($keys, array_fill(0, count($keys), $val));
>
> So that's what I did for my first, admittedly simple, modification.
>
> I couldn't figure out a reason for the *newval variable, since it seemed
to
> be the same as **val (pointer stuff can confuse me, being a C newbie ;-)).
> Was I wrong to remove it?  I also wasn't sure why sizeof(val) was used in
> one place and sizeof(zval *) in another; but it seems to be random after
> looking in array.c whether var_name or zval * is used, so I stuck with the
> latter.  I realize now that they're same (right?), but it delayed me,
> assuming there's a *reason* for everything.
>
> Other things I changed while experimenting were initializing the return
> array AFTER checking the parameters so it doesn't have to be
destroyed/freed
> later; and I made the IS_LONG case first in the switch () for the first
> parameter's type -- isn't that logical since it's supposed to a PHP int
and
> probably is? :-)
>
> I hope it's coded correctly (feedback welcome, as basic as it is, LOL).
> Everything works like it should as far as I can tell.  And it's a lot
faster
> of course than the other 2 methods I mentioned for initializing arbitrary
> keys.  Let me know if I need to diff against a version other than 5.1 or
> whatever.
>
>
> Thanks,
> Matt
Index: ext/standard/array.c
===================================================================
RCS file: /repository/php-src/ext/standard/array.c,v
retrieving revision 1.350
diff -u -r1.350 array.c
--- ext/standard/array.c        25 Jun 2006 19:19:31 -0000      1.350
+++ ext/standard/array.c        1 Jul 2006 09:58:26 -0000
@@ -1625,46 +1625,83 @@
    Create an array containing num elements starting with index start_key each 
initialized to val */
 PHP_FUNCTION(array_fill)
 {
-       zval **start_key, **num, **val, *newval;
+       zval **key_data, **num, **val, **entry;
        long i;
+       HashPosition pos;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &start_key, &num, 
&val) == FAILURE) {
+       if ((ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &key_data, &num, 
&val) == FAILURE) &&
+               (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &key_data, 
&val) == FAILURE)) {
                WRONG_PARAM_COUNT;
        }
 
-       switch (Z_TYPE_PP(start_key)) {
-               case IS_STRING:
-               case IS_UNICODE:
-               case IS_LONG:
-               case IS_DOUBLE:
-                       /* allocate an array for return */
-                       array_init(return_value);
-                       
-                       if (PZVAL_IS_REF(*val)) {
-                               SEPARATE_ZVAL(val);
-                       }
-                       convert_to_long_ex(start_key);
-                       zval_add_ref(val);
-                       zend_hash_index_update(Z_ARRVAL_P(return_value), 
Z_LVAL_PP(start_key), val, sizeof(val), NULL);
-                       break;
-               default:
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong data 
type for start key");
+       if (ZEND_NUM_ARGS() == 2) {
+               if (Z_TYPE_PP(key_data) != IS_ARRAY) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "First 
parameter must be an array when passing 2 parameters");
                        RETURN_FALSE;
-                       break;
-       }       
+               }
+       } else {
+               switch (Z_TYPE_PP(key_data)) {
+                       case IS_LONG:
+                       case IS_STRING:
+                       case IS_UNICODE:
+                       case IS_DOUBLE:
+                               convert_to_long_ex(num);
+
+                               i = Z_LVAL_PP(num) - 1;
+                               if (i < 0) {
+                                       php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "Number of elements must be positive");
+                                       RETURN_FALSE;
+                               }
 
-       convert_to_long_ex(num);
-       i = Z_LVAL_PP(num) - 1; 
-       if (i < 0) {
-               zend_hash_destroy(Z_ARRVAL_P(return_value));
-               efree(Z_ARRVAL_P(return_value));
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements 
must be positive");
-               RETURN_FALSE;
+                               convert_to_long_ex(key_data);
+                               break;
+                       default:
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Wrong data type for start key");
+                               RETURN_FALSE;
+                               break;
+               }
+       }
+
+       /* Initialize return array */
+       array_init(return_value);
+
+       if (PZVAL_IS_REF(*val)) {
+               SEPARATE_ZVAL(val);
        }
-       newval = *val;
-       while (i--) {
-               zval_add_ref(&newval);
-               zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &newval, 
sizeof(zval *), NULL);
+
+
+       if (Z_TYPE_PP(key_data) == IS_LONG) {
+               zval_add_ref(val);
+               zend_hash_index_update(Z_ARRVAL_P(return_value), 
Z_LVAL_PP(key_data), val, sizeof(zval *), NULL);
+
+               while (i--) {
+                       zval_add_ref(val);
+                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), 
val, sizeof(zval *), NULL);
+               }
+       } else {
+               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(key_data), 
&pos);
+
+               while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(key_data), 
(void **)&entry, &pos) == SUCCESS) {
+                       zval_add_ref(val);
+
+                       if (Z_TYPE_PP(entry) == IS_STRING ||
+                           Z_TYPE_PP(entry) == IS_UNICODE) {
+                               
zend_u_symtable_update(Z_ARRVAL_P(return_value), Z_TYPE_PP(entry), 
Z_UNIVAL_PP(entry), Z_UNILEN_PP(entry) + 1, val, sizeof(zval *), NULL);
+                       } else if (Z_TYPE_PP(entry) == IS_LONG) {
+                               
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), val, 
sizeof(zval *), NULL);
+                       } else {
+                               zval tmpkey;
+
+                               tmpkey = **entry;
+                               zval_copy_ctor(&tmpkey);
+                               convert_to_string(&tmpkey);
+
+                               zend_symtable_update(Z_ARRVAL_P(return_value), 
Z_STRVAL(tmpkey), Z_STRLEN(tmpkey) + 1, val, sizeof(zval *), NULL);
+
+                               zval_dtor(&tmpkey);
+                       }
+                       zend_hash_move_forward_ex(Z_ARRVAL_PP(key_data), &pos);
+               }
        }
 }
 /* }}} */

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

Reply via email to