case _CC_ENUM_BLANK: return is_HORIZWS_high(character);
case _CC_ENUM_XDIGIT: return is_XDIGIT_high(character);
case _CC_ENUM_VERTSPACE: return is_VERTWS_high(character);
- default: return 0; /* Things like CNTRL are always
- below 256 */
+ default: break;
}
- assert(0); /* NOTREACHED */
- return FALSE;
+ return FALSE; /* Things like CNTRL are always below 256 */
}
/*
goto fail;
}
+ RX_MATCH_UTF8_set(rx,utf8_target);
reginfo->is_utf8_target = cBOOL(utf8_target);
reginfo->info_aux = NULL;
reginfo->strbeg = strbeg;
* be too fiddly (e.g. REXEC_IGNOREPOS).
*/
if ( strpos != strbeg
- && (prog->intflags & (PREGf_ANCH_BOL|PREGf_ANCH_SBOL)))
+ && (prog->intflags & PREGf_ANCH_SBOL))
{
DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
" Not at start...\n"));
/* If the regex is absolutely anchored to either the start of the
- * string (BOL,SBOL) or to pos() (ANCH_GPOS), then
+ * string (SBOL) or to pos() (ANCH_GPOS), then
* check_offset_max represents an upper bound on the string where
* the substr could start. For the ANCH_GPOS case, we assume that
* the caller of intuit will have already set strpos to
}
RX_MATCH_TAINTED_off(rx);
+ RX_MATCH_UTF8_set(rx, utf8_target);
reginfo->prog = rx; /* Yes, sorry that this is confusing. */
reginfo->intuit = 0;
magic belonging to this SV.
Not newSVsv, either, as it does not COW.
*/
- assert(!IS_PADGV(sv));
reginfo->sv = newSV(0);
SvSetSV_nosteal(reginfo->sv, sv);
SAVEFREESV(reginfo->sv);
}
/* Simplest case: anchored match need be tried only once. */
- /* [unless only anchor is BOL and multiline is set] */
+ /* [unless only anchor is MBOL - implying multiline is set] */
if (prog->intflags & (PREGf_ANCH & ~PREGf_ANCH_GPOS)) {
if (s == startpos && regtry(reginfo, &s))
goto got_it;
}
DEBUG_EXECUTE_r({
SV * const prop = sv_newmortal();
- regprop(prog, prop, c, reginfo);
+ regprop(prog, prop, c, reginfo, NULL);
{
RE_PV_QUOTED_DECL(quoted,utf8_target,PERL_DEBUG_PAD_ZERO(1),
s,strend-s,60);
* and replaced it with this one. Yves */
DEBUG_EXECUTE_r(
PerlIO_printf(Perl_debug_log,
- "String does not contain required substring, cannot match.\n"
+ "%sString does not contain required substring, cannot match.%s\n",
+ PL_colors[4], PL_colors[5]
));
goto phooey;
}
if (RXp_PAREN_NAMES(prog))
(void)hv_iterinit(RXp_PAREN_NAMES(prog));
- RX_MATCH_UTF8_set(rx, utf8_target);
-
/* make sure $`, $&, $', and $digit will work later */
if ( !(flags & REXEC_NOT_FIRST) )
S_reg_set_capture_string(aTHX_ rx,
SV * const prop = sv_newmortal();
regnode *rnext=regnext(scan);
DUMP_EXEC_POS( locinput, scan, utf8_target );
- regprop(rex, prop, scan, reginfo);
+ regprop(rex, prop, scan, reginfo, NULL);
PerlIO_printf(Perl_debug_log,
"%3"IVdf":%*s%s(%"IVdf")\n",
assert(nextchr < 256 && (nextchr >= 0 || nextchr == NEXTCHR_EOS));
switch (state_num) {
- case BOL: /* /^../ */
- case SBOL: /* /^../s */
+ case SBOL: /* /^../ and /\A../ */
if (locinput == reginfo->strbeg)
break;
sayNO;
st->u.keeper.val = rex->offs[0].start;
rex->offs[0].start = locinput - reginfo->strbeg;
PUSH_STATE_GOTO(KEEPS_next, next, locinput);
- assert(0); /*NOTREACHED*/
+ /* NOTREACHED */
+ assert(0);
+
case KEEPS_next_fail:
/* rollback the start point change */
rex->offs[0].start = st->u.keeper.val;
sayNO_SILENT;
- assert(0); /*NOTREACHED*/
+ /* NOTREACHED */
+ assert(0);
case MEOL: /* /..$/m */
if (!NEXTCHR_IS_EOS && nextchr != '\n')
sayNO;
break;
- case EOL: /* /..$/ */
- /* FALLTHROUGH */
- case SEOL: /* /..$/s */
+ case SEOL: /* /..$/ */
if (!NEXTCHR_IS_EOS && nextchr != '\n')
sayNO;
if (reginfo->strend - locinput > 1)
REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
);
sayNO_SILENT;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
/* FALLTHROUGH */
case TRIE: /* (ab|cd) */
);
goto trie_first_try; /* jump into the fail handler */
}}
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case TRIE_next_fail: /* we failed - try next alternative */
{
if (ST.accepted > 1 || has_cutgroup) {
PUSH_STATE_GOTO(TRIE_next, scan, (char*)uc);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
/* only one choice left - just continue */
DEBUG_EXECUTE_r({
locinput = (char*)uc;
continue; /* execute rest of RE */
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
#undef ST
case TAIL: /* placeholder while compiling (A|B|C) */
break;
- case BACK: /* ??? doesn't appear to be used ??? */
- break;
-
#undef ST
#define ST st->u.eval
{
/* and then jump to the code we share with EVAL */
goto eval_recurse_doit;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case EVAL: /* /(?{A})B/ /(??{A})B/ and /(?(?{A})X|Y)B/ */
if (cur_eval && cur_eval->locinput==locinput) {
re_sv = rex->engine->op_comp(aTHX_ &ret, 1, NULL,
rex->engine, NULL, NULL,
/* copy /msix etc to inner pattern */
- scan->flags,
+ ARG2L(scan),
pm_flags);
if (!(SvFLAGS(ret)
cur_eval = st;
/* now continue from first node in postoned RE */
PUSH_YES_STATE_GOTO(EVAL_AB, startpoint, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
case EVAL_AB: /* cleanup after a successful (??{A})B */
}
}
goto fake_end;
- /*NOTREACHED*/
+ /* NOTREACHED */
case GROUPP: /* (?(1)) */
n = ARG(scan); /* which paren pair */
ST.lastloc = NULL; /* this will be updated by WHILEM */
PUSH_YES_STATE_GOTO(CURLYX_end, PREVOPER(next), locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
case CURLYX_end: /* just finished matching all of A*B */
cur_curlyx = ST.prev_curlyx;
sayYES;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case CURLYX_end_fail: /* just failed to match all of A*B */
regcpblow(ST.cp);
cur_curlyx = ST.prev_curlyx;
sayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
#undef ST
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_pre, A, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
/* If degenerate A matches "", assume A done. */
REGCP_SET(ST.lastcp);
PUSH_YES_STATE_GOTO(WHILEM_B_min, ST.save_curlyx->u.curlyx.B,
locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
/* Prefer A over B for maximal matching. */
cur_curlyx->u.curlyx.lastloc = locinput;
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_max, A, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
goto do_whilem_B_max;
}
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case WHILEM_B_min: /* just matched B in a minimal match */
case WHILEM_B_max: /* just matched B in a maximal match */
cur_curlyx = ST.save_curlyx;
sayYES;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case WHILEM_B_max_fail: /* just failed to match B in a maximal match */
cur_curlyx = ST.save_curlyx;
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
/* FALLTHROUGH */
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
REGCP_UNWIND(ST.lastcp);
cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
PUSH_YES_STATE_GOTO(WHILEM_B_max, ST.save_curlyx->u.curlyx.B,
locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case WHILEM_B_min_fail: /* just failed to match B in a minimal match */
cur_curlyx = ST.save_curlyx;
PUSH_STATE_GOTO(WHILEM_A_min,
/*A*/ NEXTOPER(ST.save_curlyx->u.curlyx.me) + EXTRA_STEP_2ARGS,
locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
#undef ST
#define ST st->u.branch
} else {
PUSH_STATE_GOTO(BRANCH_next, scan, locinput);
}
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case CUTGROUP: /* /(*THEN)/ */
sv_yes_mark = st->u.mark.mark_name = scan->flags ? NULL :
MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(CUTGROUP_next, next, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case CUTGROUP_next_fail:
do_cutgroup = 1;
if (st->u.mark.mark_name)
sv_commit = st->u.mark.mark_name;
sayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case BRANCH_next:
sayYES;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case BRANCH_next_fail: /* that branch failed; try the next, if any */
if (do_cutgroup) {
sayNO_SILENT;
}
continue; /* execute next BRANCH[J] op */
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case MINMOD: /* next op will be non-greedy, e.g. A*? */
minmod = 1;
curlym_do_A: /* execute the A in /A{m,n}B/ */
PUSH_YES_STATE_GOTO(CURLYM_A, ST.A, locinput); /* match A */
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case CURLYM_A: /* we've just matched an A */
ST.count++;
}
PUSH_STATE_GOTO(CURLYM_B, ST.B, locinput); /* match B */
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case CURLYM_B_fail: /* just failed to match a B */
REGCP_UNWIND(ST.cp);
REGCP_SET(ST.cp);
goto curly_try_B_max;
}
- assert(0); /* NOTREACHED */
-
+ /* NOTREACHED */
+ assert(0);
case CURLY_B_min_known_fail:
/* failed to find B in a non-greedy match where c1,c2 valid */
}
PUSH_STATE_GOTO(CURLY_B_min_known, ST.B, locinput);
}
- assert(0); /* NOTREACHED */
-
+ /* NOTREACHED */
+ assert(0);
case CURLY_B_min_fail:
/* failed to find B in a non-greedy match where c1,c2 invalid */
}
}
sayNO;
- assert(0); /* NOTREACHED */
-
+ /* NOTREACHED */
+ assert(0);
curly_try_B_max:
/* a successful greedy match: now try to match B */
if (ST.c1 == CHRTEST_VOID || could_match) {
CURLY_SETPAREN(ST.paren, ST.count);
PUSH_STATE_GOTO(CURLY_B_max, ST.B, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
}
/* FALLTHROUGH */
/* execute body of (?...A) */
PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)), newstart);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
case IFMATCH_A_fail: /* body of (?...A) failed */
if (!scan->flags)
sv_yes_mark = sv_commit = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(COMMIT_next, next, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case COMMIT_next_fail:
no_final = 1;
case OPFAIL: /* (*FAIL) */
sayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
#define ST st->u.mark
case MARKPOINT: /* (*MARK:foo) */
mark_state = st;
ST.mark_loc = locinput;
PUSH_YES_STATE_GOTO(MARKPOINT_next, next, locinput);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case MARKPOINT_next:
mark_state = ST.prev_mark;
sayYES;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case MARKPOINT_next_fail:
if (popmark && sv_eq(ST.mark_name,popmark))
sv_yes_mark = mark_state ?
mark_state->u.mark.mark_name : NULL;
sayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
case SKIP: /* (*SKIP) */
if (scan->flags) {
}
no_final = 1;
sayNO;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
#undef ST
case LNBREAK: /* \R */
/* switch break jumps here */
scan = next; /* prepare to execute the next op and ... */
continue; /* ... jump back to the top, reusing st */
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
push_yes_state:
/* push a state that backtracks on success */
locinput = pushinput;
st = newst;
continue;
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
}
* the terminating point.
*/
Perl_croak(aTHX_ "corrupted regexp pointers");
- /*NOTREACHED*/
+ /* NOTREACHED */
sayNO;
yes:
default:
Perl_croak(aTHX_ "panic: regrepeat() called with unrecognized node type %d='%s'", OP(p), PL_reg_name[OP(p)]);
- assert(0); /* NOTREACHED */
+ /* NOTREACHED */
+ assert(0);
}
GET_RE_DEBUG_FLAGS_DECL;
DEBUG_EXECUTE_r({
SV * const prop = sv_newmortal();
- regprop(prog, prop, p, reginfo);
+ regprop(prog, prop, p, reginfo, NULL);
PerlIO_printf(Perl_debug_log,
"%*s %s can match %"IVdf" times out of %"IVdf"...\n",
REPORT_CODE_OFF + depth*2, "", SvPVX_const(prop),(IV)c,(IV)max);
*altsvp = NULL;
}
- return newSVsv(_get_regclass_nonbitmap_data(prog, node, doinit, listsvp, NULL));
+ return newSVsv(_get_regclass_nonbitmap_data(prog, node, doinit, listsvp, NULL, NULL));
}
-SV *
-Perl__get_regclass_nonbitmap_data(pTHX_ const regexp *prog,
- const regnode* node,
- bool doinit,
- SV** listsvp,
- SV** only_utf8_locale_ptr)
-{
- /* For internal core use only.
- * Returns the swash for the input 'node' in the regex 'prog'.
- * If <doinit> is 'true', will attempt to create the swash if not already
- * done.
- * If <listsvp> is non-null, will return the printable contents of the
- * swash. This can be used to get debugging information even before the
- * swash exists, by calling this function with 'doinit' set to false, in
- * which case the components that will be used to eventually create the
- * swash are returned (in a printable form).
- * Tied intimately to how regcomp.c sets up the data structure */
-
- SV *sw = NULL;
- SV *si = NULL; /* Input swash initialization string */
- SV* invlist = NULL;
-
- RXi_GET_DECL(prog,progi);
- const struct reg_data * const data = prog ? progi->data : NULL;
-
- PERL_ARGS_ASSERT__GET_REGCLASS_NONBITMAP_DATA;
-
- assert(ANYOF_FLAGS(node)
- & (ANYOF_UTF8|ANYOF_NONBITMAP_NON_UTF8|ANYOF_LOC_FOLD));
-
- if (data && data->count) {
- const U32 n = ARG(node);
-
- if (data->what[n] == 's') {
- SV * const rv = MUTABLE_SV(data->data[n]);
- AV * const av = MUTABLE_AV(SvRV(rv));
- SV **const ary = AvARRAY(av);
- U8 swash_init_flags = _CORE_SWASH_INIT_ACCEPT_INVLIST;
-
- si = *ary; /* ary[0] = the string to initialize the swash with */
-
- /* Elements 3 and 4 are either both present or both absent. [3] is
- * any inversion list generated at compile time; [4] indicates if
- * that inversion list has any user-defined properties in it. */
- if (av_tindex(av) >= 2) {
- if (only_utf8_locale_ptr
- && ary[2]
- && ary[2] != &PL_sv_undef)
- {
- *only_utf8_locale_ptr = ary[2];
- }
- else {
- assert(only_utf8_locale_ptr);
- *only_utf8_locale_ptr = NULL;
- }
-
- if (av_tindex(av) >= 3) {
- invlist = ary[3];
- if (SvUV(ary[4])) {
- swash_init_flags |= _CORE_SWASH_INIT_USER_DEFINED_PROPERTY;
- }
- }
- else {
- invlist = NULL;
- }
- }
-
- /* Element [1] is reserved for the set-up swash. If already there,
- * return it; if not, create it and store it there */
- if (ary[1] && SvROK(ary[1])) {
- sw = ary[1];
- }
- else if (doinit && ((si && si != &PL_sv_undef)
- || (invlist && invlist != &PL_sv_undef))) {
- assert(si);
- sw = _core_swash_init("utf8", /* the utf8 package */
- "", /* nameless */
- si,
- 1, /* binary */
- 0, /* not from tr/// */
- invlist,
- &swash_init_flags);
- (void)av_store(av, 1, sw);
- }
- }
- }
-
- /* If requested, return a printable version of what this swash matches */
- if (listsvp) {
- SV* matches_string = newSVpvs("");
-
- /* The swash should be used, if possible, to get the data, as it
- * contains the resolved data. But this function can be called at
- * compile-time, before everything gets resolved, in which case we
- * return the currently best available information, which is the string
- * that will eventually be used to do that resolving, 'si' */
- if ((! sw || (invlist = _get_swash_invlist(sw)) == NULL)
- && (si && si != &PL_sv_undef))
- {
- sv_catsv(matches_string, si);
- }
-
- /* Add the inversion list to whatever we have. This may have come from
- * the swash, or from an input parameter */
- if (invlist) {
- sv_catsv(matches_string, _invlist_contents(invlist));
- }
- *listsvp = matches_string;
- }
-
- return sw;
-}
#endif /* !defined(PERL_IN_XSUB_RE) || defined(PLUGGABLE_RE_EXTENSION) */
/*
}
/* If this character is potentially in the bitmap, check it */
- if (c < 256) {
+ if (c < NUM_ANYOF_CODE_POINTS) {
if (ANYOF_BITMAP_TEST(n, c))
match = TRUE;
- else if (flags & ANYOF_NON_UTF8_NON_ASCII_ALL
- && ! utf8_target
- && ! isASCII(c))
+ else if ((flags & ANYOF_MATCHES_ALL_NON_UTF8_NON_ASCII)
+ && ! utf8_target
+ && ! isASCII(c))
{
match = TRUE;
}
else if (flags & ANYOF_LOCALE_FLAGS) {
- if (flags & ANYOF_LOC_FOLD) {
- if (ANYOF_BITMAP_TEST(n, PL_fold_locale[c])) {
- match = TRUE;
- }
+ if ((flags & ANYOF_LOC_FOLD)
+ && c < 256
+ && ANYOF_BITMAP_TEST(n, PL_fold_locale[c]))
+ {
+ match = TRUE;
}
- if (! match && ANYOF_POSIXL_TEST_ANY_SET(n)) {
+ else if (ANYOF_POSIXL_TEST_ANY_SET(n)
+ && c < 256
+ ) {
/* The data structure is arranged so bits 0, 2, 4, ... are set
* if the class includes the Posix character class given by
/* If the bitmap didn't (or couldn't) match, and something outside the
* bitmap could match, try that. */
if (!match) {
- if (c >= 256 && (flags & ANYOF_ABOVE_LATIN1_ALL)) {
- match = TRUE; /* Everything above 255 matches */
+ if (c >= NUM_ANYOF_CODE_POINTS
+ && (flags & ANYOF_MATCHES_ALL_ABOVE_BITMAP))
+ {
+ match = TRUE; /* Everything above the bitmap matches */
}
- else if ((flags & ANYOF_NONBITMAP_NON_UTF8)
- || (utf8_target && (flags & ANYOF_UTF8))
+ else if ((flags & ANYOF_HAS_NONBITMAP_NON_UTF8_MATCHES)
+ || (utf8_target && (flags & ANYOF_HAS_UTF8_NONBITMAP_MATCHES))
|| ((flags & ANYOF_LOC_FOLD)
&& IN_UTF8_CTYPE_LOCALE
- && ARG(n) != ANYOF_NONBITMAP_EMPTY))
+ && ARG(n) != ANYOF_ONLY_HAS_BITMAP))
{
SV* only_utf8_locale = NULL;
SV * const sw = _get_regclass_nonbitmap_data(prog, n, TRUE, 0,
- &only_utf8_locale);
+ &only_utf8_locale, NULL);
if (sw) {
U8 utf8_buffer[2];
U8 * utf8_p;