Skip to content

Commit f488b5d

Browse files
committed
Merge mb_strstr() variants under a common implementation
This reduces heavy ducplicate code
1 parent 7378713 commit f488b5d

File tree

1 file changed

+37
-124
lines changed

1 file changed

+37
-124
lines changed

ext/mbstring/mbstring.c

Lines changed: 37 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,26 +2165,41 @@ PHP_FUNCTION(mb_strripos)
21652165
}
21662166
/* }}} */
21672167

2168-
/* {{{ proto string mb_strstr(string haystack, string needle[, bool part[, string encoding]])
2169-
Finds first occurrence of a string within another */
2170-
PHP_FUNCTION(mb_strstr)
2168+
#define MB_STRSTR 1
2169+
#define MB_STRRCHR 2
2170+
#define MB_STRISTR 3
2171+
#define MB_STRRICHR 4
2172+
/* {{{ php_mb_strstr_variants */
2173+
static void php_mb_strstr_variants(INTERNAL_FUNCTION_PARAMETERS, unsigned int variant)
21712174
{
2175+
int reverse_mode = 0;
21722176
size_t n;
21732177
mbfl_string haystack, needle, result, *ret = NULL;
2174-
zend_string *enc_name = NULL;
2178+
zend_string *encoding_name = NULL;
21752179
zend_bool part = 0;
21762180

2177-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bS", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name) == FAILURE) {
2181+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bS",
2182+
(char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len,
2183+
&part, &encoding_name) == FAILURE
2184+
) {
21782185
RETURN_THROWS();
21792186
}
21802187

21812188
haystack.no_language = needle.no_language = MBSTRG(language);
2182-
haystack.encoding = needle.encoding = php_mb_get_encoding(enc_name, 4);
2189+
haystack.encoding = needle.encoding = php_mb_get_encoding(encoding_name, 4);
21832190
if (!haystack.encoding) {
21842191
RETURN_THROWS();
21852192
}
21862193

2187-
n = mbfl_strpos(&haystack, &needle, 0, 0);
2194+
if (variant == MB_STRRCHR || variant == MB_STRRICHR) { reverse_mode = 1; }
2195+
2196+
if (variant == MB_STRISTR || variant == MB_STRRICHR) {
2197+
n = php_mb_stripos(reverse_mode, (char *)haystack.val, haystack.len, (char *)needle.val,
2198+
needle.len, 0, needle.encoding);
2199+
} else {
2200+
n = mbfl_strpos(&haystack, &needle, 0, reverse_mode);
2201+
}
2202+
21882203
if (!mbfl_is_error(n)) {
21892204
if (part) {
21902205
ret = mbfl_substr(&haystack, &result, 0, n);
@@ -2209,146 +2224,44 @@ PHP_FUNCTION(mb_strstr)
22092224
RETVAL_FALSE;
22102225
}
22112226
}
2227+
2228+
/* {{{ proto string mb_strstr(string haystack, string needle[, bool part[, string encoding]])
2229+
Finds first occurrence of a string within another */
2230+
PHP_FUNCTION(mb_strstr)
2231+
{
2232+
php_mb_strstr_variants(INTERNAL_FUNCTION_PARAM_PASSTHRU, MB_STRSTR);
2233+
}
22122234
/* }}} */
22132235

22142236
/* {{{ proto string mb_strrchr(string haystack, string needle[, bool part[, string encoding]])
22152237
Finds the last occurrence of a character in a string within another */
22162238
PHP_FUNCTION(mb_strrchr)
22172239
{
2218-
size_t n;
2219-
mbfl_string haystack, needle, result, *ret = NULL;
2220-
zend_string *enc_name = NULL;
2221-
zend_bool part = 0;
2222-
2223-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bS", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &enc_name) == FAILURE) {
2224-
RETURN_THROWS();
2225-
}
2226-
2227-
haystack.no_language = needle.no_language = MBSTRG(language);
2228-
haystack.encoding = needle.encoding = php_mb_get_encoding(enc_name, 4);
2229-
if (!haystack.encoding) {
2230-
RETURN_THROWS();
2231-
}
2232-
2233-
n = mbfl_strpos(&haystack, &needle, 0, 1);
2234-
if (!mbfl_is_error(n)) {
2235-
if (part) {
2236-
ret = mbfl_substr(&haystack, &result, 0, n);
2237-
if (ret != NULL) {
2238-
// TODO: avoid reallocation ???
2239-
RETVAL_STRINGL((char *)ret->val, ret->len);
2240-
efree(ret->val);
2241-
} else {
2242-
RETVAL_FALSE;
2243-
}
2244-
} else {
2245-
ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END);
2246-
if (ret != NULL) {
2247-
// TODO: avoid reallocation ???
2248-
RETVAL_STRINGL((char *)ret->val, ret->len);
2249-
efree(ret->val);
2250-
} else {
2251-
RETVAL_FALSE;
2252-
}
2253-
}
2254-
} else {
2255-
RETVAL_FALSE;
2256-
}
2240+
php_mb_strstr_variants(INTERNAL_FUNCTION_PARAM_PASSTHRU, MB_STRRCHR);
22572241
}
22582242
/* }}} */
22592243

