From 69303b58a429eaf8df38f5733a48f14a6d23aebb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Schl=C3=BCter?= Date: Tue, 9 Aug 2005 20:49:19 +0000 Subject: [PATCH] - Added option to strstr() and stristr() to get a particular haystack component --- NEWS | 2 + ext/standard/string.c | 97 +++++++++++++++---------- ext/standard/tests/strings/stristr.phpt | 30 ++++++++ ext/standard/tests/strings/strstr.phpt | 4 + 4 files changed, 93 insertions(+), 40 deletions(-) create mode 100644 ext/standard/tests/strings/stristr.phpt diff --git a/NEWS b/NEWS index 8ad5d75512..f178ca0e44 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Added CURLINFO_HEADER_OUT to facilitate request retrieval. - Added an optional parameter to parse_url() to allow retrieval of distinct URL components. (Ilia) +- Added an optional parameter to strstr() and stristr() for retrieval of either + the part of haystack before or after first occurence of needle. (Johannes) ?? ??? 2005, PHP 5.1 - Upgraded PCRE library to version 6.2. (Andrei) diff --git a/ext/standard/string.c b/ext/standard/string.c index 347839b3f3..002b469476 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1433,52 +1433,60 @@ PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end) } /* }}} */ -/* {{{ proto string stristr(string haystack, string needle) +/* {{{ proto string stristr(string haystack, string needle[, bool part]) Finds first occurrence of a string within another, case insensitive */ PHP_FUNCTION(stristr) { - zval **haystack, **needle; + char *haystack; + long haystack_len; + zval *needle; + zend_bool part = 0; char *found = NULL; int found_offset; char *haystack_orig; char needle_char[2]; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) { + return; } - SEPARATE_ZVAL(haystack); - SEPARATE_ZVAL(needle); - - convert_to_string_ex(haystack); + SEPARATE_ZVAL(&needle); - haystack_orig = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); + haystack_orig = estrndup(haystack, haystack_len); - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { + if (Z_TYPE_P(needle) == IS_STRING) { + if (!Z_STRLEN_P(needle)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); efree(haystack_orig); RETURN_FALSE; } - found = php_stristr(Z_STRVAL_PP(haystack), - Z_STRVAL_PP(needle), - Z_STRLEN_PP(haystack), - Z_STRLEN_PP(needle)); + found = php_stristr(haystack, + Z_STRVAL_P(needle), + haystack_len, + Z_STRLEN_P(needle)); } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); + convert_to_long_ex(&needle); + needle_char[0] = (char) Z_LVAL_P(needle); needle_char[1] = 0; - found = php_stristr(Z_STRVAL_PP(haystack), + found = php_stristr(haystack, needle_char, - Z_STRLEN_PP(haystack), + haystack_len, 1); } if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETVAL_STRINGL(haystack_orig + found_offset, Z_STRLEN_PP(haystack) - found_offset, 1); + found_offset = found - haystack; + if (part) { + char *ret; + ret = emalloc(found_offset + 1); + strncpy(ret, haystack_orig, found_offset); + ret[found_offset] = '\0'; + RETVAL_STRINGL(ret , found_offset, 0); + } else { + RETVAL_STRINGL(haystack_orig + found_offset, haystack_len - found_offset, 1); + } } else { RETVAL_FALSE; } @@ -1487,45 +1495,54 @@ PHP_FUNCTION(stristr) } /* }}} */ -/* {{{ proto string strstr(string haystack, string needle) +/* {{{ proto string strstr(string haystack, string needle[, bool part]) Finds first occurrence of a string within another */ PHP_FUNCTION(strstr) { - zval **haystack, **needle; + char *haystack; + long haystack_len; + zval *needle; + zend_bool part = 0; char *found = NULL; char needle_char[2]; long found_offset; - - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_string_ex(haystack); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) { + return; + } - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { + if (Z_TYPE_P(needle) == IS_STRING) { + if (!Z_STRLEN_P(needle)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter."); RETURN_FALSE; } - found = php_memnstr(Z_STRVAL_PP(haystack), - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + found = php_memnstr(haystack, + Z_STRVAL_P(needle), + Z_STRLEN_P(needle), + haystack + haystack_len); } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); + convert_to_long_ex(&needle); + needle_char[0] = (char) Z_LVAL_P(needle); needle_char[1] = 0; - found = php_memnstr(Z_STRVAL_PP(haystack), + found = php_memnstr(haystack, needle_char, 1, - Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + haystack + haystack_len); } if (found) { - found_offset = found - Z_STRVAL_PP(haystack); - RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); + found_offset = found - haystack; + if (part) { + char *ret; + ret = emalloc(found_offset + 1); + strncpy(ret, haystack, found_offset); + ret[found_offset] = '\0'; + RETURN_STRINGL(ret , found_offset, 0); + } else { + RETURN_STRINGL(found, haystack_len - found_offset, 1); + } } else { RETURN_FALSE; } diff --git a/ext/standard/tests/strings/stristr.phpt b/ext/standard/tests/strings/stristr.phpt new file mode 100644 index 0000000000..cb5f193c76 --- /dev/null +++ b/ext/standard/tests/strings/stristr.phpt @@ -0,0 +1,30 @@ +--TEST-- +stristr() function +--FILE-- + +--EXPECT-- +string(11) "tEsT sTrInG" +string(6) "sTrInG" +string(6) "sTrInG" +string(8) "T sTrInG" +string(1) "G" +string(32) "7272696018bdeb2c9a3f8d01fc2a9273" +bool(false) +bool(false) +bool(false) +string(32) "6ec19f52f0766c463f3bb240f4396913" +string(7) " sTrInG" +string(4) "tEsT" diff --git a/ext/standard/tests/strings/strstr.phpt b/ext/standard/tests/strings/strstr.phpt index 10ed33ddc7..e18a41053e 100644 --- a/ext/standard/tests/strings/strstr.phpt +++ b/ext/standard/tests/strings/strstr.phpt @@ -14,6 +14,8 @@ strstr() function var_dump(@strstr("a", "")); var_dump(@strstr("", "a")); var_dump(md5(@strstr("\\\\a\\", "\\a"))); + var_dump(strstr("test string", " ", false)); + var_dump(strstr("test string", " ", true)); ?> --EXPECT-- string(11) "test string" @@ -28,3 +30,5 @@ bool(false) bool(false) bool(false) string(32) "6ec19f52f0766c463f3bb240f4396913" +string(7) " string" +string(4) "test" -- 2.50.1