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 #55158Patch version 2011-08-04 16:00 UTC Return to Bug #55158 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:Developer: arpad@php.netIndex: 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 |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 12:01:29 2024 UTC |