cvs: php4 /ext/standard string.c

From: Date: Sat, 12 Apr 2003 07:36:22 +0000
Subject: cvs: php4 /ext/standard string.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-20236@lists.php.net to get a copy of this message
pollita Sat Apr 12 03:36:22 2003 EDT Modified files: /php4/ext/standard string.c Log: Rewrite strrpos and strripos to be binary safe and behave the way their prototype suggests (also like their counterparts strpos and stripos) i.e.: Allow string needles rather than just characters Index: php4/ext/standard/string.c diff -u php4/ext/standard/string.c:1.370 php4/ext/standard/string.c:1.371 --- php4/ext/standard/string.c:1.370 Thu Apr 3 01:21:59 2003 +++ php4/ext/standard/string.c Sat Apr 12 03:36:22 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.370 2003/04/03 06:21:59 derick Exp $ */ +/* $Id: string.c,v 1.371 2003/04/12 07:36:22 pollita Exp $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -1568,87 +1568,82 @@ /* }}} */ /* {{{ proto int strrpos(string haystack, string needle [, int offset]) - Finds position of last occurrence of a character in a string within another */ + Finds position of last occurrence of a string within another string */ PHP_FUNCTION(strrpos) { - zval **haystack, **needle, **offset; - char *found = NULL; - int argc = ZEND_NUM_ARGS(); - int off = 0; - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &haystack, &needle, &offset) == FAILURE) { - WRONG_PARAM_COUNT; + char *needle, *haystack; + int needle_len, haystack_len, offset = 0; + char *p, *e; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &haystack, &haystack_len, &needle, &needle_len, &offset) == FAILURE) { + RETURN_FALSE; } - convert_to_string_ex(haystack); - if (argc == 3) { - convert_to_long_ex(offset); - if (Z_LVAL_PP(offset) < 0 || Z_LVAL_PP(offset) > Z_STRLEN_PP(haystack)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; + if (offset >= 0) { + p = haystack + offset; + e = haystack + haystack_len - needle_len; + } else { + p = haystack; + if (needle_len > -offset) { + e = haystack + haystack_len - needle_len; + } else { + e = haystack + haystack_len + offset; } - off = Z_LVAL_PP(offset); } - if (Z_TYPE_PP(needle) == IS_STRING) { - found = strrchr(Z_STRVAL_PP(haystack) + off, *Z_STRVAL_PP(needle)); - } else { - convert_to_long_ex(needle); - found = strrchr(Z_STRVAL_PP(haystack) + off, (char) Z_LVAL_PP(needle)); + while (e >= p) { + if (memcmp(e, needle, needle_len) == 0) { + RETURN_LONG(e - p); + } + e--; } - if (found) { - RETURN_LONG(Z_STRLEN_PP(haystack) - strlen(found)); - } else { - RETURN_FALSE; - } + RETURN_FALSE; } /* }}} */ /* {{{ proto int strripos(string haystack, string needle [, int offset]) - Finds position of last occurrence of a character in a string within another, case insensitive */ + Finds position of last occurrence of a string within another string */ PHP_FUNCTION(strripos) { - zval **haystack, **needle, **offset; - char *found = NULL; - int argc = ZEND_NUM_ARGS(); - int off = 0; - char *haystack_dup; - char needle_dup; - - if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &haystack, &needle, &offset) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); + char *needle, *haystack; + int needle_len, haystack_len, offset = 0; + char *p, *e; + char *needle_dup, *haystack_dup; - if (argc == 3) { - convert_to_long_ex(offset); - if (Z_LVAL_PP(offset) < 0 || Z_LVAL_PP(offset) > Z_STRLEN_PP(haystack)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset not contained in string."); - RETURN_FALSE; - } - off = Z_LVAL_PP(offset); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &haystack, &haystack_len, &needle, &needle_len, &offset) == FAILURE) { + RETURN_FALSE; } - haystack_dup = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); - php_strtolower(haystack_dup, Z_STRLEN_PP(haystack)); + needle_dup = estrndup(needle, needle_len); + php_strtolower(needle_dup, needle_len); + haystack_dup = estrndup(haystack, haystack_len); + php_strtolower(haystack_dup, haystack_len); - if (Z_TYPE_PP(needle) == IS_STRING) { - needle_dup = *Z_STRVAL_PP(needle); - } else { - convert_to_long_ex(needle); - needle_dup = (char) Z_LVAL_PP(needle); + if (offset >= 0) { + p = haystack_dup + offset; + e = haystack_dup + haystack_len - needle_len; + } else { + p = haystack_dup; + if (needle_len > -offset) { + e = haystack_dup + haystack_len - needle_len; + } else { + e = haystack_dup + haystack_len + offset; + } } - found = strrchr(haystack_dup + off, tolower(needle_dup)); + while (e >= p) { + if (memcmp(e, needle_dup, needle_len) == 0) { + efree(haystack_dup); + efree(needle_dup); + RETURN_LONG(e - p); + } + e--; + } efree(haystack_dup); - - if (found) { - RETURN_LONG(Z_STRLEN_PP(haystack) - strlen(found)); - } else { - RETURN_FALSE; - } + efree(needle_dup); + RETURN_FALSE; } /* }}} */

« previous php.cvs (#20236) next »