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

Reply via email to