php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch php-trunk-array_multisort-natural-case for Arrays related Bug #55158

Patch version 2011-08-04 16:00 UTC

Return to Bug #55158 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: arpad@php.net

Index: ext/standard/array.c
===================================================================
--- ext/standard/array.c	(revision 313904)
+++ ext/standard/array.c	(working copy)
@@ -118,6 +118,8 @@
 	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_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_CASE", PHP_SORT_CASE, 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);
@@ -141,15 +143,19 @@
 
 static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */
 {
-	switch (sort_type) {
+	switch (sort_type & ~PHP_SORT_CASE) {
 		case PHP_SORT_NUMERIC:
 			ARRAYG(compare_func) = numeric_compare_function;
 			break;
 
 		case PHP_SORT_STRING:
-			ARRAYG(compare_func) = string_compare_function;
+			ARRAYG(compare_func) = sort_type & PHP_SORT_CASE ? string_case_compare_function : string_compare_function;
 			break;
 
+		case PHP_SORT_NATURAL:
+			ARRAYG(compare_func) = sort_type & PHP_SORT_CASE ? string_natural_case_compare_function : string_natural_compare_function;
+			break;
+
 #if HAVE_STRCOLL
 		case PHP_SORT_LOCALE_STRING:
 			ARRAYG(compare_func) = string_locale_compare_function;
@@ -3762,7 +3768,7 @@
 	efree(args);							\
 	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_CASE]] [, array ar2 [, SORT_ASC|SORT_DESC [, SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_CASE]], ...])
    Sort multiple arrays at once similar to how ORDER BY clause works in SQL */
 PHP_FUNCTION(array_multisort)
 {
@@ -3812,7 +3818,7 @@
 				parse_state[k] = 1;
 			}
 		} else if (Z_TYPE_PP(args[i]) == IS_LONG) {
-			switch (Z_LVAL_PP(args[i])) {
+			switch (Z_LVAL_PP(args[i]) & ~PHP_SORT_CASE) {
 				case PHP_SORT_ASC:
 				case PHP_SORT_DESC:
 					/* flag allowed here */
@@ -3829,6 +3835,7 @@
 				case PHP_SORT_REGULAR:
 				case PHP_SORT_NUMERIC:
 				case PHP_SORT_STRING:
+				case PHP_SORT_NATURAL:
 #if HAVE_STRCOLL
 				case PHP_SORT_LOCALE_STRING:
 #endif
Index: ext/standard/string.c
===================================================================
--- ext/standard/string.c	(revision 313904)
+++ ext/standard/string.c	(working copy)
@@ -4734,6 +4734,49 @@
 }
 /* }}} */
 
+PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
+{
+	zval op1_copy, op2_copy;
+	int use_copy1 = 0, use_copy2 = 0, sort_result;
+
+	if (Z_TYPE_P(op1) != IS_STRING) {
+		zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+	}
+	if (Z_TYPE_P(op2) != IS_STRING) {
+		zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+	}
+
+	if (use_copy1) {
+		op1 = &op1_copy;
+	}
+	if (use_copy2) {
+		op2 = &op2_copy;
+	}
+
+	ZVAL_LONG(result, strnatcmp_ex(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2), case_insensitive));
+
+	if (use_copy1) {
+		zval_dtor(op1);
+	}
+	if (use_copy2) {
+		zval_dtor(op2);
+	}
+	return SUCCESS;
+}
+/* }}} */
+
+PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+	return string_natural_compare_function_ex(result, op1, op2, 1 TSRMLS_CC);
+}
+/* }}} */
+
+PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+	return string_natural_compare_function_ex(result, op1, op2, 0 TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ proto int strnatcmp(string s1, string s2)
    Returns the result of string comparison using 'natural' algorithm */
 PHP_FUNCTION(strnatcmp)
Index: ext/standard/php_array.h
===================================================================
--- ext/standard/php_array.h	(revision 313904)
+++ ext/standard/php_array.h	(working copy)
@@ -113,6 +113,8 @@
 #define PHP_SORT_DESC               3
 #define PHP_SORT_ASC                4
 #define PHP_SORT_LOCALE_STRING      5
+#define PHP_SORT_NATURAL            6
+#define PHP_SORT_CASE               8
 
 ZEND_BEGIN_MODULE_GLOBALS(array) 
 	int *multisort_flags[2];
Index: ext/standard/php_string.h
===================================================================
--- ext/standard/php_string.h	(revision 313904)
+++ ext/standard/php_string.h	(working copy)
@@ -143,6 +143,10 @@
 PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end); 
 PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end); 
 
+PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC);
+PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+
 #ifndef HAVE_STRERROR
 PHPAPI char *php_strerror(int errnum);
 #define strerror php_strerror
Index: Zend/zend_operators.c
===================================================================
--- Zend/zend_operators.c	(revision 313904)
+++ Zend/zend_operators.c	(working copy)
@@ -1288,7 +1288,7 @@
 }
 /* }}} */
 
-ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
 {
 	zval op1_copy, op2_copy;
 	int use_copy1 = 0, use_copy2 = 0;
@@ -1307,7 +1307,11 @@
 		op2 = &op2_copy;
 	}
 
-	ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
+	if (case_insensitive) {
+		ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2));
+	} else {
+		ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
+	}
 
 	if (use_copy1) {
 		zval_dtor(op1);
@@ -1319,6 +1323,18 @@
 }
 /* }}} */
 
+ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+	return string_compare_function_ex(result, op1, op2, 0);
+}
+/* }}} */
+
+ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
+{
+	return string_compare_function_ex(result, op1, op2, 1);
+}
+/* }}} */
+
 #if HAVE_STRCOLL
 ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
 {
Index: Zend/zend_operators.h
===================================================================
--- Zend/zend_operators.h	(revision 313904)
+++ Zend/zend_operators.h	(working copy)
@@ -301,7 +301,9 @@
 ZEND_API int zval_is_true(zval *op);
 ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
 ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC);
 ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
 #if HAVE_STRCOLL
 ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
 #endif
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 12:01:59 2014 UTC