diff options
author | Nicholas Clark <nick@ccl4.org> | 2011-06-27 17:14:39 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2011-07-01 14:05:40 +0200 |
commit | 56e9eeb1a239fc995bf33475e31f8379bd01cbad (patch) | |
tree | 6cbb3b168a951fe169e6873a5cf01b590ec7da69 /util.c | |
parent | 0177730e7e0c099d1250571eb39367a76e2d91eb (diff) | |
download | perl-56e9eeb1a239fc995bf33475e31f8379bd01cbad.tar.gz |
Change PL_screamnext to store absolute positions.
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.
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 34 |
1 files changed, 18 insertions, 16 deletions
@@ -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: |