diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | ext/pcre/php_pcre.c | 1 | ||||
-rw-r--r-- | ext/standard/basic_functions.c | 1 | ||||
-rw-r--r-- | ext/standard/php_string.h | 1 | ||||
-rw-r--r-- | ext/standard/string.c | 53 |
5 files changed, 58 insertions, 0 deletions
@@ -31,6 +31,8 @@ global * find a better way to implement script timeouts. SIGVTALRM is used by some POSIX threads implementations (i.e. OpenBSD) and is not available in ZTS mode. + * add aliases to functions to conform to new naming conventions, e.g. + str_to_upper(). documentation ------------- diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 7a9289803f..f8a19fb99c 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -24,6 +24,7 @@ - Make new modifier, similar to /e, that passes matches to a user-defined function - add option to preg_grep() to return entries that _don't_ match + - add option to preg_grep() to return the matching keys */ #include "php.h" diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 587ecea7e1..1fa2dab0fd 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -122,6 +122,7 @@ function_entry basic_functions[] = { PHP_FE(strnatcmp, NULL) PHP_FE(strnatcasecmp, NULL) + PHP_FE(substr_count, NULL) PHP_FE(strspn, NULL) PHP_FE(strcspn, NULL) PHP_FE(strtok, NULL) diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 81d703553d..9e31cb3cd9 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -84,6 +84,7 @@ PHP_FUNCTION(str_repeat); PHP_FUNCTION(substr_replace); PHP_FUNCTION(strnatcmp); PHP_FUNCTION(strnatcasecmp); +PHP_FUNCTION(substr_count); #define strnatcmp(a, b) \ strnatcmp_ex(a, strlen(a), b, strlen(b), 0) diff --git a/ext/standard/string.c b/ext/standard/string.c index 03930d85bc..39d9bd5e18 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2473,12 +2473,65 @@ static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case) fold_case)); } + +/* {{{ proto int strnatcmp(string s1, string s2) + Returns the result of string comparison using 'natural' algorithm */ PHP_FUNCTION(strnatcmp) { php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } +/* }}} */ + +/* {{{ proto int strnatcasecmp(string s1, string s2) + Returns the result of case-insensitive string comparison using 'natural' algorithm */ PHP_FUNCTION(strnatcasecmp) { php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); } +/* }}} */ + + +/* {{{ proto int str_count(string haystack, string needle) + Returns the number of times a substring occurs in the string. */ +PHP_FUNCTION(substr_count) +{ + zval **haystack, **needle; + int i, length, count = 0; + char *p, *endp, cmp; + + if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &haystack, &needle) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_string_ex(haystack); + convert_to_string_ex(needle); + + if ((*needle)->value.str.len == 0) { + php_error(E_WARNING, "Empty substring"); + RETURN_FALSE; + } else if ((*needle)->value.str.len == 1) { + // Special optimized case to avoid calls to php_memnstr + for (i = 0, p = (*haystack)->value.str.val, + length = (*haystack)->value.str.len, cmp = (*needle)->value.str.val[0]; + i < length; i++) { + if (p[i] == cmp) { + count++; + } + } + } else { + p = (*haystack)->value.str.val; + endp = p + (*haystack)->value.str.len; + while (p <= endp) { + if( (p = php_memnstr(p, (*needle)->value.str.val, (*needle)->value.str.len, endp)) != NULL ) { + p += (*needle)->value.str.len; + count++; + } else { + break; + } + } + } + + RETURN_LONG(count); +} +/* }}} */ |