]> granicus.if.org Git - php/commitdiff
- Added option to strstr() and stristr() to get a particular haystack component
authorJohannes Schlüter <johannes@php.net>
Tue, 9 Aug 2005 20:49:19 +0000 (20:49 +0000)
committerJohannes Schlüter <johannes@php.net>
Tue, 9 Aug 2005 20:49:19 +0000 (20:49 +0000)
NEWS
ext/standard/string.c
ext/standard/tests/strings/stristr.phpt [new file with mode: 0644]
ext/standard/tests/strings/strstr.phpt

diff --git a/NEWS b/NEWS
index 8ad5d755124575b2c45fd84068131587f82600f0..f178ca0e441af1daf32b6de130c0b905c1d53028 100644 (file)
--- 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)
index 347839b3f3310c5271775bd77eb3ec29d105f9e4..002b469476f3ca14f27d218687c4786bb88b3dd2 100644 (file)
@@ -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 (file)
index 0000000..cb5f193
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+stristr() function
+--FILE--
+<?php
+       var_dump(stristr("tEsT sTrInG", "tEsT"));
+       var_dump(stristr("tEsT sTrInG", "stRiNg"));
+       var_dump(stristr("tEsT sTrInG", "stRiN"));
+       var_dump(stristr("tEsT sTrInG", "t S"));
+       var_dump(stristr("tEsT sTrInG", "g"));
+       var_dump(md5(stristr("te".chr(0)."st", chr(0))));
+       var_dump(@stristr("", ""));
+       var_dump(@stristr("a", ""));
+       var_dump(@stristr("", "a"));
+       var_dump(md5(@stristr("\\\\a\\", "\\a")));
+       var_dump(stristr("tEsT sTrInG", " ", false));
+       var_dump(stristr("tEsT sTrInG", " ", true));
+?>
+--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"
index 10ed33ddc75cc44515fb56b3a242ad3df1109da8..e18a41053ed41ca3fd0e93dccffd6309398c0203 100644 (file)
@@ -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"