? I32_MAX : data->pos_min + data->pos_delta;
}
sv_catpvn(data->last_found, STRING(scan), STR_LEN(scan));
+ if (UTF)
+ SvUTF8_on(data->last_found);
data->last_end = data->pos_min + l;
data->pos_min += l; /* As in the first entry. */
data->flags &= ~SF_BEFORE_EOL;
&& SvCUR(data.longest_fixed) == SvCUR(data.longest_float))
goto remove_float; /* As in (a)+. */
- r->float_substr = data.longest_float;
+ if (SvUTF8(data.longest_float)) {
+ r->float_utf8 = data.longest_float;
+ r->float_substr = Nullsv;
+ } else {
+ r->float_substr = data.longest_float;
+ r->float_utf8 = Nullsv;
+ }
r->float_min_offset = data.offset_float_min;
r->float_max_offset = data.offset_float_max;
t = (data.flags & SF_FL_BEFORE_EOL /* Can't have SEOL and MULTI */
&& (!(data.flags & SF_FL_BEFORE_MEOL)
|| (RExC_flags16 & PMf_MULTILINE)));
- fbm_compile(r->float_substr, t ? FBMcf_TAIL : 0);
+ fbm_compile(data.longest_float, t ? FBMcf_TAIL : 0);
}
else {
remove_float:
- r->float_substr = Nullsv;
+ r->float_substr = r->float_utf8 = Nullsv;
SvREFCNT_dec(data.longest_float);
longest_float_length = 0;
}
|| (RExC_flags16 & PMf_MULTILINE)))) {
int t;
- r->anchored_substr = data.longest_fixed;
+ if (SvUTF8(data.longest_fixed)) {
+ r->anchored_utf8 = data.longest_fixed;
+ r->anchored_substr = Nullsv;
+ } else {
+ r->anchored_substr = data.longest_fixed;
+ r->anchored_utf8 = Nullsv;
+ }
r->anchored_offset = data.offset_fixed;
t = (data.flags & SF_FIX_BEFORE_EOL /* Can't have SEOL and MULTI */
&& (!(data.flags & SF_FIX_BEFORE_MEOL)
|| (RExC_flags16 & PMf_MULTILINE)));
- fbm_compile(r->anchored_substr, t ? FBMcf_TAIL : 0);
+ fbm_compile(data.longest_fixed, t ? FBMcf_TAIL : 0);
}
else {
- r->anchored_substr = Nullsv;
+ r->anchored_substr = r->anchored_utf8 = Nullsv;
SvREFCNT_dec(data.longest_fixed);
longest_fixed_length = 0;
}
if (r->regstclass
&& (OP(r->regstclass) == REG_ANY || OP(r->regstclass) == SANY))
r->regstclass = NULL;
- if ((!r->anchored_substr || r->anchored_offset) && stclass_flag
+ if ((!(r->anchored_substr || r->anchored_utf8) || r->anchored_offset)
+ && stclass_flag
&& !(data.start_class->flags & ANYOF_EOS)
&& !cl_is_anything(data.start_class)) {
I32 n = add_data(pRExC_state, 1, "f");
/* A temporary algorithm prefers floated substr to fixed one to dig more info. */
if (longest_fixed_length > longest_float_length) {
r->check_substr = r->anchored_substr;
+ r->check_utf8 = r->anchored_utf8;
r->check_offset_min = r->check_offset_max = r->anchored_offset;
if (r->reganch & ROPT_ANCH_SINGLE)
r->reganch |= ROPT_NOSCAN;
}
else {
r->check_substr = r->float_substr;
+ r->check_utf8 = r->float_utf8;
r->check_offset_min = data.offset_float_min;
r->check_offset_max = data.offset_float_max;
}
/* XXXX Currently intuiting is not compatible with ANCH_GPOS.
This should be changed ASAP! */
- if (r->check_substr && !(r->reganch & ROPT_ANCH_GPOS)) {
+ if ((r->check_substr || r->check_utf8) && !(r->reganch & ROPT_ANCH_GPOS)) {
r->reganch |= RE_USE_INTUIT;
- if (SvTAIL(r->check_substr))
+ if (SvTAIL(r->check_substr ? r->check_substr : r->check_utf8))
r->reganch |= RE_INTUIT_TAIL;
}
}
data.start_class = &ch_class;
data.last_closep = &last_close;
minlen = study_chunk(pRExC_state, &scan, &fake, scan + RExC_size, &data, SCF_DO_STCLASS_AND|SCF_WHILEM_VISITED_POS);
- r->check_substr = r->anchored_substr = r->float_substr = Nullsv;
+ r->check_substr = r->check_utf8 = r->anchored_substr = r->anchored_utf8
+ = r->float_substr = r->float_utf8 = Nullsv;
if (!(data.start_class->flags & ANYOF_EOS)
&& !cl_is_anything(data.start_class)) {
I32 n = add_data(pRExC_state, 1, "f");
PL_colors[1],
SvTAIL(r->anchored_substr) ? "$" : "",
(IV)r->anchored_offset);
+ else if (r->anchored_utf8)
+ PerlIO_printf(Perl_debug_log,
+ "anchored utf8 `%s%.*s%s'%s at %"IVdf" ",
+ PL_colors[0],
+ (int)(SvCUR(r->anchored_utf8) - (SvTAIL(r->anchored_utf8)!=0)),
+ SvPVX(r->anchored_utf8),
+ PL_colors[1],
+ SvTAIL(r->anchored_utf8) ? "$" : "",
+ (IV)r->anchored_offset);
if (r->float_substr)
PerlIO_printf(Perl_debug_log,
"floating `%s%.*s%s'%s at %"IVdf"..%"UVuf" ",
PL_colors[1],
SvTAIL(r->float_substr) ? "$" : "",
(IV)r->float_min_offset, (UV)r->float_max_offset);
- if (r->check_substr)
+ else if (r->float_utf8)
+ PerlIO_printf(Perl_debug_log,
+ "floating utf8 `%s%.*s%s'%s at %"IVdf"..%"UVuf" ",
+ PL_colors[0],
+ (int)(SvCUR(r->float_utf8) - (SvTAIL(r->float_utf8)!=0)),
+ SvPVX(r->float_utf8),
+ PL_colors[1],
+ SvTAIL(r->float_utf8) ? "$" : "",
+ (IV)r->float_min_offset, (UV)r->float_max_offset);
+ if (r->check_substr || r->check_utf8)
PerlIO_printf(Perl_debug_log,
r->check_substr == r->float_substr
+ && r->check_utf8 == r->float_utf8
? "(checking floating" : "(checking anchored");
if (r->reganch & ROPT_NOSCAN)
PerlIO_printf(Perl_debug_log, " noscan");
if (r->reganch & ROPT_CHECK_ALL)
PerlIO_printf(Perl_debug_log, " isall");
- if (r->check_substr)
+ if (r->check_substr || r->check_utf8)
PerlIO_printf(Perl_debug_log, ") ");
if (r->regstclass) {
{ /* Assume that RE_INTUIT is set */
DEBUG_r(
{ STRLEN n_a;
- char *s = SvPV(prog->check_substr,n_a);
+ char *s = SvPV(prog->check_substr
+ ? prog->check_substr : prog->check_utf8, n_a);
if (!PL_colorset) reginitcolors();
PerlIO_printf(Perl_debug_log,
- "%sUsing REx substr:%s `%s%.60s%s%s'\n",
- PL_colors[4],PL_colors[5],PL_colors[0],
+ "%sUsing REx %ssubstr:%s `%s%.60s%s%s'\n",
+ PL_colors[4],
+ prog->check_substr ? "" : "utf8 ",
+ PL_colors[5],PL_colors[0],
s,
PL_colors[1],
(strlen(s) > 60 ? "..." : ""));
} );
- return prog->check_substr;
+ return prog->check_substr ? prog->check_substr : prog->check_utf8;
}
void
if (r->substrs) {
if (r->anchored_substr)
SvREFCNT_dec(r->anchored_substr);
+ if (r->anchored_utf8)
+ SvREFCNT_dec(r->anchored_utf8);
if (r->float_substr)
SvREFCNT_dec(r->float_substr);
+ if (r->float_utf8)
+ SvREFCNT_dec(r->float_utf8);
Safefree(r->substrs);
}
if (r->data) {
* Forwards.
*/
-#define CHR_SVLEN(sv) (UTF ? sv_len_utf8(sv) : SvCUR(sv))
+#define CHR_SVLEN(sv) (do_utf8 ? sv_len_utf8(sv) : SvCUR(sv))
#define CHR_DIST(a,b) (PL_reg_match_utf8 ? utf8_distance(a,b) : a - b)
#define reghop_c(pos,off) ((char*)reghop((U8*)pos, off))
register SV *check;
char *strbeg;
char *t;
+ int do_utf8 = sv ? SvUTF8(sv) : 0; /* if no sv we have to assume bytes */
I32 ml_anch;
register char *other_last = Nullch; /* other substr checked before this */
char *check_at = Nullch; /* check substr found at this pos */
}
strbeg = (sv && SvPOK(sv)) ? strend - SvCUR(sv) : strpos;
PL_regeol = strend;
- check = prog->check_substr;
+ if (do_utf8) {
+ if (!prog->check_utf8 && prog->check_substr)
+ to_utf8_substr(prog);
+ check = prog->check_utf8;
+ } else {
+ if (!prog->check_substr && prog->check_utf8)
+ to_byte_substr(prog);
+ check = prog->check_substr;
+ }
+ if (check == &PL_sv_undef) {
+ DEBUG_r(PerlIO_printf(Perl_debug_log,
+ "Non-utf string cannot match utf check string\n"));
+ goto fail;
+ }
if (prog->reganch & ROPT_ANCH) { /* Match at beg-of-str or after \n */
ml_anch = !( (prog->reganch & ROPT_ANCH_SINGLE)
|| ( (prog->reganch & ROPT_ANCH_BOL)
DEBUG_r(PerlIO_printf(Perl_debug_log, "%s %s substr `%s%.*s%s'%s%s",
(s ? "Found" : "Did not find"),
- ((check == prog->anchored_substr) ? "anchored" : "floating"),
+ (check == (do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) ? "anchored" : "floating"),
PL_colors[0],
(int)(SvCUR(check) - (SvTAIL(check)!=0)),
SvPVX(check),
Probably it is right to do no SCREAM here...
*/
- if (prog->float_substr && prog->anchored_substr) {
+ if (do_utf8 ? (prog->float_utf8 && prog->anchored_utf8) : (prog->float_substr && prog->anchored_substr)) {
/* Take into account the "other" substring. */
/* XXXX May be hopelessly wrong for UTF... */
if (!other_last)
other_last = strpos;
- if (check == prog->float_substr) {
+ if (check == (do_utf8 ? prog->float_utf8 : prog->float_substr)) {
do_other_anchored:
{
char *last = HOP3c(s, -start_shift, strbeg), *last1, *last2;
char *s1 = s;
+ SV* must;
t = s - prog->check_offset_max;
if (s - strpos > prog->check_offset_max /* signed-corrected t > strpos */
last1 = last;
/* XXXX It is not documented what units *_offsets are in. Assume bytes. */
/* On end-of-str: see comment below. */
- s = fbm_instr((unsigned char*)t,
- HOP3(HOP3(last1, prog->anchored_offset, strend)
- + SvCUR(prog->anchored_substr),
- -(SvTAIL(prog->anchored_substr)!=0), strbeg),
- prog->anchored_substr,
- PL_multiline ? FBMrf_MULTILINE : 0);
+ must = do_utf8 ? prog->anchored_utf8 : prog->anchored_substr;
+ if (must == &PL_sv_undef) {
+ s = (char*)NULL;
+ DEBUG_r(must = prog->anchored_utf8); /* for debug */
+ }
+ else
+ s = fbm_instr(
+ (unsigned char*)t,
+ HOP3(HOP3(last1, prog->anchored_offset, strend)
+ + SvCUR(must), -(SvTAIL(must)!=0), strbeg),
+ must,
+ PL_multiline ? FBMrf_MULTILINE : 0
+ );
DEBUG_r(PerlIO_printf(Perl_debug_log,
"%s anchored substr `%s%.*s%s'%s",
(s ? "Found" : "Contradicts"),
PL_colors[0],
- (int)(SvCUR(prog->anchored_substr)
- - (SvTAIL(prog->anchored_substr)!=0)),
- SvPVX(prog->anchored_substr),
- PL_colors[1], (SvTAIL(prog->anchored_substr) ? "$" : "")));
+ (int)(SvCUR(must)
+ - (SvTAIL(must)!=0)),
+ SvPVX(must),
+ PL_colors[1], (SvTAIL(must) ? "$" : "")));
if (!s) {
if (last1 >= last2) {
DEBUG_r(PerlIO_printf(Perl_debug_log,
}
}
else { /* Take into account the floating substring. */
- char *last, *last1;
- char *s1 = s;
-
- t = HOP3c(s, -start_shift, strbeg);
- last1 = last =
- HOP3c(strend, -prog->minlen + prog->float_min_offset, strbeg);
- if (CHR_DIST((U8*)last, (U8*)t) > prog->float_max_offset)
- last = HOP3c(t, prog->float_max_offset, strend);
- s = HOP3c(t, prog->float_min_offset, strend);
- if (s < other_last)
- s = other_last;
+ char *last, *last1;
+ char *s1 = s;
+ SV* must;
+
+ t = HOP3c(s, -start_shift, strbeg);
+ last1 = last =
+ HOP3c(strend, -prog->minlen + prog->float_min_offset, strbeg);
+ if (CHR_DIST((U8*)last, (U8*)t) > prog->float_max_offset)
+ last = HOP3c(t, prog->float_max_offset, strend);
+ s = HOP3c(t, prog->float_min_offset, strend);
+ if (s < other_last)
+ s = other_last;
/* XXXX It is not documented what units *_offsets are in. Assume bytes. */
- /* fbm_instr() takes into account exact value of end-of-str
- if the check is SvTAIL(ed). Since false positives are OK,
- and end-of-str is not later than strend we are OK. */
+ must = do_utf8 ? prog->float_utf8 : prog->float_substr;
+ /* fbm_instr() takes into account exact value of end-of-str
+ if the check is SvTAIL(ed). Since false positives are OK,
+ and end-of-str is not later than strend we are OK. */
+ if (must == &PL_sv_undef) {
+ s = (char*)NULL;
+ DEBUG_r(must = prog->float_utf8); /* for debug message */
+ }
+ else
s = fbm_instr((unsigned char*)s,
- (unsigned char*)last + SvCUR(prog->float_substr)
- - (SvTAIL(prog->float_substr)!=0),
- prog->float_substr, PL_multiline ? FBMrf_MULTILINE : 0);
- DEBUG_r(PerlIO_printf(Perl_debug_log, "%s floating substr `%s%.*s%s'%s",
- (s ? "Found" : "Contradicts"),
- PL_colors[0],
- (int)(SvCUR(prog->float_substr)
- - (SvTAIL(prog->float_substr)!=0)),
- SvPVX(prog->float_substr),
- PL_colors[1], (SvTAIL(prog->float_substr) ? "$" : "")));
- if (!s) {
- if (last1 == last) {
- DEBUG_r(PerlIO_printf(Perl_debug_log,
- ", giving up...\n"));
- goto fail_finish;
- }
+ (unsigned char*)last + SvCUR(must)
+ - (SvTAIL(must)!=0),
+ must, PL_multiline ? FBMrf_MULTILINE : 0);
+ DEBUG_r(PerlIO_printf(Perl_debug_log, "%s floating substr `%s%.*s%s'%s",
+ (s ? "Found" : "Contradicts"),
+ PL_colors[0],
+ (int)(SvCUR(must) - (SvTAIL(must)!=0)),
+ SvPVX(must),
+ PL_colors[1], (SvTAIL(must) ? "$" : "")));
+ if (!s) {
+ if (last1 == last) {
DEBUG_r(PerlIO_printf(Perl_debug_log,
- ", trying anchored starting at offset %ld...\n",
- (long)(s1 + 1 - i_strpos)));
- other_last = last;
- s = HOP3c(t, 1, strend);
- goto restart;
- }
- else {
- DEBUG_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
- (long)(s - i_strpos)));
- other_last = s; /* Fix this later. --Hugo */
- s = s1;
- if (t == strpos)
- goto try_at_start;
- goto try_at_offset;
+ ", giving up...\n"));
+ goto fail_finish;
}
+ DEBUG_r(PerlIO_printf(Perl_debug_log,
+ ", trying anchored starting at offset %ld...\n",
+ (long)(s1 + 1 - i_strpos)));
+ other_last = last;
+ s = HOP3c(t, 1, strend);
+ goto restart;
+ }
+ else {
+ DEBUG_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
+ (long)(s - i_strpos)));
+ other_last = s; /* Fix this later. --Hugo */
+ s = s1;
+ if (t == strpos)
+ goto try_at_start;
+ goto try_at_offset;
+ }
}
}
while (t < strend - prog->minlen) {
if (*t == '\n') {
if (t < check_at - prog->check_offset_min) {
- if (prog->anchored_substr) {
+ if (do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) {
/* Since we moved from the found position,
we definitely contradict the found anchored
substr. Due to the above check we do not
}
s = t;
set_useful:
- ++BmUSEFUL(prog->check_substr); /* hooray/5 */
+ ++BmUSEFUL(do_utf8 ? prog->check_utf8 : prog->check_substr); /* hooray/5 */
}
else {
/* The found string does not prohibit matching at strpos,
);
success_at_start:
if (!(prog->reganch & ROPT_NAUGHTY) /* XXXX If strpos moved? */
- && prog->check_substr /* Could be deleted already */
- && --BmUSEFUL(prog->check_substr) < 0
- && prog->check_substr == prog->float_substr)
+ && (do_utf8 ? (
+ prog->check_utf8 /* Could be deleted already */
+ && --BmUSEFUL(prog->check_utf8) < 0
+ && (prog->check_utf8 == prog->float_utf8)
+ ) : (
+ prog->check_substr /* Could be deleted already */
+ && --BmUSEFUL(prog->check_substr) < 0
+ && (prog->check_substr == prog->float_substr)
+ )))
{
/* If flags & SOMETHING - do not do it many times on the same match */
DEBUG_r(PerlIO_printf(Perl_debug_log, "... Disabling check substring...\n"));
- SvREFCNT_dec(prog->check_substr);
- prog->check_substr = Nullsv; /* disable */
- prog->float_substr = Nullsv; /* clear */
+ SvREFCNT_dec(do_utf8 ? prog->check_utf8 : prog->check_substr);
+ if (do_utf8 ? prog->check_substr : prog->check_utf8)
+ SvREFCNT_dec(do_utf8 ? prog->check_substr : prog->check_utf8);
+ prog->check_substr = prog->check_utf8 = Nullsv; /* disable */
+ prog->float_substr = prog->float_utf8 = Nullsv; /* clear */
check = Nullsv; /* abort */
s = strpos;
/* XXXX This is a remnant of the old implementation. It
int cl_l = (PL_regkind[(U8)OP(prog->regstclass)] == EXACT
? CHR_DIST(str+STR_LEN(prog->regstclass), str)
: 1);
- char *endpos = (prog->anchored_substr || ml_anch)
+ char *endpos = (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
? HOP3c(s, (prog->minlen ? cl_l : 0), strend)
- : (prog->float_substr
+ : (prog->float_substr || prog->float_utf8
? HOP3c(HOP3c(check_at, -start_shift, strbeg),
cl_l, strend)
: strend);
if ((prog->reganch & ROPT_ANCH) && !ml_anch)
goto fail;
/* Contradict one of substrings */
- if (prog->anchored_substr) {
- if (prog->anchored_substr == check) {
+ if (prog->anchored_substr || prog->anchored_utf8) {
+ if ((do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) == check) {
DEBUG_r( what = "anchored" );
hop_and_restart:
s = HOP3c(t, 1, strend);
PL_colors[0],PL_colors[1], (long)(t - i_strpos)) );
goto try_at_offset;
}
- if (!prog->float_substr) /* Could have been deleted */
+ if (!(do_utf8 ? prog->float_utf8 : prog->float_substr)) /* Could have been deleted */
goto fail;
/* Check is floating subtring. */
retry_floating_check:
return s;
fail_finish: /* Substring not found */
- if (prog->check_substr) /* could be removed already */
- BmUSEFUL(prog->check_substr) += 5; /* hooray */
+ if (prog->check_substr || prog->check_utf8) /* could be removed already */
+ BmUSEFUL(do_utf8 ? prog->check_utf8 : prog->check_substr) += 5; /* hooray */
fail:
DEBUG_r(PerlIO_printf(Perl_debug_log, "%sMatch rejected by optimizer%s\n",
PL_colors[4],PL_colors[5]));
PL_reg_ganch = strbeg;
}
- if (do_utf8 == (UTF!=0) &&
- !(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
+ if (!(flags & REXEC_CHECKED) && (prog->check_substr != Nullsv || prog->check_utf8 != Nullsv)) {
re_scream_pos_data d;
d.scream_olds = &scream_olds;
dontbother = minlen - 1;
end = HOP3c(strend, -dontbother, strbeg) - 1;
/* for multiline we only have to try after newlines */
- if (prog->check_substr) {
+ if (prog->check_substr || prog->check_utf8) {
if (s == startpos)
goto after_try;
while (1) {
}
/* Messy cases: unanchored match. */
- if (prog->anchored_substr && prog->reganch & ROPT_SKIP) {
+ if ((prog->anchored_substr || prog->anchored_utf8) && prog->reganch & ROPT_SKIP) {
/* we have /x+whatever/ */
/* it must be a one character string (XXXX Except UTF?) */
- char ch = SvPVX(prog->anchored_substr)[0];
+ char ch;
#ifdef DEBUGGING
int did_match = 0;
#endif
+ if (!(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr))
+ do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
+ ch = SvPVX(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr)[0];
if (do_utf8) {
while (s < strend) {
);
}
/*SUPPRESS 560*/
- else if (do_utf8 == (UTF!=0) &&
- (prog->anchored_substr != Nullsv
- || (prog->float_substr != Nullsv
- && prog->float_max_offset < strend - s))) {
- SV *must = prog->anchored_substr
- ? prog->anchored_substr : prog->float_substr;
- I32 back_max =
- prog->anchored_substr ? prog->anchored_offset : prog->float_max_offset;
- I32 back_min =
- prog->anchored_substr ? prog->anchored_offset : prog->float_min_offset;
- char *last = HOP3c(strend, /* Cannot start after this */
- -(I32)(CHR_SVLEN(must)
- - (SvTAIL(must) != 0) + back_min), strbeg);
+ else if (prog->anchored_substr != Nullsv
+ || prog->anchored_utf8 != Nullsv
+ || ((prog->float_substr != Nullsv || prog->float_utf8 != Nullsv)
+ && prog->float_max_offset < strend - s)) {
+ SV *must;
+ I32 back_max;
+ I32 back_min;
+ char *last;
char *last1; /* Last position checked before */
#ifdef DEBUGGING
int did_match = 0;
#endif
+ if (prog->anchored_substr || prog->anchored_utf8) {
+ if (!(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr))
+ do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
+ must = do_utf8 ? prog->anchored_utf8 : prog->anchored_substr;
+ back_max = back_min = prog->anchored_offset;
+ } else {
+ if (!(do_utf8 ? prog->float_utf8 : prog->float_substr))
+ do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
+ must = do_utf8 ? prog->float_utf8 : prog->float_substr;
+ back_max = prog->float_max_offset;
+ back_min = prog->float_min_offset;
+ }
+ if (must == &PL_sv_undef)
+ /* could not downgrade utf8 check substring, so must fail */
+ goto phooey;
+
+ last = HOP3c(strend, /* Cannot start after this */
+ -(I32)(CHR_SVLEN(must)
+ - (SvTAIL(must) != 0) + back_min), strbeg);
if (s > PL_bostr)
last1 = HOPc(s, -1);
DEBUG_r(if (!did_match)
PerlIO_printf(Perl_debug_log,
"Did not find %s substr `%s%.*s%s'%s...\n",
- ((must == prog->anchored_substr)
+ ((must == prog->anchored_substr || must == prog->anchored_utf8)
? "anchored" : "floating"),
PL_colors[0],
(int)(SvCUR(must) - (SvTAIL(must)!=0)),
}
else {
dontbother = 0;
- if (prog->float_substr != Nullsv) { /* Trim the end. */
+ if (prog->float_substr != Nullsv || prog->float_utf8 != Nullsv) {
+ /* Trim the end. */
char *last;
+ SV* float_real;
+
+ if (!(do_utf8 ? prog->float_utf8 : prog->float_substr))
+ do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
+ float_real = do_utf8 ? prog->float_utf8 : prog->float_substr;
if (flags & REXEC_SCREAM) {
- last = screaminstr(sv, prog->float_substr, s - strbeg,
+ last = screaminstr(sv, float_real, s - strbeg,
end_shift, &scream_pos, 1); /* last one */
if (!last)
last = scream_olds; /* Only one occurrence. */
}
else {
STRLEN len;
- char *little = SvPV(prog->float_substr, len);
+ char *little = SvPV(float_real, len);
- if (SvTAIL(prog->float_substr)) {
+ if (SvTAIL(float_real)) {
if (memEQ(strend - len + 1, little, len - 1))
last = strend - len + 1;
else if (!PL_multiline)
PL_curpm = PL_reg_oldcurpm;
}
}
+
+STATIC void
+S_to_utf8_substr(pTHX_ register regexp *prog)
+{
+ SV* sv;
+ if (prog->float_substr && !prog->float_utf8) {
+ prog->float_utf8 = sv = NEWSV(117, 0);
+ SvSetMagicSV(sv, prog->float_substr);
+ sv_utf8_upgrade(sv);
+ if (SvTAIL(prog->float_substr))
+ SvTAIL_on(sv);
+ if (prog->float_substr == prog->check_substr)
+ prog->check_utf8 = sv;
+ }
+ if (prog->anchored_substr && !prog->anchored_utf8) {
+ prog->anchored_utf8 = sv = NEWSV(118, 0);
+ SvSetMagicSV(sv, prog->anchored_substr);
+ sv_utf8_upgrade(sv);
+ if (SvTAIL(prog->anchored_substr))
+ SvTAIL_on(sv);
+ if (prog->anchored_substr == prog->check_substr)
+ prog->check_utf8 = sv;
+ }
+}
+
+STATIC void
+S_to_byte_substr(pTHX_ register regexp *prog)
+{
+ SV* sv;
+ if (prog->float_utf8 && !prog->float_substr) {
+ prog->float_substr = sv = NEWSV(117, 0);
+ SvSetMagicSV(sv, prog->float_utf8);
+ if (sv_utf8_downgrade(sv, TRUE)) {
+ if (SvTAIL(prog->float_utf8))
+ SvTAIL_on(sv);
+ } else {
+ SvREFCNT_dec(sv);
+ prog->float_substr = sv = &PL_sv_undef;
+ }
+ if (prog->float_utf8 == prog->check_utf8)
+ prog->check_substr = sv;
+ }
+ if (prog->anchored_utf8 && !prog->anchored_substr) {
+ prog->anchored_substr = sv = NEWSV(118, 0);
+ SvSetMagicSV(sv, prog->anchored_utf8);
+ if (sv_utf8_downgrade(sv, TRUE)) {
+ if (SvTAIL(prog->anchored_utf8))
+ SvTAIL_on(sv);
+ } else {
+ SvREFCNT_dec(sv);
+ prog->anchored_substr = sv = &PL_sv_undef;
+ }
+ if (prog->anchored_utf8 == prog->check_utf8)
+ prog->check_substr = sv;
+ }
+}