22602244
/* {{{ proto string mb_stristr(string haystack, string needle[, bool part[, string encoding]])
22612245
Finds first occurrence of a string within another, case insensitive */
22622246
PHP_FUNCTION(mb_stristr)
22632247
{
2264-
zend_bool part = 0;
2265-
size_t n;
2266-
mbfl_string haystack, needle, result, *ret = NULL;
2267-
zend_string *from_encoding = NULL;
2268-
2269-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bS", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding) == FAILURE) {
2270-
RETURN_THROWS();
2271-
}
2272-
2273-
haystack.no_language = needle.no_language = MBSTRG(language);
2274-
haystack.encoding = needle.encoding = php_mb_get_encoding(from_encoding, 4);
2275-
if (!haystack.encoding) {
2276-
RETURN_THROWS();
2277-
}
2278-
2279-
n = php_mb_stripos(0, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, 0, needle.encoding);
2280-
if (mbfl_is_error(n)) {
2281-
RETURN_FALSE;
2282-
}
2283-
2284-
if (part) {
2285-
ret = mbfl_substr(&haystack, &result, 0, n);
2286-
if (ret != NULL) {
2287-
// TODO: avoid reallocation ???
2288-
RETVAL_STRINGL((char *)ret->val, ret->len);
2289-
efree(ret->val);
2290-
} else {
2291-
RETVAL_FALSE;
2292-
}
2293-
} else {
2294-
ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END);
2295-
if (ret != NULL) {
2296-
// TODO: avoid reallocaton ???
2297-
RETVAL_STRINGL((char *)ret->val, ret->len);
2298-
efree(ret->val);
2299-
} else {
2300-
RETVAL_FALSE;
2301-
}
2302-
}
2248+
php_mb_strstr_variants(INTERNAL_FUNCTION_PARAM_PASSTHRU, MB_STRISTR);
23032249
}
23042250
/* }}} */
23052251

23062252
/* {{{ proto string mb_strrichr(string haystack, string needle[, bool part[, string encoding]])
23072253
Finds the last occurrence of a character in a string within another, case insensitive */
23082254
PHP_FUNCTION(mb_strrichr)
23092255
{
2310-
zend_bool part = 0;
2311-
size_t n;
2312-
mbfl_string haystack, needle, result, *ret = NULL;
2313-
zend_string *from_encoding = NULL;
2314-
2315-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bS", (char **)&haystack.val, &haystack.len, (char **)&needle.val, &needle.len, &part, &from_encoding) == FAILURE) {
2316-
RETURN_THROWS();
2317-
}
2318-
2319-
haystack.no_language = needle.no_language = MBSTRG(language);
2320-
haystack.encoding = needle.encoding = php_mb_get_encoding(from_encoding, 4);
2321-
if (!haystack.encoding) {
2322-
RETURN_THROWS();
2323-
}
2324-
2325-
n = php_mb_stripos(1, (char *)haystack.val, haystack.len, (char *)needle.val, needle.len, 0, needle.encoding);
2326-
if (mbfl_is_error(n)) {
2327-
RETURN_FALSE;
2328-
}
2329-
2330-
if (part) {
2331-
ret = mbfl_substr(&haystack, &result, 0, n);
2332-
if (ret != NULL) {
2333-
// TODO: avoid reallocation ???
2334-
RETVAL_STRINGL((char *)ret->val, ret->len);
2335-
efree(ret->val);
2336-
} else {
2337-
RETVAL_FALSE;
2338-
}
2339-
} else {
2340-
ret = mbfl_substr(&haystack, &result, n, MBFL_SUBSTR_UNTIL_END);
2341-
if (ret != NULL) {
2342-
// TODO: avoid reallocation ???
2343-
RETVAL_STRINGL((char *)ret->val, ret->len);
2344-
efree(ret->val);
2345-
} else {
2346-
RETVAL_FALSE;
2347-
}
2348-
}
2256+
php_mb_strstr_variants(INTERNAL_FUNCTION_PARAM_PASSTHRU, MB_STRRICHR);
23492257
}
23502258
/* }}} */
23512259

2260+
#undef MB_STRSTR
2261+
#undef MB_STRRCHR
2262+
#undef MB_STRISTR
2263+
#undef MB_STRRICHR
2264+
23522265
/* {{{ proto int mb_substr_count(string haystack, string needle [, string encoding])
23532266
Count the number of substring occurrences */
23542267
PHP_FUNCTION(mb_substr_count)

0 commit comments

Comments
 (0)