Change PL_screamnext to store absolute positions.
authorNicholas Clark <nick@ccl4.org>
Mon, 27 Jun 2011 15:14:39 +0000 (17:14 +0200)
committerNicholas Clark <nick@ccl4.org>
Fri, 1 Jul 2011 12:05:40 +0000 (14:05 +0200)
PL_screamnext gives the position of the next occurrence of the current octet.
Previously it stored this as an offset from the current position, with -pos
stored for "no more", so that the calculated new offset would be zero,
allowing a zero/non-zero loop exit test in Perl_screaminstr().

Now it stores absolute position, with -1 for "no more". Also codify -1 as the
"not present" value for PL_screamfirst, instead of any negative value.

pp.c
regexec.c
util.c

diff --git a/pp.c b/pp.c
index c72ce28..61e9dc1 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -762,9 +762,9 @@ PP(pp_study)
     while (--pos >= 0) {
        register const I32 ch = s[pos];
        if (sfirst[ch] >= 0)
-           snext[pos] = sfirst[ch] - pos;
+           snext[pos] = sfirst[ch];
        else
-           snext[pos] = -pos;
+           snext[pos] = -1;
        sfirst[ch] = pos;
     }
 
index 6ae2770..00fc712 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -696,7 +696,7 @@ Perl_re_intuit_start(pTHX_ REGEXP * const rx, SV *sv, char *strpos,
        I32 p = -1;                     /* Internal iterator of scream. */
        I32 * const pp = data ? data->scream_pos : &p;
 
-       if (PL_screamfirst[BmRARE(check)] >= 0
+       if (PL_screamfirst[BmRARE(check)] != -1
            || ( BmRARE(check) == '\n'
                 && (BmPREVIOUS(check) == SvCUR(check) - 1)
                 && SvTAIL(check) ))
diff --git a/util.c b/util.c
index 093b70e..9185e08 100644 (file)
--- a/util.c
+++ b/util.c
@@ -867,9 +867,9 @@ Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift
     assert(SvTYPE(littlestr) == SVt_PVMG);
     assert(SvVALID(littlestr));
 
-    if (*old_posp == -1
-       ? (pos = PL_screamfirst[BmRARE(littlestr)]) < 0
-       : (((pos = *old_posp), pos += PL_screamnext[pos]) == 0)) {
+    pos = *old_posp == -1
+       ? PL_screamfirst[BmRARE(littlestr)] : PL_screamnext[*old_posp];
+    if (pos == -1) {
       cant_find:
        if ( BmRARE(littlestr) == '\n'
             && BmPREVIOUS(littlestr) == SvCUR(littlestr) - 1) {
@@ -901,27 +901,29 @@ Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift
        return NULL;
     }
     while (pos < previous + start_shift) {
-       if (!(pos += PL_screamnext[pos]))
+       pos = PL_screamnext[pos];
+       if (pos == -1)
            goto cant_find;
     }
     big -= previous;
     do {
        register const unsigned char *s, *x;
        if (pos >= stop_pos) break;
-       if (big[pos] != first)
-           continue;
-       for (x=big+pos+1,s=little; s < littleend; /**/ ) {
-           if (*s++ != *x++) {
-               s--;
-               break;
+       if (big[pos] == first) {
+           for (x=big+pos+1,s=little; s < littleend; /**/ ) {
+               if (*s++ != *x++) {
+                   s--;
+                   break;
+               }
+           }
+           if (s == littleend) {
+               *old_posp = pos;
+               if (!last) return (char *)(big+pos);
+               found = 1;
            }
        }
-       if (s == littleend) {
-           *old_posp = pos;
-           if (!last) return (char *)(big+pos);
-           found = 1;
-       }
-    } while ( pos += PL_screamnext[pos] );
+       pos = PL_screamnext[pos];
+    } while (pos != -1);
     if (last && found)
        return (char *)(big+(*old_posp));
   check_tail: