X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=regexec.c;h=da4513bc95a5f8bdfbecfcdf4f4b812f741c3b61;hb=f022b9987cfef8a7e7c7c892f22c2e71c583bfc7;hp=5990ea3ca4b6871a9a0bb2061450913440d3e81b;hpb=9b877dbba0196ef7d4c6e2b0fcfc6e6f4955d526;p=p5sagit%2Fp5-mst-13.2.git diff --git a/regexec.c b/regexec.c index 5990ea3..da4513b 100644 --- a/regexec.c +++ b/regexec.c @@ -38,11 +38,11 @@ # define Perl_re_intuit_start my_re_intuit_start /* *These* symbols are masked to allow static link. */ # define Perl_pregexec my_pregexec -# define Perl_reginitcolors my_reginitcolors +# define Perl_reginitcolors my_reginitcolors # define Perl_regclass_swash my_regclass_swash # define PERL_NO_GET_CONTEXT -#endif +#endif /*SUPPRESS 112*/ /* @@ -116,6 +116,15 @@ #define HOPc(pos,off) ((char*)HOP(pos,off)) #define HOPMAYBEc(pos,off) ((char*)HOPMAYBE(pos,off)) +#define HOPBACK(pos, off) ( \ + (UTF && DO_UTF8(PL_reg_sv)) \ + ? reghopmaybe((U8*)pos, -off) \ + : (pos - off >= PL_bostr) \ + ? (U8*)(pos - off) \ + : (U8*)NULL \ +) +#define HOPBACKc(pos, off) (char*)HOPBACK(pos, off) + #define reghop3_c(pos,off,lim) ((char*)reghop3((U8*)pos, off, (U8*)lim)) #define reghopmaybe3_c(pos,off,lim) ((char*)reghopmaybe3((U8*)pos, off, (U8*)lim)) #define HOP3(pos,off,lim) (DO_UTF8(PL_reg_sv) ? reghop3((U8*)pos, off, (U8*)lim) : (U8*)(pos + off)) @@ -123,28 +132,40 @@ #define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim)) #define HOPMAYBE3c(pos,off,lim) ((char*)HOPMAYBE3(pos,off,lim)) -static void restore_pos(pTHXo_ void *arg); +#define LOAD_UTF8_CHARCLASS(a,b) STMT_START { if (!CAT2(PL_utf8_,a)) (void)CAT2(is_utf8_, a)((U8*)b); } STMT_END +static void restore_pos(pTHXo_ void *arg); STATIC CHECKPOINT S_regcppush(pTHX_ I32 parenfloor) { int retval = PL_savestack_ix; - int i = (PL_regsize - parenfloor) * 4; +#define REGCP_PAREN_ELEMS 4 + int paren_elems_to_push = (PL_regsize - parenfloor) * REGCP_PAREN_ELEMS; int p; - SSCHECK(i + 5); + if (paren_elems_to_push < 0) + Perl_croak(aTHX_ "panic: paren_elems_to_push < 0"); + +#define REGCP_OTHER_ELEMS 5 + SSCHECK(paren_elems_to_push + REGCP_OTHER_ELEMS); for (p = PL_regsize; p > parenfloor; p--) { +/* REGCP_PARENS_ELEMS are pushed per pairs of parentheses. */ SSPUSHINT(PL_regendp[p]); SSPUSHINT(PL_regstartp[p]); SSPUSHPTR(PL_reg_start_tmp[p]); SSPUSHINT(p); } +/* REGCP_OTHER_ELEMS are pushed in any case, parentheses or no. */ SSPUSHINT(PL_regsize); SSPUSHINT(*PL_reglastparen); SSPUSHPTR(PL_reginput); - SSPUSHINT(i + 3); - SSPUSHINT(SAVEt_REGCONTEXT); +#define REGCP_FRAME_ELEMS 2 +/* REGCP_FRAME_ELEMS are part of the REGCP_OTHER_ELEMS and + * are needed for the regexp context stack bookkeeping. */ + SSPUSHINT(paren_elems_to_push + REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS); + SSPUSHINT(SAVEt_REGCONTEXT); /* Magic cookie. */ + return retval; } @@ -161,16 +182,22 @@ S_regcppush(pTHX_ I32 parenfloor) STATIC char * S_regcppop(pTHX) { - I32 i = SSPOPINT; + I32 i; U32 paren = 0; char *input; I32 tmps; - assert(i == SAVEt_REGCONTEXT); + + /* Pop REGCP_OTHER_ELEMS before the parentheses loop starts. */ i = SSPOPINT; + assert(i == SAVEt_REGCONTEXT); /* Check that the magic cookie is there. */ + i = SSPOPINT; /* Parentheses elements to pop. */ input = (char *) SSPOPPTR; *PL_reglastparen = SSPOPINT; PL_regsize = SSPOPINT; - for (i -= 3; i > 0; i -= 4) { + + /* Now restore the parentheses context. */ + for (i -= (REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS); + i > 0; i -= REGCP_PAREN_ELEMS) { paren = (U32)SSPOPINT; PL_reg_start_tmp[paren] = (char *) SSPOPPTR; PL_regstartp[paren] = SSPOPINT; @@ -180,9 +207,9 @@ S_regcppop(pTHX) DEBUG_r( PerlIO_printf(Perl_debug_log, " restoring \\%"UVuf" to %"IVdf"(%"IVdf")..%"IVdf"%s\n", - (UV)paren, (IV)PL_regstartp[paren], + (UV)paren, (IV)PL_regstartp[paren], (IV)(PL_reg_start_tmp[paren] - PL_bostr), - (IV)PL_regendp[paren], + (IV)PL_regendp[paren], (paren > *PL_reglastparen ? "(no)" : "")); ); } @@ -267,7 +294,7 @@ Perl_pregexec(pTHX_ register regexp *prog, char *stringarg, register char *stren /* nosave: For optimizations. */ { return - regexec_flags(prog, stringarg, strend, strbeg, minend, screamer, NULL, + regexec_flags(prog, stringarg, strend, strbeg, minend, screamer, NULL, nosave ? 0 : REXEC_COPY_STR); } @@ -279,11 +306,11 @@ S_cache_re(pTHX_ regexp *prog) PL_regprogram = prog->program; #endif PL_regnpar = prog->nparens; - PL_regdata = prog->data; - PL_reg_re = prog; + PL_regdata = prog->data; + PL_reg_re = prog; } -/* +/* * Need to implement the following flags for reg_anch: * * USE_INTUIT_NOML - Useful to call re_intuit_start() first @@ -333,17 +360,16 @@ char * Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, char *strend, U32 flags, re_scream_pos_data *data) { - register I32 start_shift; + register I32 start_shift = 0; /* Should be nonnegative! */ - register I32 end_shift; + register I32 end_shift = 0; register char *s; register SV *check; char *strbeg; char *t; I32 ml_anch; - char *tmp; register char *other_last = Nullch; /* other substr checked before this */ - char *check_at; /* check substr found at this pos */ + char *check_at = Nullch; /* check substr found at this pos */ #ifdef DEBUGGING char *i_strpos = strpos; #endif @@ -377,14 +403,16 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, && !PL_multiline ) ); /* Check after \n? */ if (!ml_anch) { - if ( !(prog->reganch & ROPT_ANCH_GPOS) /* Checked by the caller */ + if ( !(prog->reganch & (ROPT_ANCH_GPOS /* Checked by the caller */ + | ROPT_IMPLICIT)) /* not a real BOL */ /* SvCUR is not set on references: SvRV and SvPVX overlap */ && sv && !SvROK(sv) && (strpos != strbeg)) { DEBUG_r(PerlIO_printf(Perl_debug_log, "Not at start...\n")); goto fail; } - if (prog->check_offset_min == prog->check_offset_max) { + if (prog->check_offset_min == prog->check_offset_max && + !(prog->reganch & ROPT_SANY_SEEN)) { /* Substring at constant offset from beg-of-str... */ I32 slen; @@ -392,7 +420,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, if (SvTAIL(check)) { slen = SvCUR(check); /* >= 1 */ - if ( strend - s > slen || strend - s < slen - 1 + if ( strend - s > slen || strend - s < slen - 1 || (strend - s == slen && strend[-1] != '\n')) { DEBUG_r(PerlIO_printf(Perl_debug_log, "String too long...\n")); goto fail_finish; @@ -443,8 +471,6 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, #endif restart: - other_last = Nullch; - /* Find a possible match in the region s..strend by looking for the "check" substring in the region corrected by start/end_shift. */ if (flags & REXEC_SCREAM) { @@ -455,13 +481,17 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, || ( BmRARE(check) == '\n' && (BmPREVIOUS(check) == SvCUR(check) - 1) && SvTAIL(check) )) - s = screaminstr(sv, check, + s = screaminstr(sv, check, start_shift + (s - strbeg), end_shift, pp, 0); else goto fail_finish; if (data) *data->scream_olds = s; } + else if (prog->reganch & ROPT_SANY_SEEN) + s = fbm_instr((U8*)(s + start_shift), + (U8*)(strend - end_shift), + check, PL_multiline ? FBMrf_MULTILINE : 0); else s = fbm_instr(HOP3(s, start_shift, strend), HOP3(strend, -end_shift, strbeg), @@ -597,14 +627,14 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, DEBUG_r(PerlIO_printf(Perl_debug_log, ", trying anchored starting at offset %ld...\n", (long)(s1 + 1 - i_strpos))); - other_last = last + 1; + 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 + 1; + other_last = s; /* Fix this later. --Hugo */ s = s1; if (t == strpos) goto try_at_start; @@ -640,7 +670,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, Thus we can arrive here only if check substr is float. Redo checking for "other"=="fixed". */ - strpos = t + 1; + strpos = t + 1; DEBUG_r(PerlIO_printf(Perl_debug_log, "Found /%s^%s/m at offset %ld, rescanning for anchored from offset %ld...\n", PL_colors[0],PL_colors[1], (long)(strpos - i_strpos), (long)(strpos - i_strpos + prog->anchored_offset))); goto do_other_anchored; @@ -747,7 +777,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, s = find_byclass(prog, prog->regstclass, s, endpos, startpos, 1); if (!s) { #ifdef DEBUGGING - char *what; + char *what = 0; #endif if (endpos == strend) { DEBUG_r( PerlIO_printf(Perl_debug_log, @@ -781,7 +811,7 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, if (t + start_shift >= check_at) /* Contradicts floating=check */ goto retry_floating_check; /* Recheck anchored substring, but not floating... */ - s = check_at; + s = check_at; if (!check) goto giveup; DEBUG_r( PerlIO_printf(Perl_debug_log, @@ -808,13 +838,17 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos, DEBUG_r( what = "floating" ); goto hop_and_restart; } - DEBUG_r( if (t != s) - PerlIO_printf(Perl_debug_log, + if (t != s) { + DEBUG_r(PerlIO_printf(Perl_debug_log, "By STCLASS: moving %ld --> %ld\n", - (long)(t - i_strpos), (long)(s - i_strpos)); - else - PerlIO_printf(Perl_debug_log, - "Does not contradict STCLASS...\n") ); + (long)(t - i_strpos), (long)(s - i_strpos)) + ); + } + else { + DEBUG_r(PerlIO_printf(Perl_debug_log, + "Does not contradict STCLASS...\n"); + ); + } } giveup: DEBUG_r(PerlIO_printf(Perl_debug_log, "%s%s:%s match at offset %ld\n", @@ -886,14 +920,14 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta STRLEN len; if (c1 == c2) while (s <= e) { - if ( utf8_to_uv_simple((U8*)s, &len) == c1 + if ( utf8_to_uvchr((U8*)s, &len) == c1 && regtry(prog, s) ) goto got_it; s += len; } else while (s <= e) { - UV c = utf8_to_uv_simple((U8*)s, &len); + UV c = utf8_to_uvchr((U8*)s, &len); if ( (c == c1 || c == c2) && regtry(prog, s) ) goto got_it; s += len; @@ -927,18 +961,20 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta /* FALL THROUGH */ case BOUND: if (do_utf8) { - if (s == startpos) + if (s == PL_bostr) tmp = '\n'; else { U8 *r = reghop3((U8*)s, -1, (U8*)startpos); - - tmp = (I32)utf8_to_uv(r, s - (char*)r, 0, 0); + + if (s > (char*)r) + tmp = (I32)utf8n_to_uvchr(r, s - (char*)r, 0, 0); } tmp = ((OP(c) == BOUND ? - isALNUM_uni(tmp) : isALNUM_LC_uni(tmp)) != 0); + isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0); + LOAD_UTF8_CHARCLASS(alnum,"a"); while (s < strend) { if (tmp == !(OP(c) == BOUND ? - swash_fetch(PL_utf8_alnum, (U8*)s) : + swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) : isALNUM_LC_utf8((U8*)s))) { tmp = !tmp; @@ -949,7 +985,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta } } else { - tmp = (s != startpos) ? UCHARAT(s - 1) : '\n'; + tmp = (s != PL_bostr) ? UCHARAT(s - 1) : '\n'; tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0); while (s < strend) { if (tmp == @@ -969,18 +1005,20 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta /* FALL THROUGH */ case NBOUND: if (do_utf8) { - if (s == startpos) + if (s == PL_bostr) tmp = '\n'; else { U8 *r = reghop3((U8*)s, -1, (U8*)startpos); - - tmp = (I32)utf8_to_uv(r, s - (char*)r, 0, 0); + + if (s > (char*)r) + tmp = (I32)utf8n_to_uvchr(r, s - (char*)r, 0, 0); } tmp = ((OP(c) == NBOUND ? - isALNUM_uni(tmp) : isALNUM_LC_uni(tmp)) != 0); + isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0); + LOAD_UTF8_CHARCLASS(alnum,"a"); while (s < strend) { if (tmp == !(OP(c) == NBOUND ? - swash_fetch(PL_utf8_alnum, (U8*)s) : + swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) : isALNUM_LC_utf8((U8*)s))) tmp = !tmp; else if ((norun || regtry(prog, s))) @@ -989,7 +1027,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta } } else { - tmp = (s != startpos) ? UCHARAT(s - 1) : '\n'; + tmp = (s != PL_bostr) ? UCHARAT(s - 1) : '\n'; tmp = ((OP(c) == NBOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0); while (s < strend) { @@ -1006,8 +1044,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case ALNUM: if (do_utf8) { + LOAD_UTF8_CHARCLASS(alnum,"a"); while (s < strend) { - if (swash_fetch(PL_utf8_alnum, (U8*)s)) { + if (swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8)) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1063,8 +1102,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case NALNUM: if (do_utf8) { + LOAD_UTF8_CHARCLASS(alnum,"a"); while (s < strend) { - if (!swash_fetch(PL_utf8_alnum, (U8*)s)) { + if (!swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8)) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1120,8 +1160,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case SPACE: if (do_utf8) { + LOAD_UTF8_CHARCLASS(space," "); while (s < strend) { - if (*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s)) { + if (*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8)) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1177,8 +1218,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case NSPACE: if (do_utf8) { + LOAD_UTF8_CHARCLASS(space," "); while (s < strend) { - if (!(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s))) { + if (!(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8))) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1234,8 +1276,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case DIGIT: if (do_utf8) { + LOAD_UTF8_CHARCLASS(digit,"0"); while (s < strend) { - if (swash_fetch(PL_utf8_digit,(U8*)s)) { + if (swash_fetch(PL_utf8_digit,(U8*)s, do_utf8)) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1291,8 +1334,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta break; case NDIGIT: if (do_utf8) { + LOAD_UTF8_CHARCLASS(digit,"0"); while (s < strend) { - if (!swash_fetch(PL_utf8_digit,(U8*)s)) { + if (!swash_fetch(PL_utf8_digit,(U8*)s, do_utf8)) { if (tmp && (norun || regtry(prog, s))) goto got_it; else @@ -1384,7 +1428,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * cache_re(prog); #ifdef DEBUGGING - PL_regnarrate = PL_debug & 512; + PL_regnarrate = DEBUG_r_TEST; #endif /* Be paranoid... */ @@ -1395,25 +1439,13 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * minlen = prog->minlen; if (do_utf8) { - if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey; + if (!(prog->reganch & ROPT_SANY_SEEN)) + if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey; } else { if (strend - startpos < minlen) goto phooey; } - if (startpos == strbeg) /* is ^ valid at stringarg? */ - PL_regprev = '\n'; - else { - if (prog->reganch & ROPT_UTF8 && do_utf8) { - U8 *s = reghop3((U8*)stringarg, -1, (U8*)strbeg); - PL_regprev = utf8_to_uv(s, (U8*)stringarg - s, NULL, 0); - } - else - PL_regprev = (U32)stringarg[-1]; - if (!PL_multiline && PL_regprev == '\n') - PL_regprev = '\0'; /* force ^ to NOT match */ - } - /* Check validity of program. */ if (UCHARAT(prog->program) != REG_MAGIC) { Perl_croak(aTHX_ "corrupted regexp program"); @@ -1450,7 +1482,8 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * PL_reg_ganch = startpos; else if (sv && SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) - && (mg = mg_find(sv, 'g')) && mg->mg_len >= 0) { + && (mg = mg_find(sv, PERL_MAGIC_regex_global)) + && mg->mg_len >= 0) { PL_reg_ganch = strbeg + mg->mg_len; /* Defined pos() */ if (prog->reganch & ROPT_ANCH_GPOS) { if (s > PL_reg_ganch) @@ -1462,7 +1495,8 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * PL_reg_ganch = strbeg; } - if (!(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) { + if (do_utf8 == (UTF!=0) && + !(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) { re_scream_pos_data d; d.scream_olds = &scream_olds; @@ -1535,7 +1569,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * } /* Messy cases: unanchored match. */ - if (prog->anchored_substr && prog->reganch & ROPT_SKIP) { + if (prog->anchored_substr && 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]; @@ -1567,20 +1601,21 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * s++; } } - DEBUG_r(did_match || + DEBUG_r(if (!did_match) PerlIO_printf(Perl_debug_log, - "Did not find anchored character...\n")); + "Did not find anchored character...\n") + ); } /*SUPPRESS 560*/ else if (do_utf8 == (UTF!=0) && (prog->anchored_substr != Nullsv - || (prog->float_substr != Nullsv + || (prog->float_substr != Nullsv && prog->float_max_offset < strend - s))) { - SV *must = prog->anchored_substr + SV *must = prog->anchored_substr ? prog->anchored_substr : prog->float_substr; - I32 back_max = + I32 back_max = prog->anchored_substr ? prog->anchored_offset : prog->float_max_offset; - I32 back_min = + 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) @@ -1601,11 +1636,11 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * dontbother = end_shift; strend = HOPc(strend, -dontbother); while ( (s <= last) && - ((flags & REXEC_SCREAM) + ((flags & REXEC_SCREAM) ? (s = screaminstr(sv, must, HOP3c(s, back_min, strend) - strbeg, end_shift, &scream_pos, 0)) : (s = fbm_instr((unsigned char*)HOP3(s, back_min, strend), - (unsigned char*)strend, must, + (unsigned char*)strend, must, PL_multiline ? FBMrf_MULTILINE : 0))) ) { DEBUG_r( did_match = 1 ); if (HOPc(s, -back_max) > last1) { @@ -1633,14 +1668,16 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * } } } - DEBUG_r(did_match || - PerlIO_printf(Perl_debug_log, "Did not find %s substr `%s%.*s%s'%s...\n", + DEBUG_r(if (!did_match) + PerlIO_printf(Perl_debug_log, + "Did not find %s substr `%s%.*s%s'%s...\n", ((must == prog->anchored_substr) ? "anchored" : "floating"), PL_colors[0], (int)(SvCUR(must) - (SvTAIL(must)!=0)), SvPVX(must), - PL_colors[1], (SvTAIL(must) ? "$" : ""))); + PL_colors[1], (SvTAIL(must) ? "$" : "")) + ); goto phooey; } else if ((c = prog->regstclass)) { @@ -1675,13 +1712,13 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char * if (memEQ(strend - len + 1, little, len - 1)) last = strend - len + 1; else if (!PL_multiline) - last = memEQ(strend - len, little, len) + last = memEQ(strend - len, little, len) ? strend - len : Nullch; else goto find_last; } else { find_last: - if (len) + if (len) last = rninstr(s, strend, little, little + len); else last = strend; /* matching `$' */ @@ -1750,7 +1787,7 @@ got_it: prog->sublen = PL_regeol - strbeg; /* strend may have been modified */ } } - + return 1; phooey: @@ -1799,11 +1836,12 @@ S_regtry(pTHX_ regexp *prog, char *startpos) DEFSV = PL_reg_sv; } - if (!(SvTYPE(PL_reg_sv) >= SVt_PVMG && SvMAGIC(PL_reg_sv) - && (mg = mg_find(PL_reg_sv, 'g')))) { + if (!(SvTYPE(PL_reg_sv) >= SVt_PVMG && SvMAGIC(PL_reg_sv) + && (mg = mg_find(PL_reg_sv, PERL_MAGIC_regex_global)))) { /* prepare for quick setting of pos */ - sv_magic(PL_reg_sv, (SV*)0, 'g', Nullch, 0); - mg = mg_find(PL_reg_sv, 'g'); + sv_magic(PL_reg_sv, (SV*)0, + PERL_MAGIC_regex_global, Nullch, 0); + mg = mg_find(PL_reg_sv, PERL_MAGIC_regex_global); mg->mg_len = -1; } PL_reg_magic = mg; @@ -1930,13 +1968,15 @@ S_regmatch(pTHX_ regnode *prog) register I32 nextchr; /* renamed nextchr - nextchar colides with function of same name */ register I32 n; /* no or next */ - register I32 ln; /* len or last */ - register char *s; /* operand or save */ + register I32 ln = 0; /* len or last */ + register char *s = Nullch; /* operand or save */ register char *locinput = PL_reginput; - register I32 c1, c2, paren; /* case fold search, parenth */ + register I32 c1 = 0, c2 = 0, paren; /* case fold search, parenth */ int minmod = 0, sw = 0, logical = 0; I32 unwind = 0; +#if 0 I32 firstcp = PL_savestack_ix; +#endif register bool do_utf8 = DO_UTF8(PL_reg_sv); #ifdef DEBUGGING @@ -1977,7 +2017,7 @@ S_regmatch(pTHX_ regnode *prog) after the current position the third one. We assume that pref0_len <= pref_len, otherwise we decrease pref0_len. */ - int pref_len = (locinput - PL_bostr) > (5 + taill) - l + int pref_len = (locinput - PL_bostr) > (5 + taill) - l ? (5 + taill) - l : locinput - PL_bostr; int pref0_len; @@ -1985,7 +2025,7 @@ S_regmatch(pTHX_ regnode *prog) pref_len++; pref0_len = pref_len - (locinput - PL_reg_starttry); if (l + pref_len < (5 + taill) && l < PL_regeol - locinput) - l = ( PL_regeol - locinput > (5 + taill) - pref_len + l = ( PL_regeol - locinput > (5 + taill) - pref_len ? (5 + taill) - pref_len : PL_regeol - locinput); while (UTF8_IS_CONTINUATION(*(U8*)(locinput + l))) l--; @@ -1994,12 +2034,12 @@ S_regmatch(pTHX_ regnode *prog) if (pref0_len > pref_len) pref0_len = pref_len; regprop(prop, scan); - PerlIO_printf(Perl_debug_log, + PerlIO_printf(Perl_debug_log, "%4"IVdf" <%s%.*s%s%s%.*s%s%s%s%.*s%s>%*s|%3"IVdf":%*s%s\n", - (IV)(locinput - PL_bostr), - PL_colors[4], pref0_len, + (IV)(locinput - PL_bostr), + PL_colors[4], pref0_len, locinput - pref_len, PL_colors[5], - PL_colors[2], pref_len - pref0_len, + PL_colors[2], pref_len - pref0_len, locinput - pref_len + pref0_len, PL_colors[3], (docolor ? "" : "> <"), PL_colors[0], l, locinput, PL_colors[1], @@ -2015,19 +2055,16 @@ S_regmatch(pTHX_ regnode *prog) switch (OP(scan)) { case BOL: - if (locinput == PL_bostr - ? PL_regprev == '\n' - : (PL_multiline && - (nextchr || locinput < PL_regeol) && locinput[-1] == '\n') ) + if (locinput == PL_bostr || (PL_multiline && + (nextchr || locinput < PL_regeol) && locinput[-1] == '\n') ) { /* regtill = regbol; */ break; } sayNO; case MBOL: - if (locinput == PL_bostr - ? PL_regprev == '\n' - : ((nextchr || locinput < PL_regeol) && locinput[-1] == '\n') ) + if (locinput == PL_bostr || + ((nextchr || locinput < PL_regeol) && locinput[-1] == '\n')) { break; } @@ -2062,13 +2099,6 @@ S_regmatch(pTHX_ regnode *prog) sayNO; break; case SANY: - if (do_utf8) { - locinput += PL_utf8skip[nextchr]; - if (locinput > PL_regeol) - sayNO; - nextchr = UCHARAT(locinput); - break; - } if (!nextchr && locinput >= PL_regeol) sayNO; nextchr = UCHARAT(++locinput); @@ -2096,7 +2126,7 @@ S_regmatch(pTHX_ regnode *prog) while (s < e) { if (l >= PL_regeol) sayNO; - if (*((U8*)s) != utf8_to_uv_simple((U8*)l, &len)) + if (*((U8*)s) != utf8_to_uvchr((U8*)l, &len)) sayNO; s++; l += len; @@ -2105,7 +2135,7 @@ S_regmatch(pTHX_ regnode *prog) while (s < e) { if (l >= PL_regeol) sayNO; - if (*((U8*)l) != utf8_to_uv_simple((U8*)s, &len)) + if (*((U8*)l) != utf8_to_uvchr((U8*)s, &len)) sayNO; s += len; l++; @@ -2140,7 +2170,7 @@ S_regmatch(pTHX_ regnode *prog) if (l >= PL_regeol) { sayNO; } - if ((UTF ? utf8_to_uv((U8*)s, e - s, 0, 0) : *((U8*)s)) != + if ((UTF ? utf8n_to_uvchr((U8*)s, e - s, 0, 0) : *((U8*)s)) != (c1 ? toLOWER_utf8((U8*)l) : toLOWER_LC_utf8((U8*)l))) sayNO; s += UTF ? UTF8SKIP(s) : 1; @@ -2191,8 +2221,9 @@ S_regmatch(pTHX_ regnode *prog) if (!nextchr) sayNO; if (do_utf8) { + LOAD_UTF8_CHARCLASS(alnum,"a"); if (!(OP(scan) == ALNUM - ? swash_fetch(PL_utf8_alnum, (U8*)locinput) + ? swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8) : isALNUM_LC_utf8((U8*)locinput))) { sayNO; @@ -2213,8 +2244,9 @@ S_regmatch(pTHX_ regnode *prog) if (!nextchr && locinput >= PL_regeol) sayNO; if (do_utf8) { + LOAD_UTF8_CHARCLASS(alnum,"a"); if (OP(scan) == NALNUM - ? swash_fetch(PL_utf8_alnum, (U8*)locinput) + ? swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8) : isALNUM_LC_utf8((U8*)locinput)) { sayNO; @@ -2236,25 +2268,26 @@ S_regmatch(pTHX_ regnode *prog) case NBOUND: /* was last char in word? */ if (do_utf8) { - if (locinput == PL_regbol) - ln = PL_regprev; + if (locinput == PL_bostr) + ln = '\n'; else { U8 *r = reghop((U8*)locinput, -1); - - ln = utf8_to_uv(r, s - (char*)r, 0, 0); + + ln = utf8n_to_uvchr(r, s - (char*)r, 0, 0); } if (OP(scan) == BOUND || OP(scan) == NBOUND) { ln = isALNUM_uni(ln); - n = swash_fetch(PL_utf8_alnum, (U8*)locinput); + LOAD_UTF8_CHARCLASS(alnum,"a"); + n = swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8); } else { - ln = isALNUM_LC_uni(ln); + ln = isALNUM_LC_uvchr(UNI_TO_NATIVE(ln)); n = isALNUM_LC_utf8((U8*)locinput); } } else { - ln = (locinput != PL_regbol) ? - UCHARAT(locinput - 1) : PL_regprev; + ln = (locinput != PL_bostr) ? + UCHARAT(locinput - 1) : '\n'; if (OP(scan) == BOUND || OP(scan) == NBOUND) { ln = isALNUM(ln); n = isALNUM(nextchr); @@ -2276,8 +2309,9 @@ S_regmatch(pTHX_ regnode *prog) sayNO; if (do_utf8) { if (UTF8_IS_CONTINUED(nextchr)) { + LOAD_UTF8_CHARCLASS(space," "); if (!(OP(scan) == SPACE - ? swash_fetch(PL_utf8_space, (U8*)locinput) + ? swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8) : isSPACE_LC_utf8((U8*)locinput))) { sayNO; @@ -2305,8 +2339,9 @@ S_regmatch(pTHX_ regnode *prog) if (!nextchr && locinput >= PL_regeol) sayNO; if (do_utf8) { + LOAD_UTF8_CHARCLASS(space," "); if (OP(scan) == NSPACE - ? swash_fetch(PL_utf8_space, (U8*)locinput) + ? swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8) : isSPACE_LC_utf8((U8*)locinput)) { sayNO; @@ -2327,8 +2362,9 @@ S_regmatch(pTHX_ regnode *prog) if (!nextchr) sayNO; if (do_utf8) { + LOAD_UTF8_CHARCLASS(digit,"0"); if (!(OP(scan) == DIGIT - ? swash_fetch(PL_utf8_digit, (U8*)locinput) + ? swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8) : isDIGIT_LC_utf8((U8*)locinput))) { sayNO; @@ -2349,8 +2385,9 @@ S_regmatch(pTHX_ regnode *prog) if (!nextchr && locinput >= PL_regeol) sayNO; if (do_utf8) { + LOAD_UTF8_CHARCLASS(digit,"0"); if (OP(scan) == NDIGIT - ? swash_fetch(PL_utf8_digit, (U8*)locinput) + ? swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8) : isDIGIT_LC_utf8((U8*)locinput)) { sayNO; @@ -2365,10 +2402,13 @@ S_regmatch(pTHX_ regnode *prog) nextchr = UCHARAT(++locinput); break; case CLUMP: - if (locinput >= PL_regeol || swash_fetch(PL_utf8_mark,(U8*)locinput)) + LOAD_UTF8_CHARCLASS(mark,"~"); + if (locinput >= PL_regeol || + swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8)) sayNO; locinput += PL_utf8skip[nextchr]; - while (locinput < PL_regeol && swash_fetch(PL_utf8_mark,(U8*)locinput)) + while (locinput < PL_regeol && + swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8)) locinput += UTF8SKIP(locinput); if (locinput > PL_regeol) sayNO; @@ -2452,7 +2492,7 @@ S_regmatch(pTHX_ regnode *prog) COP *ocurcop = PL_curcop; SV **ocurpad = PL_curpad; SV *ret; - + n = ARG(scan); PL_op = (OP_4tree*)PL_regdata->data[n]; DEBUG_r( PerlIO_printf(Perl_debug_log, " re_eval 0x%"UVxf"\n", PTR2UV(PL_op)) ); @@ -2463,7 +2503,7 @@ S_regmatch(pTHX_ regnode *prog) SPAGAIN; ret = POPs; PUTBACK; - + PL_op = oop; PL_curpad = ocurpad; PL_curcop = ocurcop; @@ -2478,7 +2518,7 @@ S_regmatch(pTHX_ regnode *prog) SV *sv = SvROK(ret) ? SvRV(ret) : ret; if(SvMAGICAL(sv)) - mg = mg_find(sv, 'r'); + mg = mg_find(sv, PERL_MAGIC_qr); } if (mg) { re = (regexp *)mg->mg_obj; @@ -2492,17 +2532,18 @@ S_regmatch(pTHX_ regnode *prog) I32 osize = PL_regsize; I32 onpar = PL_regnpar; - pm.op_pmflags = 0; + Zero(&pm, 1, PMOP); re = CALLREGCOMP(aTHX_ t, t + len, &pm); - if (!(SvFLAGS(ret) + if (!(SvFLAGS(ret) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY))) - sv_magic(ret,(SV*)ReREFCNT_inc(re),'r',0,0); + sv_magic(ret,(SV*)ReREFCNT_inc(re), + PERL_MAGIC_qr,0,0); PL_regprecomp = oprecomp; PL_regsize = osize; PL_regnpar = onpar; } DEBUG_r( - PerlIO_printf(Perl_debug_log, + PerlIO_printf(Perl_debug_log, "Entering embedded `%s%.60s%s%s'\n", PL_colors[0], re->precomp, @@ -2515,7 +2556,7 @@ S_regmatch(pTHX_ regnode *prog) state.re = PL_reg_re; PL_regcc = 0; - + cp = regcppush(0); /* Save *all* the positions. */ REGCP_SET(lastcp); cache_re(re); @@ -2604,7 +2645,7 @@ S_regmatch(pTHX_ regnode *prog) 1) After matching X, regnode for CURLYX is processed; - 2) This regnode creates infoblock on the stack, and calls + 2) This regnode creates infoblock on the stack, and calls regmatch() recursively with the starting point at WHILEM node; 3) Each hit of WHILEM node tries to match A and Z (in the order @@ -2625,7 +2666,7 @@ S_regmatch(pTHX_ regnode *prog) and whatever it mentions via ->next, and additional attached trees corresponding to temporarily unset infoblocks as in "5" above. - In the following picture infoblocks for outer loop of + In the following picture infoblocks for outer loop of (Y(A)*?Z)*?T are denoted O, for inner I. NULL starting block is denoted by x. The matched string is YAAZYAZT. Temporarily postponed infoblocks are drawn below the "reset" infoblock. @@ -2718,10 +2759,10 @@ S_regmatch(pTHX_ regnode *prog) PL_reginput = locinput; DEBUG_r( - PerlIO_printf(Perl_debug_log, - "%*s %ld out of %ld..%ld cc=%lx\n", + PerlIO_printf(Perl_debug_log, + "%*s %ld out of %ld..%ld cc=%lx\n", REPORT_CODE_OFF+PL_regindent*2, "", - (long)n, (long)cc->min, + (long)n, (long)cc->min, (long)cc->max, (long)cc) ); @@ -2820,7 +2861,7 @@ S_regmatch(pTHX_ regnode *prog) PL_regcc = cc; if (n >= cc->max) { /* Maximum greed exceeded? */ - if (ckWARN(WARN_REGEXP) && n >= REG_INFTY + if (ckWARN(WARN_REGEXP) && n >= REG_INFTY && !(PL_reg_flags & RF_warned)) { PL_reg_flags |= RF_warned; Perl_warner(aTHX_ WARN_REGEXP, "%s limit (%d) exceeded", @@ -2872,7 +2913,7 @@ S_regmatch(pTHX_ regnode *prog) REPORT_CODE_OFF+PL_regindent*2, "") ); } - if (ckWARN(WARN_REGEXP) && n >= REG_INFTY + if (ckWARN(WARN_REGEXP) && n >= REG_INFTY && !(PL_reg_flags & RF_warned)) { PL_reg_flags |= RF_warned; Perl_warner(aTHX_ WARN_REGEXP, "%s limit (%d) exceeded", @@ -2894,17 +2935,16 @@ S_regmatch(pTHX_ regnode *prog) sayNO; } /* NOT REACHED */ - case BRANCHJ: + case BRANCHJ: next = scan + ARG(scan); if (next == scan) next = NULL; inner = NEXTOPER(NEXTOPER(scan)); goto do_branch; - case BRANCH: + case BRANCH: inner = NEXTOPER(scan); do_branch: { - CHECKPOINT lastcp; c1 = OP(scan); if (OP(next) != c1) /* No choice. */ next = inner; /* Avoid recursion. */ @@ -2943,7 +2983,7 @@ S_regmatch(pTHX_ regnode *prog) { I32 l = 0; CHECKPOINT lastcp; - + /* We suppose that the next guy does not need backtracking: in particular, it is of constant length, and has no parenths to influence future backrefs. */ @@ -3121,7 +3161,7 @@ S_regmatch(pTHX_ regnode *prog) c2 = to_utf8_upper(s); } else { - c2 = c1 = utf8_to_uv_simple(s, NULL); + c2 = c1 = utf8_to_uvchr(s, NULL); } } } @@ -3164,7 +3204,7 @@ S_regmatch(pTHX_ regnode *prog) while (locinput <= e && *locinput != c1) locinput++; } else { - while (locinput <= e + while (locinput <= e && *locinput != c1 && *locinput != c2) locinput++; @@ -3176,20 +3216,20 @@ S_regmatch(pTHX_ regnode *prog) if (c1 == c2) { for (count = 0; locinput <= e && - utf8_to_uv_simple((U8*)locinput, &len) != c1; + utf8_to_uvchr((U8*)locinput, &len) != c1; count++) locinput += len; } else { for (count = 0; locinput <= e; count++) { - UV c = utf8_to_uv_simple((U8*)locinput, &len); + UV c = utf8_to_uvchr((U8*)locinput, &len); if (c == c1 || c == c2) break; - locinput += len; + locinput += len; } } } - if (locinput > e) + if (locinput > e) sayNO; /* PL_reginput == old now */ if (locinput != old) { @@ -3214,12 +3254,18 @@ S_regmatch(pTHX_ regnode *prog) UV c; if (c1 != -1000) { if (do_utf8) - c = utf8_to_uv_simple((U8*)PL_reginput, NULL); + c = utf8_to_uvchr((U8*)PL_reginput, NULL); else - c = UCHARAT(PL_reginput); + c = UCHARAT(PL_reginput); + /* If it could work, try it. */ + if (c == c1 || c == c2) + { + TRYPAREN(paren, n, PL_reginput); + REGCP_UNWIND(lastcp); + } } /* If it could work, try it. */ - if (c1 == -1000 || c == c1 || c == c2) + else if (c1 == -1000) { TRYPAREN(paren, n, PL_reginput); REGCP_UNWIND(lastcp); @@ -3249,13 +3295,13 @@ S_regmatch(pTHX_ regnode *prog) } REGCP_SET(lastcp); if (paren) { - UV c; + UV c = 0; while (n >= ln) { if (c1 != -1000) { if (do_utf8) - c = utf8_to_uv_simple((U8*)PL_reginput, NULL); + c = utf8_to_uvchr((U8*)PL_reginput, NULL); else - c = UCHARAT(PL_reginput); + c = UCHARAT(PL_reginput); } /* If it could work, try it. */ if (c1 == -1000 || c == c1 || c == c2) @@ -3269,13 +3315,13 @@ S_regmatch(pTHX_ regnode *prog) } } else { - UV c; + UV c = 0; while (n >= ln) { if (c1 != -1000) { if (do_utf8) - c = utf8_to_uv_simple((U8*)PL_reginput, NULL); + c = utf8_to_uvchr((U8*)PL_reginput, NULL); else - c = UCHARAT(PL_reginput); + c = UCHARAT(PL_reginput); } /* If it could work, try it. */ if (c1 == -1000 || c == c1 || c == c2) @@ -3343,24 +3389,14 @@ S_regmatch(pTHX_ regnode *prog) case SUSPEND: n = 1; PL_reginput = locinput; - goto do_ifmatch; + goto do_ifmatch; case UNLESSM: n = 0; if (scan->flags) { - if (UTF) { /* XXXX This is absolutely - broken, we read before - start of string. */ - s = HOPMAYBEc(locinput, -scan->flags); - if (!s) - goto say_yes; - PL_reginput = s; - } - else { - if (locinput < PL_bostr + scan->flags) - goto say_yes; - PL_reginput = locinput - scan->flags; - goto do_ifmatch; - } + s = HOPBACKc(locinput, scan->flags); + if (!s) + goto say_yes; + PL_reginput = s; } else PL_reginput = locinput; @@ -3368,20 +3404,10 @@ S_regmatch(pTHX_ regnode *prog) case IFMATCH: n = 1; if (scan->flags) { - if (UTF) { /* XXXX This is absolutely - broken, we read before - start of string. */ - s = HOPMAYBEc(locinput, -scan->flags); - if (!s || s < PL_bostr) - goto say_no; - PL_reginput = s; - } - else { - if (locinput < PL_bostr + scan->flags) - goto say_no; - PL_reginput = locinput - scan->flags; - goto do_ifmatch; - } + s = HOPBACKc(locinput, scan->flags); + if (!s) + goto say_no; + PL_reginput = s; } else PL_reginput = locinput; @@ -3470,14 +3496,14 @@ do_no: { re_unwind_branch_t *uwb = &(uw->branch); I32 lastparen = uwb->lastparen; - + REGCP_UNWIND(uwb->lastcp); for (n = *PL_reglastparen; n > lastparen; n--) PL_regendp[n] = -1; *PL_reglastparen = n; scan = next = uwb->next; - if ( !scan || - OP(scan) != (uwb->type == RE_UNWIND_BRANCH + if ( !scan || + OP(scan) != (uwb->type == RE_UNWIND_BRANCH ? BRANCH : BRANCHJ) ) { /* Failure */ unwind = uwb->prev; #ifdef DEBUGGING @@ -3550,15 +3576,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max) } break; case SANY: - if (do_utf8) { - loceol = PL_regeol; - while (hardcount < max && scan < loceol) { - scan += UTF8SKIP(scan); - hardcount++; - } - } else { - scan = loceol; - } + scan = loceol; break; case EXACT: /* length of string is 1 */ c = (U8)*STRING(p); @@ -3594,8 +3612,9 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case ALNUM: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(alnum,"a"); while (hardcount < max && scan < loceol && - swash_fetch(PL_utf8_alnum, (U8*)scan)) { + swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) { scan += UTF8SKIP(scan); hardcount++; } @@ -3621,8 +3640,9 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case NALNUM: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(alnum,"a"); while (hardcount < max && scan < loceol && - !swash_fetch(PL_utf8_alnum, (U8*)scan)) { + !swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) { scan += UTF8SKIP(scan); hardcount++; } @@ -3648,8 +3668,10 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case SPACE: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(space," "); while (hardcount < max && scan < loceol && - (*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) { + (*scan == ' ' || + swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) { scan += UTF8SKIP(scan); hardcount++; } @@ -3675,8 +3697,10 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case NSPACE: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(space," "); while (hardcount < max && scan < loceol && - !(*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) { + !(*scan == ' ' || + swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) { scan += UTF8SKIP(scan); hardcount++; } @@ -3702,8 +3726,9 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case DIGIT: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(digit,"0"); while (hardcount < max && scan < loceol && - swash_fetch(PL_utf8_digit,(U8*)scan)) { + swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) { scan += UTF8SKIP(scan); hardcount++; } @@ -3715,8 +3740,9 @@ S_regrepeat(pTHX_ regnode *p, I32 max) case NDIGIT: if (do_utf8) { loceol = PL_regeol; + LOAD_UTF8_CHARCLASS(digit,"0"); while (hardcount < max && scan < loceol && - !swash_fetch(PL_utf8_digit,(U8*)scan)) { + !swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) { scan += UTF8SKIP(scan); hardcount++; } @@ -3735,29 +3761,29 @@ S_regrepeat(pTHX_ regnode *p, I32 max) c = scan - PL_reginput; PL_reginput = scan; - DEBUG_r( + DEBUG_r( { SV *prop = sv_newmortal(); regprop(prop, p); - PerlIO_printf(Perl_debug_log, - "%*s %s can match %"IVdf" times out of %"IVdf"...\n", + PerlIO_printf(Perl_debug_log, + "%*s %s can match %"IVdf" times out of %"IVdf"...\n", REPORT_CODE_OFF+1, "", SvPVX(prop),(IV)c,(IV)max); }); - + return(c); } /* - regrepeat_hard - repeatedly match something, report total lenth and length - * + * * The repeater is supposed to have constant length. */ STATIC I32 S_regrepeat_hard(pTHX_ regnode *p, I32 max, I32 *lp) { - register char *scan; + register char *scan = Nullch; register char *start; register char *loceol = PL_regeol; I32 l = 0; @@ -3796,7 +3822,7 @@ S_regrepeat_hard(pTHX_ regnode *p, I32 max, I32 *lp) } if (!res) PL_reginput = scan; - + return count; } @@ -3817,10 +3843,10 @@ Perl_regclass_swash(pTHX_ register regnode* node, bool doinit, SV** initsvp) SV *rv = (SV*)PL_regdata->data[n]; AV *av = (AV*)SvRV((SV*)rv); SV **a; - + si = *av_fetch(av, 0, FALSE); a = av_fetch(av, 1, FALSE); - + if (a) sw = *a; else if (si && doinit) { @@ -3846,36 +3872,33 @@ S_reginclass(pTHX_ register regnode *n, register U8* p, register bool do_utf8) char flags = ANYOF_FLAGS(n); bool match = FALSE; UV c; - STRLEN len; + STRLEN len = 0; - if (do_utf8) - c = utf8_to_uv_simple(p, &len); - else - c = *p; + c = do_utf8 ? utf8_to_uvchr(p, &len) : *p; if (do_utf8 || (flags & ANYOF_UNICODE)) { if (do_utf8 && !ANYOF_RUNTIME(n)) { if (len != (STRLEN)-1 && c < 256 && ANYOF_BITMAP_TEST(n, c)) match = TRUE; } - if (do_utf8 && flags & ANYOF_UNICODE_ALL && c >= 256) + if (!match && do_utf8 && (flags & ANYOF_UNICODE_ALL) && c >= 256) match = TRUE; if (!match) { SV *sw = regclass_swash(n, TRUE, 0); if (sw) { - if (swash_fetch(sw, p)) + if (swash_fetch(sw, p, do_utf8)) match = TRUE; else if (flags & ANYOF_FOLD) { U8 tmpbuf[UTF8_MAXLEN+1]; - + if (flags & ANYOF_LOCALE) { PL_reg_flags |= RF_tainted; - uv_to_utf8(tmpbuf, toLOWER_LC_utf8(p)); + uvchr_to_utf8(tmpbuf, toLOWER_LC_utf8(p)); } else - uv_to_utf8(tmpbuf, toLOWER_utf8(p)); - if (swash_fetch(sw, tmpbuf)) + uvchr_to_utf8(tmpbuf, toLOWER_utf8(p)); + if (swash_fetch(sw, tmpbuf, do_utf8)) match = TRUE; } } @@ -3885,7 +3908,7 @@ S_reginclass(pTHX_ register regnode *n, register U8* p, register bool do_utf8) if (ANYOF_BITMAP_TEST(n, c)) match = TRUE; else if (flags & ANYOF_FOLD) { - I32 f; + I32 f; if (flags & ANYOF_LOCALE) { PL_reg_flags |= RF_tainted; @@ -3942,13 +3965,13 @@ S_reginclass(pTHX_ register regnode *n, register U8* p, register bool do_utf8) STATIC U8 * S_reghop(pTHX_ U8 *s, I32 off) -{ +{ return S_reghop3(aTHX_ s, off, (U8*)(off >= 0 ? PL_regeol : PL_bostr)); } STATIC U8 * S_reghop3(pTHX_ U8 *s, I32 off, U8* lim) -{ +{ if (off >= 0) { while (off-- && s < lim) { /* XXX could check well-formedness here */ @@ -3972,7 +3995,7 @@ S_reghop3(pTHX_ U8 *s, I32 off, U8* lim) STATIC U8 * S_reghopmaybe(pTHX_ U8 *s, I32 off) -{ +{ return S_reghopmaybe3(aTHX_ s, off, (U8*)(off >= 0 ? PL_regeol : PL_bostr)); }