Perl_instr() implement with libc equivalent.
authorKarl Williamson <public@khwilliamson.com>
Mon, 24 Dec 2012 15:56:22 +0000 (08:56 -0700)
committerKarl Williamson <public@khwilliamson.com>
Thu, 27 Dec 2012 16:13:45 +0000 (09:13 -0700)
C89 libc contains the strstr() function that does the same thing as
instr().  Convert to use it under the assumption that it is faster than
our code, and is less for us to maintain.  Because early versions of
Lunix libc had a bug when the 'little' argument was NULL (fixed in late
1994), check for that explicitly.  If we were willing to ignore issues
with such old libc versions, or if we had a Configure probe that tested
for the bug, we could replace the macro instr() completely with a call
to strstr().

The memmem() GNU extension does the same thing as Perl_ninstr().  It
however has bugs in much later libc versions.  A Configure probe could
be written to see if it is usable.

util.c

diff --git a/util.c b/util.c
index 987e41e..a3fbd3c 100644 (file)
--- a/util.c
+++ b/util.c
@@ -428,33 +428,13 @@ Perl_delimcpy(char *to, const char *toend, const char *from, const char *fromend
 char *
 Perl_instr(const char *big, const char *little)
 {
-    I32 first;
 
     PERL_ARGS_ASSERT_INSTR;
 
+    /* libc prior to 4.6.27 did not work properly on a NULL 'little' */
     if (!little)
        return (char*)big;
-    first = *little++;
-    if (!first)
-       return (char*)big;
-    while (*big) {
-       const char *s, *x;
-       if (*big++ != first)
-           continue;
-       for (x=big,s=little; *s; /**/ ) {
-           if (!*x)
-               return NULL;
-           if (*s != *x)
-               break;
-           else {
-               s++;
-               x++;
-           }
-       }
-       if (!*s)
-           return (char*)(big-1);
-    }
-    return NULL;
+    return strstr((char*)big, (char*)little);
 }
 
 /* same as instr but allow embedded nulls.  The end pointers point to 1 beyond