(IV)(cp), (IV)PL_savestack_ix)); \
regcpblow(cp)
+#define UNWIND_PAREN(lp, lcp) \
+ for (n = rex->lastparen; n > lp; n--) \
+ rex->offs[n].end = -1; \
+ rex->lastparen = n; \
+ rex->lastcloseparen = lcp;
+
+
STATIC void
S_regcppop(pTHX_ regexp *rex)
{
#endif
}
+/* restore the parens and associated vars at savestack position ix,
+ * but without popping the stack */
+
+STATIC void
+S_regcp_restore(pTHX_ regexp *rex, I32 ix)
+{
+ I32 tmpix = PL_savestack_ix;
+ PL_savestack_ix = ix;
+ regcppop(rex);
+ PL_savestack_ix = tmpix;
+}
+
#define regcpblow(cp) LEAVE_SCOPE(cp) /* Ignores regcppush()ed data. */
/*
}
+/* Set which rex is pointed to by PL_reg_state, handling ref counting.
+ * Do inc before dec, in case old and new rex are the same */
+#define SET_reg_curpm(Re2) \
+ if (PL_reg_state.re_state_eval_setup_done) { \
+ (void)ReREFCNT_inc(Re2); \
+ ReREFCNT_dec(PM_GETRE(PL_reg_curpm)); \
+ PM_SETRE((PL_reg_curpm), (Re2)); \
+ }
+
+
/*
- regtry - try match at specific point
*/
}
#endif
}
-#ifdef USE_ITHREADS
- /* It seems that non-ithreads works both with and without this code.
- So for efficiency reasons it seems best not to have the code
- compiled when it is not needed. */
- /* This is safe against NULLs: */
- ReREFCNT_dec(PM_GETRE(PL_reg_curpm));
- /* PM_reg_curpm owns a reference to this regexp. */
- (void)ReREFCNT_inc(rx);
-#endif
- PM_SETRE(PL_reg_curpm, rx);
+ SET_reg_curpm(rx);
PL_reg_oldcurpm = PL_curpm;
PL_curpm = PL_reg_curpm;
if (RXp_MATCH_COPIED(prog)) {
}
-#define SETREX(Re1,Re2) \
- if (PL_reg_state.re_state_eval_setup_done) \
- PM_SETRE((PL_reg_curpm), (Re2)); \
- Re1 = (Re2)
-
STATIC I32 /* 0 failure, 1 success */
S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
{
I32 gimme = G_SCALAR;
CV *caller_cv = NULL; /* who called us */
CV *last_pushed_cv = NULL; /* most recently called (?{}) CV */
+ CHECKPOINT runops_cp; /* savestack position before executing EVAL */
#ifdef DEBUGGING
GET_RE_DEBUG_FLAGS_DECL;
REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
);
sayNO_SILENT;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
/* FALL THROUGH */
case TRIE:
);
goto trie_first_try; /* jump into the fail handler */
}}
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case TRIE_next_fail: /* we failed - try next alternative */
if ( ST.jump) {
REGCP_UNWIND(ST.cp);
- for (n = rex->lastparen; n > ST.lastparen; n--)
- rex->offs[n].end = -1;
- rex->lastparen = n;
- rex->lastcloseparen = ST.lastcloseparen;
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
}
if (!--ST.accepted) {
DEBUG_EXECUTE_r({
if (ST.accepted > 1 || has_cutgroup) {
PUSH_STATE_GOTO(TRIE_next, scan);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
/* only one choice left - just continue */
DEBUG_EXECUTE_r({
locinput = PL_reginput;
nextchr = UCHARAT(locinput);
continue; /* execute rest of RE */
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
#undef ST
case EXACT: {
re_sv = rex_sv;
re = rex;
rei = rexi;
- (void)ReREFCNT_inc(rex_sv);
if (OP(scan)==GOSUB) {
startpoint = scan + ARG2L(scan);
ST.close_paren = ARG(scan);
ST.close_paren = 0;
}
goto eval_recurse_doit;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case EVAL: /* /(?{A})B/ /(??{A})B/ and /(?(?{A})X|Y)B/ */
if (cur_eval && cur_eval->locinput==locinput) {
if ( ++nochange_depth > max_nochange_depth )
struct re_save_state saved_state;
CV *newcv;
+ /* save *all* paren positions */
+ regcppush(rex, 0);
+ REGCP_SET(runops_cp);
+
/* To not corrupt the existing regex state while executing the
* eval we would normally put it on the save stack, like with
* save_re_context. However, re-evals have a weird scoping so we
nop = (OP*)rexi->data->data[n];
}
+ /* normally if we're about to execute code from the same
+ * CV that we used previously, we just use the existing
+ * CX stack entry. However, its possible that in the
+ * meantime we may have backtracked, popped from the save
+ * stack, and undone the SAVECOMPPAD(s) associated with
+ * PUSH_MULTICALL; in which case PL_comppad no longer
+ * points to newcv's pad. */
+ if (newcv != last_pushed_cv || PL_comppad != last_pad)
+ {
+ I32 depth = (newcv == caller_cv) ? 0 : 1;
+ if (last_pushed_cv) {
+ CHANGE_MULTICALL_WITHDEPTH(newcv, depth);
+ }
+ else {
+ PUSH_MULTICALL_WITHDEPTH(newcv, depth);
+ }
+ last_pushed_cv = newcv;
+ }
+ last_pad = PL_comppad;
+
/* the initial nextstate you would normally execute
* at the start of an eval (which would cause error
* messages to come from the eval), may be optimised
DEBUG_STATE_r( PerlIO_printf(Perl_debug_log,
" re EVAL PL_op=0x%"UVxf"\n", PTR2UV(nop)) );
- /* normally if we're about to execute code from the same
- * CV that we used previously, we just use the existing
- * CX stack entry. However, its possible that in the
- * meantime we may have backtracked, popped from the save
- * stack, and undone the SAVECOMPPAD(s) associated with
- * PUSH_MULTICALL; in which case PL_comppad no longer
- * points to newcv's pad. */
- if (newcv != last_pushed_cv || PL_comppad != last_pad)
- {
- I32 depth = (newcv == caller_cv) ? 0 : 1;
- if (last_pushed_cv) {
- CHANGE_MULTICALL_WITHDEPTH(newcv, depth);
- }
- else {
- PUSH_MULTICALL_WITHDEPTH(newcv, depth);
- }
- last_pushed_cv = newcv;
- }
- last_pad = PL_comppad;
-
rex->offs[0].end = PL_reg_magic->mg_len = locinput - PL_bostr;
if (sv_yes_mark) {
PUTBACK;
}
+ /* before restoring everything, evaluate the returned
+ * value, so that 'uninit' warnings don't use the wrong
+ * PL_op or pad. Also need to process any magic vars
+ * (e.g. $1) *before* parentheses are restored */
+
+ PL_op = NULL;
+
+ re_sv = NULL;
+ if (logical == 0) /* (?{})/ */
+ sv_setsv(save_scalar(PL_replgv), ret); /* $^R */
+ else if (logical == 1) { /* /(?(?{...})X|Y)/ */
+ sw = cBOOL(SvTRUE(ret));
+ logical = 0;
+ }
+ else { /* /(??{}) */
+ /* if its overloaded, let the regex compiler handle
+ * it; otherwise extract regex, or stringify */
+ if (!SvAMAGIC(ret)) {
+ SV *sv = ret;
+ if (SvROK(sv))
+ sv = SvRV(sv);
+ if (SvTYPE(sv) == SVt_REGEXP)
+ re_sv = (REGEXP*) sv;
+ else if (SvSMAGICAL(sv)) {
+ MAGIC *mg = mg_find(sv, PERL_MAGIC_qr);
+ if (mg)
+ re_sv = (REGEXP *) mg->mg_obj;
+ }
+
+ /* force any magic, undef warnings here */
+ if (!re_sv) {
+ ret = sv_mortalcopy(ret);
+ (void) SvPV_force_nolen(ret);
+ }
+ }
+
+ }
+
Copy(&saved_state, &PL_reg_state, 1, struct re_save_state);
/* *** Note that at this point we don't restore
PL_op = oop;
PL_curcop = ocurcop;
PL_regeol = saved_regeol;
- if (!logical) {
- /* /(?{...})/ */
- sv_setsv(save_scalar(PL_replgv), ret);
+ S_regcp_restore(aTHX_ rex, runops_cp);
+
+ if (logical != 2)
break;
- }
}
- if (logical == 2) { /* Postponed subexpression: /(??{...})/ */
+
+ /* only /(??{})/ from now on */
logical = 0;
{
/* extract RE object from returned value; compiling if
* necessary */
- MAGIC *mg = NULL;
- REGEXP *rx = NULL;
-
- if (SvROK(ret)) {
- SV *const sv = SvRV(ret);
-
- if (SvTYPE(sv) == SVt_REGEXP) {
- rx = (REGEXP*) sv;
- } else if (SvSMAGICAL(sv)) {
- mg = mg_find(sv, PERL_MAGIC_qr);
- assert(mg);
- }
- } else if (SvTYPE(ret) == SVt_REGEXP) {
- rx = (REGEXP*) ret;
- } else if (SvSMAGICAL(ret)) {
- if (SvGMAGICAL(ret)) {
- /* I don't believe that there is ever qr magic
- here. */
- assert(!mg_find(ret, PERL_MAGIC_qr));
- sv_unmagic(ret, PERL_MAGIC_qr);
- }
- else {
- mg = mg_find(ret, PERL_MAGIC_qr);
- /* testing suggests mg only ends up non-NULL for
- scalars who were upgraded and compiled in the
- else block below. In turn, this is only
- triggered in the "postponed utf8 string" tests
- in t/op/pat.t */
- }
- }
- if (mg) {
- rx = (REGEXP *) mg->mg_obj; /*XXX:dmq*/
- assert(rx);
- }
- if (rx) {
- rx = reg_temp_copy(NULL, rx);
+ if (re_sv) {
+ re_sv = reg_temp_copy(NULL, re_sv);
}
else {
U32 pm_flags = 0;
const I32 osize = PL_regsize;
- if (DO_UTF8(ret)) {
- assert (SvUTF8(ret));
- } else if (SvUTF8(ret)) {
- /* Not doing UTF-8, despite what the SV says. Is
- this only if we're trapped in use 'bytes'? */
- /* Make a copy of the octet sequence, but without
- the flag on, as the compiler now honours the
- SvUTF8 flag on ret. */
+ if (SvUTF8(ret) && IN_BYTES) {
+ /* In use 'bytes': make a copy of the octet
+ * sequence, but without the flag on */
STRLEN len;
const char *const p = SvPV(ret, len);
ret = newSVpvn_flags(p, len, SVs_TEMP);
}
- rx = CALLREGCOMP(ret, pm_flags);
+ if (rex->intflags & PREGf_USE_RE_EVAL)
+ pm_flags |= PMf_USE_RE_EVAL;
+
+ /* if we got here, it should be an engine which
+ * supports compiling code blocks and stuff */
+ assert(rex->engine && rex->engine->op_comp);
+ assert(!(scan->flags & ~RXf_PMf_COMPILETIME));
+ re_sv = rex->engine->op_comp(aTHX_ &ret, 1, NULL,
+ rex->engine, NULL, NULL,
+ /* copy /msix etc to inner pattern */
+ scan->flags,
+ pm_flags);
+
if (!(SvFLAGS(ret)
& (SVs_TEMP | SVs_PADTMP | SVf_READONLY
| SVs_GMG))) {
/* This isn't a first class regexp. Instead, it's
caching a regexp onto an existing, Perl visible
scalar. */
- sv_magic(ret, MUTABLE_SV(rx), PERL_MAGIC_qr, 0, 0);
+ sv_magic(ret, MUTABLE_SV(re_sv), PERL_MAGIC_qr, 0, 0);
}
PL_regsize = osize;
+ /* safe to do now that any $1 etc has been
+ * interpolated into the new pattern string and
+ * compiled */
+ S_regcp_restore(aTHX_ rex, runops_cp);
}
- re_sv = rx;
- re = (struct regexp *)SvANY(rx);
+ re = (struct regexp *)SvANY(re_sv);
}
RXp_MATCH_COPIED_off(re);
re->subbeg = rex->subbeg;
ST.cp = regcppush(rex, 0); /* Save *all* the positions. */
REGCP_SET(ST.lastcp);
- /* see regtry, specifically PL_reglast(?:close)?paren is a pointer! (i dont know why) :dmq */
re->lastparen = 0;
re->lastcloseparen = 0;
ST.prev_rex = rex_sv;
ST.prev_curlyx = cur_curlyx;
- SETREX(rex_sv,re_sv);
+ rex_sv = re_sv;
+ SET_reg_curpm(rex_sv);
rex = re;
rexi = rei;
cur_curlyx = NULL;
cur_eval = st;
/* now continue from first node in postoned RE */
PUSH_YES_STATE_GOTO(EVAL_AB, startpoint);
- /* NOTREACHED */
- }
- /* logical is 1, /(?(?{...})X|Y)/ */
- sw = cBOOL(SvTRUE(ret));
- logical = 0;
- break;
+ assert(0); /* NOTREACHED */
}
case EVAL_AB: /* cleanup after a successful (??{A})B */
/* note: this is called twice; first after popping B, then A */
PL_reg_flags ^= ST.toggle_reg_flags;
- ReREFCNT_dec(rex_sv);
- SETREX(rex_sv,ST.prev_rex);
+ rex_sv = ST.prev_rex;
+ SET_reg_curpm(rex_sv);
rex = (struct regexp *)SvANY(rex_sv);
rexi = RXi_GET(rex);
regcpblow(ST.cp);
case EVAL_AB_fail: /* unsuccessfully ran A or B in (??{A})B */
/* note: this is called twice; first after popping B, then A */
PL_reg_flags ^= ST.toggle_reg_flags;
- ReREFCNT_dec(rex_sv);
- SETREX(rex_sv,ST.prev_rex);
+ rex_sv = ST.prev_rex;
+ SET_reg_curpm(rex_sv);
rex = (struct regexp *)SvANY(rex_sv);
rexi = RXi_GET(rex);
PL_reginput = locinput;
PUSH_YES_STATE_GOTO(CURLYX_end, PREVOPER(next));
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
case CURLYX_end: /* just finished matching all of A*B */
cur_curlyx = ST.prev_curlyx;
sayYES;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CURLYX_end_fail: /* just failed to match all of A*B */
regcpblow(ST.cp);
cur_curlyx = ST.prev_curlyx;
sayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
#undef ST
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_pre, A);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
/* If degenerate A matches "", assume A done. */
ST.cp = regcppush(rex, ST.save_curlyx->u.curlyx.parenfloor);
REGCP_SET(ST.lastcp);
PUSH_YES_STATE_GOTO(WHILEM_B_min, ST.save_curlyx->u.curlyx.B);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
/* Prefer A over B for maximal matching. */
cur_curlyx->u.curlyx.lastloc = locinput;
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_max, A);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
goto do_whilem_B_max;
}
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
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;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
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;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
/* FALL THROUGH */
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
REGCP_UNWIND(ST.lastcp);
ST.save_curlyx = cur_curlyx;
cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
PUSH_YES_STATE_GOTO(WHILEM_B_max, ST.save_curlyx->u.curlyx.B);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case WHILEM_B_min_fail: /* just failed to match B in a minimal match */
cur_curlyx = ST.save_curlyx;
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_min,
/*A*/ NEXTOPER(ST.save_curlyx->u.curlyx.me) + EXTRA_STEP_2ARGS);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
#undef ST
#define ST st->u.branch
} else {
PUSH_STATE_GOTO(BRANCH_next, scan);
}
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CUTGROUP:
PL_reginput = locinput;
sv_yes_mark = st->u.mark.mark_name = scan->flags ? NULL :
MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(CUTGROUP_next,next);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CUTGROUP_next_fail:
do_cutgroup = 1;
no_final = 1;
if (st->u.mark.mark_name)
sv_commit = st->u.mark.mark_name;
sayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case BRANCH_next:
sayYES;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case BRANCH_next_fail: /* that branch failed; try the next, if any */
if (do_cutgroup) {
do_cutgroup = 0;
no_final = 0;
}
REGCP_UNWIND(ST.cp);
- for (n = rex->lastparen; n > ST.lastparen; n--)
- rex->offs[n].end = -1;
- rex->lastparen = n;
- rex->lastcloseparen = ST.lastcloseparen;
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
scan = ST.next_branch;
/* no more branches? */
if (!scan || (OP(scan) != BRANCH && OP(scan) != BRANCHJ)) {
sayNO_SILENT;
}
continue; /* execute next BRANCH[J] op */
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case MINMOD:
minmod = 1;
curlym_do_A: /* execute the A in /A{m,n}B/ */
PL_reginput = locinput;
PUSH_YES_STATE_GOTO(CURLYM_A, ST.A); /* match A */
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CURLYM_A: /* we've just matched an A */
locinput = st->locinput;
}
PUSH_STATE_GOTO(CURLYM_B, ST.B); /* match B */
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CURLYM_B_fail: /* just failed to match a B */
REGCP_UNWIND(ST.cp);
- rex->lastparen = ST.lastparen;
- rex->lastcloseparen = ST.lastcloseparen;
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
if (ST.minmod) {
I32 max = ARG2(ST.me);
if (max != REG_INFTY && ST.count == max)
REGCP_SET(ST.cp);
goto curly_try_B_max;
}
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CURLY_B_min_known_fail:
PL_reginput = locinput; /* Could be reset... */
REGCP_UNWIND(ST.cp);
+ if (ST.paren) {
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
+ }
/* Couldn't or didn't -- move forward. */
ST.oldloc = locinput;
if (utf8_target)
}
PUSH_STATE_GOTO(CURLY_B_min_known, ST.B);
}
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case CURLY_B_min_fail:
/* failed to find B in a non-greedy match where c1,c2 invalid */
REGCP_UNWIND(ST.cp);
+ if (ST.paren) {
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
+ }
/* failed -- move forward one */
PL_reginput = locinput;
if (regrepeat(rex, ST.A, 1, depth)) {
}
}
sayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
curly_try_B_max:
if (ST.c1 == CHRTEST_VOID || c == (UV)ST.c1 || c == (UV)ST.c2) {
CURLY_SETPAREN(ST.paren, ST.count);
PUSH_STATE_GOTO(CURLY_B_max, ST.B);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
}
/* FALL THROUGH */
/* failed to find B in a greedy match */
REGCP_UNWIND(ST.cp);
+ if (ST.paren) {
+ UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
+ }
/* back up. */
if (--ST.count < ST.min)
sayNO;
fake_end:
if (cur_eval) {
/* we've just finished A in /(??{A})B/; now continue with B */
- I32 tmpix;
st->u.eval.toggle_reg_flags
= cur_eval->u.eval.toggle_reg_flags;
PL_reg_flags ^= st->u.eval.toggle_reg_flags;
st->u.eval.prev_rex = rex_sv; /* inner */
st->u.eval.cp = regcppush(rex, 0); /* Save *all* the positions. */
- SETREX(rex_sv,cur_eval->u.eval.prev_rex);
+ rex_sv = cur_eval->u.eval.prev_rex;
+ SET_reg_curpm(rex_sv);
rex = (struct regexp *)SvANY(rex_sv);
rexi = RXi_GET(rex);
cur_curlyx = cur_eval->u.eval.prev_curlyx;
- (void)ReREFCNT_inc(rex_sv);
REGCP_SET(st->u.eval.lastcp);
PL_reginput = locinput;
/* Restore parens of the outer rex without popping the
* savestack */
- tmpix = PL_savestack_ix;
- PL_savestack_ix = cur_eval->u.eval.lastcp;
- regcppop(rex);
- PL_savestack_ix = tmpix;
+ S_regcp_restore(aTHX_ rex, cur_eval->u.eval.lastcp);
st->u.eval.prev_eval = cur_eval;
cur_eval = cur_eval->u.eval.prev_eval;
/* execute body of (?...A) */
PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)));
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case IFMATCH_A_fail: /* body of (?...A) failed */
ST.wanted = !ST.wanted;
if (!scan->flags)
sv_yes_mark = sv_commit = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(COMMIT_next,next);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case COMMIT_next_fail:
no_final = 1;
/* FALLTHROUGH */
case OPFAIL:
sayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
#define ST st->u.mark
case MARKPOINT:
mark_state = st;
ST.mark_loc = PL_reginput = locinput;
PUSH_YES_STATE_GOTO(MARKPOINT_next,next);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case MARKPOINT_next:
mark_state = ST.prev_mark;
sayYES;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
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;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
case SKIP:
PL_reginput = locinput;
if (scan->flags) {
}
no_final = 1;
sayNO;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
#undef ST
case LNBREAK:
if ((n=is_LNBREAK(locinput,utf8_target))) {
/* switch break jumps here */
scan = next; /* prepare to execute the next op and ... */
continue; /* ... jump back to the top, reusing st */
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
push_yes_state:
/* push a state that backtracks on success */
nextchr = UCHARAT(locinput);
st = newst;
continue;
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
}