#define restore_expect CPerlObj::Perl_restore_expect
#define restore_lex_expect CPerlObj::Perl_restore_lex_expect
#define restore_magic CPerlObj::Perl_restore_magic
+#define restore_pos CPerlObj::Perl_restore_pos
#define restore_rsfp CPerlObj::Perl_restore_rsfp
#define rninstr CPerlObj::Perl_rninstr
#define rsignal CPerlObj::Perl_rsignal
regcppop
regcp_set_to
cache_re
+ restore_pos
reghop
reghopmaybe
dump
#define PL_reg_eval_set (PL_curinterp->Treg_eval_set)
#define PL_reg_flags (PL_curinterp->Treg_flags)
#define PL_reg_ganch (PL_curinterp->Treg_ganch)
+#define PL_reg_magic (PL_curinterp->Treg_magic)
+#define PL_reg_oldpos (PL_curinterp->Treg_oldpos)
#define PL_reg_re (PL_curinterp->Treg_re)
#define PL_reg_start_tmp (PL_curinterp->Treg_start_tmp)
#define PL_reg_start_tmpl (PL_curinterp->Treg_start_tmpl)
#define PL_Treg_eval_set PL_reg_eval_set
#define PL_Treg_flags PL_reg_flags
#define PL_Treg_ganch PL_reg_ganch
+#define PL_Treg_magic PL_reg_magic
+#define PL_Treg_oldpos PL_reg_oldpos
#define PL_Treg_re PL_reg_re
#define PL_Treg_start_tmp PL_reg_start_tmp
#define PL_Treg_start_tmpl PL_reg_start_tmpl
#define PL_reg_eval_set (thr->Treg_eval_set)
#define PL_reg_flags (thr->Treg_flags)
#define PL_reg_ganch (thr->Treg_ganch)
+#define PL_reg_magic (thr->Treg_magic)
+#define PL_reg_oldpos (thr->Treg_oldpos)
#define PL_reg_re (thr->Treg_re)
#define PL_reg_start_tmp (thr->Treg_start_tmp)
#define PL_reg_start_tmpl (thr->Treg_start_tmpl)
#define PL_reg_flags pPerl->PL_reg_flags
#undef PL_reg_ganch
#define PL_reg_ganch pPerl->PL_reg_ganch
+#undef PL_reg_magic
+#define PL_reg_magic pPerl->PL_reg_magic
+#undef PL_reg_oldpos
+#define PL_reg_oldpos pPerl->PL_reg_oldpos
#undef PL_reg_re
#define PL_reg_re pPerl->PL_reg_re
#undef PL_reg_start_tmp
#define restore_lex_expect pPerl->Perl_restore_lex_expect
#undef restore_magic
#define restore_magic pPerl->Perl_restore_magic
+#undef restore_pos
+#define restore_pos pPerl->Perl_restore_pos
#undef restore_rsfp
#define restore_rsfp pPerl->Perl_restore_rsfp
#undef rninstr
/* Are we done */
if (cx->sb_once || !CALLREGEXEC(rx, s, cx->sb_strend, orig,
- s == m, Nullsv, cx->sb_targ,
+ s == m, cx->sb_targ, NULL,
((cx->sb_rflags & REXEC_COPY_STR)
? 0 : REXEC_COPY_STR)))
{
char * regcppop _((void));
char * regcp_set_to _((I32 ss));
void cache_re _((regexp *prog));
+void restore_pos _((void *arg));
U8 * reghop _((U8 *pos, I32 off));
U8 * reghopmaybe _((U8 *pos, I32 off));
void dump _((char *pat,...));
static char * regcppop _((void));
static char * regcp_set_to _((I32 ss));
static void cache_re _((regexp *prog));
+static void restore_pos _((void *arg));
#endif
#define REGINCLASS(p,c) (*(p) ? reginclass(p,c) : ANYOF_TEST(p,c))
PL_reg_re = prog;
}
+STATIC void
+restore_pos(void *arg)
+{
+ if (PL_reg_eval_set) {
+ PL_reg_magic->mg_len = PL_reg_oldpos;
+ PL_reg_eval_set = 0;
+ }
+}
+
+
/*
- regexec_flags - match a regexp against a string
*/
/* Mark beginning of line for ^ and lookbehind. */
PL_regbol = startpos;
PL_bostr = strbeg;
+ PL_reg_sv = sv;
/* Mark end of line for $ (and such) */
PL_regeol = strend;
restored, the value remains
the same. */
}
+ if (PL_reg_eval_set)
+ restore_pos(0);
return 1;
phooey:
+ if (PL_reg_eval_set)
+ restore_pos(0);
return 0;
}
CHECKPOINT lastcp;
if ((prog->reganch & ROPT_EVAL_SEEN) && !PL_reg_eval_set) {
+ MAGIC *mg;
+
PL_reg_eval_set = RS_init;
DEBUG_r(DEBUG_s(
PerlIO_printf(Perl_debug_log, " setting stack tmpbase at %i\n",
/* Apparently this is not needed, judging by wantarray. */
/* SAVEINT(cxstack[cxstack_ix].blk_gimme);
cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
+
+ if (PL_reg_sv) {
+ /* Make $_ available to executed code. */
+ if (PL_reg_sv != GvSV(PL_defgv)) {
+ SAVESPTR(GvSV(PL_defgv));
+ GvSV(PL_defgv) = PL_reg_sv;
+ }
+
+ if (!(SvTYPE(PL_reg_sv) >= SVt_PVMG && SvMAGIC(PL_reg_sv)
+ && (mg = mg_find(PL_reg_sv, 'g')))) {
+ /* prepare for quick setting of pos */
+ sv_magic(PL_reg_sv, (SV*)0, 'g', Nullch, 0);
+ mg = mg_find(PL_reg_sv, 'g');
+ mg->mg_len = -1;
+ }
+ PL_reg_magic = mg;
+ PL_reg_oldpos = mg->mg_len;
+ SAVEDESTRUCTOR(restore_pos, 0);
+ }
}
PL_reginput = startpos;
PL_regstartp = prog->startp;
PL_op = (OP_4tree*)PL_regdata->data[n];
DEBUG_r( PerlIO_printf(Perl_debug_log, " re_eval 0x%x\n", PL_op) );
PL_curpad = AvARRAY((AV*)PL_regdata->data[n + 1]);
+ PL_reg_magic->mg_len = locinput - PL_bostr;
CALLRUNOPS(); /* Scalar context. */
SPAGAIN;
# the format supported by op/regexp.t. If you want to add a test
# that does fit that format, add it to op/re_tests, not here.
-print "1..168\n";
+print "1..174\n";
BEGIN {
chdir 't' if -d 't';
print "ok $test\n";
$test++;
+undef $foo; undef $bar;
+print "#'$str','$foo','$bar'\nnot "
+ unless $str =~ /b(?{$foo = $_; $bar = pos})c/
+ and $foo eq 'abcde' and $bar eq 2;
+print "ok $test\n";
+$test++;
+
+undef $foo; undef $bar;
+pos $str = undef;
+print "#'$str','$foo','$bar'\nnot "
+ unless $str =~ /b(?{$foo = $_; $bar = pos})c/g
+ and $foo eq 'abcde' and $bar eq 2 and pos $str eq 3;
+print "ok $test\n";
+$test++;
+
+$_ = $str;
+
+undef $foo; undef $bar;
+print "#'$str','$foo','$bar'\nnot "
+ unless /b(?{$foo = $_; $bar = pos})c/
+ and $foo eq 'abcde' and $bar eq 2;
+print "ok $test\n";
+$test++;
+
+undef $foo; undef $bar;
+print "#'$str','$foo','$bar'\nnot "
+ unless /b(?{$foo = $_; $bar = pos})c/g
+ and $foo eq 'abcde' and $bar eq 2 and pos eq 3;
+print "ok $test\n";
+$test++;
+
+undef $foo; undef $bar;
+pos = undef;
+1 while /b(?{$foo = $_; $bar = pos})c/g;
+print "#'$str','$foo','$bar'\nnot "
+ unless $foo eq 'abcde' and $bar eq 2 and not defined pos;
+print "ok $test\n";
+$test++;
+
+undef $foo; undef $bar;
+$_ = 'abcde|abcde';
+print "#'$str','$foo','$bar','$_'\nnot "
+ unless s/b(?{$foo = $_; $bar = pos})c/x/g and $foo eq 'abcde|abcde'
+ and $bar eq 8 and $_ eq 'axde|axde';
+print "ok $test\n";
+$test++;
+
# see if matching against temporaries (created via pp_helem()) is safe
{ foo => "ok $test\n".$^X }->{foo} =~ /^(.*)\n/g;
print "$1\n";
PERLVAR(Treg_re, regexp *) /* from regexec.c */
PERLVAR(Treg_ganch, char *) /* position of \G */
PERLVAR(Treg_sv, SV *) /* what we match against */
+PERLVAR(Treg_magic, MAGIC *) /* pos-magic of what we match */
+PERLVAR(Treg_oldpos, I32) /* old pos of what we match */
PERLVARI(Tregcompp, regcomp_t, FUNC_NAME_TO_PTR(pregcomp))
/* Pointer to RE compiler */