summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-03-29 10:29:29 -0600
committerKarl Williamson <khw@cpan.org>2020-08-13 14:06:45 -0600
commit66256797ef032411a88bcb391415a291004066d8 (patch)
tree066449b778b76b6fd6e36cb314712914911bb2b8 /util.c
parent6841cd5977c2d35ad75233734c66983a65613fce (diff)
downloadperl-66256797ef032411a88bcb391415a291004066d8.tar.gz
ninstr(): Use memchr instead of a loop
This function is perl's memmem if that function isn't available. This commit replaces its loop with a call to memchr, which is a C89 function.
Diffstat (limited to 'util.c')
-rw-r--r--util.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/util.c b/util.c
index 61ead11ccf..578ceddabb 100644
--- a/util.c
+++ b/util.c
@@ -672,23 +672,32 @@ Perl_ninstr(const char *big, const char *bigend, const char *little, const char
return ninstr(big, bigend, little, lend);
#else
- if (little >= lend)
- return (char*)big;
- {
- const char first = *little;
- bigend -= lend - little++;
- OUTER:
+ if (little >= lend) {
+ return (char*) big;
+ }
+ else {
+ const U8 first = *little;
+ Size_t lsize;
+
+ /* No match can start closer to the end of the haystack than the length
+ * of the needle. */
+ bigend -= lend - little;
+ little++; /* Look for 'first', then the remainder is in here */
+ lsize = lend - little;
+
while (big <= bigend) {
- if (*big++ == first) {
- const char *s, *x;
- for (x=big,s=little; s < lend; x++,s++) {
- if (*s != *x)
- goto OUTER;
- }
- return (char*)(big-1);
+ big = (char *) memchr((U8 *) big, first, bigend - big + 1);
+ if (big == NULL || big > bigend) {
+ return NULL;
+ }
+
+ if (memEQ(big + 1, little, lsize)) {
+ return (char*) big;
}
+ big++;
}
}
+
return NULL;
#endif