This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Gut screaminstr
authorFather Chrysostomos <sprout@cpan.org>
Thu, 24 May 2012 21:00:56 +0000 (14:00 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 30 May 2012 06:55:22 +0000 (23:55 -0700)
How did this ever end up in the API?

Anyway, this commit guts it by removing its guts and replacing it with
a panic message.  This function would fail assertions if passed an
unstudied scalar, so it should never be called any more.  But XS mod-
ules that still do if (SvSCREAM(sv)) screaminstr(...) should still be
able to compile.

util.c

diff --git a/util.c b/util.c
index 37f23bf..7a8f3bb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -838,174 +838,21 @@ Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *lit
     }
 }
 
-/* start_shift, end_shift are positive quantities which give offsets
-   of ends of some substring of bigstr.
-   If "last" we want the last occurrence.
-   old_posp is the way of communication between consequent calls if
-   the next call needs to find the .
-   The initial *old_posp should be -1.
-
-   Note that we take into account SvTAIL, so one can get extra
-   optimizations if _ALL flag is set.
- */
-
-/* If SvTAIL is actually due to \Z or \z, this gives false positives
-   if PL_multiline.  In fact if !PL_multiline the authoritative answer
-   is not supported yet. */
-
 char *
 Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift, I32 *old_posp, I32 last)
 {
     dVAR;
-    register const unsigned char *big;
-    U32 pos = 0; /* hush a gcc warning */
-    register I32 previous;
-    register I32 first;
-    register const unsigned char *little;
-    register I32 stop_pos;
-    register const unsigned char *littleend;
-    bool found = FALSE;
-    const MAGIC * mg;
-    const void *screamnext_raw = NULL; /* hush a gcc warning */
-    bool cant_find = FALSE; /* hush a gcc warning */
-
     PERL_ARGS_ASSERT_SCREAMINSTR;
-
-    assert(SvMAGICAL(bigstr));
-    mg = mg_find(bigstr, PERL_MAGIC_study);
-    assert(mg);
-    assert(SvTYPE(littlestr) == SVt_PVMG);
-    assert(SvVALID(littlestr));
-
-    if (mg->mg_private == 1) {
-       const U8 *const screamfirst = (U8 *)mg->mg_ptr;
-       const U8 *const screamnext = screamfirst + 256;
-
-       screamnext_raw = (const void *)screamnext;
-
-       pos = *old_posp == -1
-           ? screamfirst[BmRARE(littlestr)] : screamnext[*old_posp];
-       cant_find = pos == (U8)~0;
-    } else if (mg->mg_private == 2) {
-       const U16 *const screamfirst = (U16 *)mg->mg_ptr;
-       const U16 *const screamnext = screamfirst + 256;
-
-       screamnext_raw = (const void *)screamnext;
-
-       pos = *old_posp == -1
-           ? screamfirst[BmRARE(littlestr)] : screamnext[*old_posp];
-       cant_find = pos == (U16)~0;
-    } else if (mg->mg_private == 4) {
-       const U32 *const screamfirst = (U32 *)mg->mg_ptr;
-       const U32 *const screamnext = screamfirst + 256;
-
-       screamnext_raw = (const void *)screamnext;
-
-       pos = *old_posp == -1
-           ? screamfirst[BmRARE(littlestr)] : screamnext[*old_posp];
-       cant_find = pos == (U32)~0;
-    } else
-       Perl_croak(aTHX_ "panic: unknown study size %u", mg->mg_private);
-
-    if (cant_find) {
-      cant_find:
-       if ( BmRARE(littlestr) == '\n'
-            && BmPREVIOUS(littlestr) == SvCUR(littlestr) - 1) {
-           little = (const unsigned char *)(SvPVX_const(littlestr));
-           littleend = little + SvCUR(littlestr);
-           first = *little++;
-           goto check_tail;
-       }
-       return NULL;
-    }
-
-    little = (const unsigned char *)(SvPVX_const(littlestr));
-    littleend = little + SvCUR(littlestr);
-    first = *little++;
-    /* The value of pos we can start at: */
-    previous = BmPREVIOUS(littlestr);
-    big = (const unsigned char *)(SvPVX_const(bigstr));
-    /* The value of pos we can stop at: */
-    stop_pos = SvCUR(bigstr) - end_shift - (SvCUR(littlestr) - 1 - previous);
-    if (previous + start_shift > stop_pos) {
-/*
-  stop_pos does not include SvTAIL in the count, so this check is incorrect
-  (I think) - see [ID 20010618.006] and t/op/study.t. HVDS 2001/06/19
-*/
-#if 0
-       if (previous + start_shift == stop_pos + 1) /* A fake '\n'? */
-           goto check_tail;
-#endif
-       return NULL;
-    }
-    if (mg->mg_private == 1) {
-       const U8 *const screamnext = (const U8 *const) screamnext_raw;
-       while ((I32)pos < previous + start_shift) {
-           pos = screamnext[pos];
-           if (pos == (U8)~0)
-               goto cant_find;
-       }
-    } else if (mg->mg_private == 2) {
-       const U16 *const screamnext = (const U16 *const) screamnext_raw;
-       while ((I32)pos < previous + start_shift) {
-           pos = screamnext[pos];
-           if (pos == (U16)~0)
-               goto cant_find;
-       }
-    } else if (mg->mg_private == 4) {
-       const U32 *const screamnext = (const U32 *const) screamnext_raw;
-       while ((I32)pos < previous + start_shift) {
-           pos = screamnext[pos];
-           if (pos == (U32)~0)
-               goto cant_find;
-       }
-    }
-    big -= previous;
-    while (1) {
-       if ((I32)pos >= stop_pos) break;
-       if (big[pos] == first) {
-           const unsigned char *s = little;
-           const unsigned char *x = big + pos + 1;
-           while (s < littleend) {
-               if (*s != *x++)
-                   break;
-               ++s;
-           }
-           if (s == littleend) {
-               *old_posp = (I32)pos;
-               if (!last) return (char *)(big+pos);
-               found = TRUE;
-           }
-       }
-       if (mg->mg_private == 1) {
-           pos = ((const U8 *const)screamnext_raw)[pos];
-           if (pos == (U8)~0)
-               break;
-       } else if (mg->mg_private == 2) {
-           pos = ((const U16 *const)screamnext_raw)[pos];
-           if (pos == (U16)~0)
-               break;
-       } else if (mg->mg_private == 4) {
-           pos = ((const U32 *const)screamnext_raw)[pos];
-           if (pos == (U32)~0)
-               break;
-       }
-    };
-    if (last && found)
-       return (char *)(big+(*old_posp));
-  check_tail:
-    if (!SvTAIL(littlestr) || (end_shift > 0))
-       return NULL;
-    /* Ignore the trailing "\n".  This code is not microoptimized */
-    big = (const unsigned char *)(SvPVX_const(bigstr) + SvCUR(bigstr));
-    stop_pos = littleend - little;     /* Actual littlestr len */
-    if (stop_pos == 0)
-       return (char*)big;
-    big -= stop_pos;
-    if (*big == first
-       && ((stop_pos == 1) ||
-           memEQ((char *)(big + 1), (char *)little, stop_pos - 1)))
-       return (char*)big;
+    PERL_UNUSED_ARG(bigstr);
+    PERL_UNUSED_ARG(littlestr);
+    PERL_UNUSED_ARG(start_shift);
+    PERL_UNUSED_ARG(end_shift);
+    PERL_UNUSED_ARG(old_posp);
+    PERL_UNUSED_ARG(last);
+
+    /* This function must only ever be called on a scalar with study magic,
+       but those do not happen any more. */
+    Perl_croak(aTHX_ "panic: screaminstr");
     return NULL;
 }