cvs: php4 /ext/standard/ array.c basic_functions.c php_array.h

[email protected] ("Andrei Zmievski") Tue, 30 May 2000 17:03:56 -0000
Newsgroups php.version4
Message-ID <cvsandrei959706236@cvsserver>
andrei		Tue May 30 10:03:56 2000 EDT

  Modified files:
    /php4/ext/standard	array.c basic_functions.c php_array.h 
  Log:
  
  @- Added array_merge_recursive() that will recursively merge values
  @  under the same keys. (Andrei)
  
  
Index: php4/ext/standard/array.c
diff -u php4/ext/standard/array.c:1.46 php4/ext/standard/array.c:1.47
--- php4/ext/standard/array.c:1.46	Wed May 24 12:07:17 2000
+++ php4/ext/standard/array.c	Tue May 30 10:03:56 2000
@@ -1734,17 +1734,48 @@
 /* }}} */
 
 
-/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
-   Merges elements from passed arrays into one array */
-PHP_FUNCTION(array_merge)
+static void php_array_merge_impl(HashTable *dest, HashTable *src, int recursive)
+{
+	zval	  **src_entry,
+			  **dest_entry;
+	char	   *string_key;
+	ulong		num_key;
+
+	zend_hash_internal_pointer_reset(src);
+	while(zend_hash_get_current_data(src, (void **)&src_entry) == SUCCESS) {
+		switch (zend_hash_get_current_key(src, &string_key, &num_key)) {
+			case HASH_KEY_IS_STRING:
+				if (recursive &&
+					zend_hash_find(dest, string_key, strlen(string_key) + 1,
+								   (void **)&dest_entry) == SUCCESS) {
+					convert_to_array_ex(dest_entry);
+					convert_to_array_ex(src_entry);
+					php_array_merge_impl(Z_ARRVAL_PP(dest_entry),
+										 Z_ARRVAL_PP(src_entry), recursive);
+				} else {
+					(*src_entry)->refcount++;
+
+					zend_hash_update(dest, string_key, strlen(string_key)+1,
+									 src_entry, sizeof(zval *), NULL);
+				}
+				efree(string_key);
+				break;
+
+			case HASH_KEY_IS_LONG:
+				(*src_entry)->refcount++;
+				zend_hash_next_index_insert(dest, src_entry, sizeof(zval *), NULL);
+				break;
+		}
+
+		zend_hash_move_forward(src);
+	}
+}
+
+static void php_array_merge(INTERNAL_FUNCTION_PARAMETERS, int recursive)
 {
-	zval	  ***args = NULL,
-			   **entry;
-	HashTable	*hash;
+	zval	  ***args = NULL;
 	int			 argc,
 				 i;
-	char		*string_key;
-	ulong		 num_key;
 
 	/* Get the argument count and check it */	
 	argc = ARG_COUNT(ht);
@@ -1762,34 +1793,28 @@
 	array_init(return_value);
 	
 	for (i=0; i<argc; i++) {
-		if ((*args[i])->type != IS_ARRAY) {
-			php_error(E_WARNING, "Skipping argument #%d to array_merge(), since it's not an array", i+1);
-			continue;
-		}
-		hash = (*args[i])->value.ht;
-		
-		zend_hash_internal_pointer_reset(hash);
-		while(zend_hash_get_current_data(hash, (void **)&entry) == SUCCESS) {
-			(*entry)->refcount++;
-			
-			switch (zend_hash_get_current_key(hash, &string_key, &num_key)) {
-				case HASH_KEY_IS_STRING:
-					zend_hash_update(return_value->value.ht, string_key, strlen(string_key)+1,
-									 entry, sizeof(zval *), NULL);
-					efree(string_key);
-					break;
-
-				case HASH_KEY_IS_LONG:
-					zend_hash_next_index_insert(return_value->value.ht,
-												entry, sizeof(zval *), NULL);
-					break;
-			}
-
-			zend_hash_move_forward(hash);
-		}
+		convert_to_array_ex(args[i]);
+		php_array_merge_impl(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive);
 	}
 	
 	efree(args);
+}
+
+
+/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
+   Merges elements from passed arrays into one array */
+PHP_FUNCTION(array_merge)
+{
+	php_array_merge(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+
+/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
+   Recursively merges elements from passed arrays into one array */
+PHP_FUNCTION(array_merge_recursive)
+{
+	php_array_merge(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
 }
 /* }}} */
 
Index: php4/ext/standard/basic_functions.c
diff -u php4/ext/standard/basic_functions.c:1.200 php4/ext/standard/basic_functions.c:1.201
--- php4/ext/standard/basic_functions.c:1.200	Mon May 29 09:51:27 2000
+++ php4/ext/standard/basic_functions.c	Tue May 30 10:03:56 2000
@@ -495,6 +495,7 @@
 	PHP_FE(array_splice,							first_arg_force_ref)
 	PHP_FE(array_slice,								NULL)
 	PHP_FE(array_merge,								NULL)
+	PHP_FE(array_merge_recursive,					NULL)
 	PHP_FE(array_keys,								NULL)
 	PHP_FE(array_values,							NULL)
 	PHP_FE(array_count_values,		 			  	NULL)
Index: php4/ext/standard/php_array.h
diff -u php4/ext/standard/php_array.h:1.10 php4/ext/standard/php_array.h:1.11
--- php4/ext/standard/php_array.h:1.10	Thu May 18 08:34:35 2000
+++ php4/ext/standard/php_array.h	Tue May 30 10:03:56 2000
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_array.h,v 1.10 2000/05/18 15:34:35 zeev Exp $ */
+/* $Id: php_array.h,v 1.11 2000/05/30 17:03:56 andrei Exp $ */
 
 #ifndef _PHP_ARRAY_H
 #define _PHP_ARRAY_H
@@ -61,6 +61,7 @@
 PHP_FUNCTION(array_splice);
 PHP_FUNCTION(array_slice);
 PHP_FUNCTION(array_merge);
+PHP_FUNCTION(array_merge_recursive);
 PHP_FUNCTION(array_keys);
 PHP_FUNCTION(array_values);
 PHP_FUNCTION(array_count_values);