cvs: php4 /ext/standard string.c
| From: | Sara Golemon | 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;
}
/* }}} */