summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2011-06-27 17:14:39 +0200
committerNicholas Clark <nick@ccl4.org>2011-07-01 14:05:40 +0200
commit56e9eeb1a239fc995bf33475e31f8379bd01cbad (patch)
tree6cbb3b168a951fe169e6873a5cf01b590ec7da69 /util.c
parent0177730e7e0c099d1250571eb39367a76e2d91eb (diff)
downloadperl-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.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/util.c b/util.c
index 093b70e62a..9185e08308 100644
--- 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: