rolland Mon Oct 24 10:35:05 2005 EDT Modified files: /php-src/ext/standard string.c Log: - Unicode impl of strrchr() http://cvs.php.net/diff.php/php-src/ext/standard/string.c?r1=1.503&r2=1.504&ty=u Index: php-src/ext/standard/string.c diff -u php-src/ext/standard/string.c:1.503 php-src/ext/standard/string.c:1.504 --- php-src/ext/standard/string.c:1.503 Sat Oct 22 09:36:55 2005 +++ php-src/ext/standard/string.c Mon Oct 24 10:35:02 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.503 2005/10/22 13:36:55 rolland Exp $ */ +/* $Id: string.c,v 1.504 2005/10/24 14:35:02 rolland Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -2714,30 +2714,82 @@ } /* }}} */ +/* {{{ php_u_strrchr + */ +UChar *php_u_strrchr(UChar *s, UChar32 ch, int32_t s_len) +{ + UChar32 ch1; + int32_t i = s_len; + + while (i > 0) { + U16_PREV(s, 0, i, ch1); + if (ch1 == ch) { + return (s+i); + } + } + return NULL; +} +/* }}} */ + /* {{{ proto string strrchr(string haystack, string needle) Finds the last occurrence of a character in a string within another */ PHP_FUNCTION(strrchr) { - zval **haystack, **needle; - char *found = NULL; - long found_offset; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == - FAILURE) { + zval *haystack, *needle; + zend_uchar str_type; + UChar32 ch; + void *found = NULL; + int32_t found_offset; + + if (ZEND_NUM_ARGS() != 2 || zend_parse_parameters(2 TSRMLS_CC, "zz", &haystack, &needle) == FAILURE) { WRONG_PARAM_COUNT; } - convert_to_string_ex(haystack); + if (Z_TYPE_P(haystack) != IS_UNICODE || Z_TYPE_P(haystack) != IS_BINARY || Z_TYPE_P(haystack) != IS_STRING) { + convert_to_string(haystack); + } - if (Z_TYPE_PP(needle) == IS_STRING) { - found = strrchr(Z_STRVAL_PP(haystack), *Z_STRVAL_PP(needle)); + if (Z_TYPE_P(needle) == IS_UNICODE || Z_TYPE_P(needle) == IS_BINARY || Z_TYPE_P(needle) == IS_STRING) { + if (Z_TYPE_P(needle) != Z_TYPE_P(haystack)) { + str_type = zend_get_unified_string_type(2 TSRMLS_CC, Z_TYPE_P(haystack), Z_TYPE_P(needle)); + if (str_type == (zend_uchar)-1) { + convert_to_explicit_type(haystack, IS_BINARY); + convert_to_explicit_type(needle, IS_BINARY); + } else { + convert_to_explicit_type(haystack, str_type); + convert_to_explicit_type(needle, str_type); + } + } + if (Z_TYPE_P(haystack) == IS_UNICODE) { + U16_GET(Z_USTRVAL_P(needle), 0, 0, Z_USTRLEN_P(needle), ch); + found = php_u_strrchr(Z_USTRVAL_P(haystack), ch, Z_USTRLEN_P(haystack)); + } else { + found = strrchr(Z_STRVAL_P(haystack), *Z_STRVAL_P(needle)); + } } else { - convert_to_long_ex(needle); - found = strrchr(Z_STRVAL_PP(haystack), (char) Z_LVAL_PP(needle)); + convert_to_long(needle); + if (Z_TYPE_P(haystack) == IS_UNICODE) { + if (Z_LVAL_P(needle) < 0 || Z_LVAL_P(needle) > 0x10FFFF) { + php_error(E_WARNING, "Needle argument codepoint value out of range (0 - 0x10FFFF)"); + RETURN_FALSE; + } + found = php_u_strrchr(Z_USTRVAL_P(haystack), (UChar32)Z_LVAL_P(needle), Z_USTRLEN_P(haystack)); + } else { + found = strrchr(Z_STRVAL_P(haystack), (char)Z_LVAL_P(needle)); + } } if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); + if (Z_TYPE_P(haystack) == IS_UNICODE) { + found_offset = (UChar *)found - Z_USTRVAL_P(haystack); + RETURN_UNICODEL((UChar *)found, Z_USTRLEN_P(haystack) - found_offset, 1); + } else { + found_offset = (char *)found - Z_STRVAL_P(haystack); + if (Z_TYPE_P(haystack) == IS_BINARY) { + RETURN_BINARYL((char *)found, Z_BINLEN_P(haystack) - found_offset, 1); + } else { + RETURN_STRINGL((char *)found, Z_STRLEN_P(haystack) - found_offset, 1); + } + } } else { RETURN_FALSE; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php