X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/ce12e2548182b5bf6788188c520311eef0eca0ca..7c93a4714664dfc1aed62ada328290af9eba350a:/regexp.h diff --git a/regexp.h b/regexp.h index 78aa899..b22ada5 100644 --- a/regexp.h +++ b/regexp.h @@ -85,6 +85,14 @@ struct reg_code_block { REGEXP *src_regex; }; +/* array of reg_code_block's plus header info */ + +struct reg_code_blocks { + int refcnt; /* we may be pointed to from a regex and from the savestack */ + int count; /* how many code blocks */ + struct reg_code_block *cb; /* array of reg_code_block's */ +}; + /* The regexp/REGEXP struct, see L for further documentation @@ -262,7 +270,7 @@ and check for NULL. */ #define SvRX(sv) (Perl_get_re_arg(aTHX_ sv)) -#define SvRXOK(sv) (Perl_get_re_arg(aTHX_ sv) ? TRUE : FALSE) +#define SvRXOK(sv) cBOOL(Perl_get_re_arg(aTHX_ sv)) /* Flags stored in regexp->extflags @@ -278,25 +286,26 @@ and check for NULL. #include "op_reg_common.h" -#define RXf_PMf_STD_PMMOD (RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_FOLD|RXf_PMf_EXTENDED|RXf_PMf_NOCAPTURE) +#define RXf_PMf_STD_PMMOD (RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_FOLD|RXf_PMf_EXTENDED|RXf_PMf_EXTENDED_MORE|RXf_PMf_NOCAPTURE) #define CASE_STD_PMMOD_FLAGS_PARSE_SET(pmfl, x_count) \ case IGNORE_PAT_MOD: *(pmfl) |= RXf_PMf_FOLD; break; \ case MULTILINE_PAT_MOD: *(pmfl) |= RXf_PMf_MULTILINE; break; \ case SINGLE_PAT_MOD: *(pmfl) |= RXf_PMf_SINGLELINE; break; \ - case XTENDED_PAT_MOD: *(pmfl) |= RXf_PMf_EXTENDED; (x_count)++; break;\ + case XTENDED_PAT_MOD: if (x_count == 0) { \ + *(pmfl) |= RXf_PMf_EXTENDED; \ + *(pmfl) &= ~RXf_PMf_EXTENDED_MORE; \ + } \ + else { \ + *(pmfl) |= RXf_PMf_EXTENDED \ + |RXf_PMf_EXTENDED_MORE; \ + } \ + (x_count)++; break; \ case NOCAPTURE_PAT_MOD: *(pmfl) |= RXf_PMf_NOCAPTURE; break; -#define STD_PMMOD_FLAGS_PARSE_X_WARN(x_count) \ - if (UNLIKELY((x_count) > 1)) { \ - Perl_ck_warner_d(aTHX_ packWARN2(WARN_DEPRECATED, WARN_REGEXP), \ - "Having more than one /%c regexp modifier is deprecated", \ - XTENDED_PAT_MOD); \ - } - /* Note, includes charset ones, assumes 0 is the default for them */ #define STD_PMMOD_FLAGS_CLEAR(pmfl) \ - *(pmfl) &= ~(RXf_PMf_FOLD|RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_EXTENDED|RXf_PMf_CHARSET|RXf_PMf_NOCAPTURE) + *(pmfl) &= ~(RXf_PMf_FOLD|RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_EXTENDED|RXf_PMf_EXTENDED_MORE|RXf_PMf_CHARSET|RXf_PMf_NOCAPTURE) /* chars and strings used as regex pattern modifiers * Singular is a 'c'har, plural is a "string" @@ -358,9 +367,8 @@ and check for NULL. */ /* - Set in Perl_pmruntime if op_flags & OPf_SPECIAL, i.e. split. Will - be used by regex engines to check whether they should set - RXf_SKIPWHITE + Set in Perl_pmruntime for a split. Will be used by regex engines to + check whether they should set RXf_SKIPWHITE */ #define RXf_SPLIT RXf_PMf_SPLIT @@ -449,104 +457,126 @@ and check for NULL. */ #ifdef NO_TAINT_SUPPORT -# define RX_ISTAINTED(prog) 0 -# define RX_TAINT_on(prog) NOOP -# define RXp_MATCH_TAINTED(prog) 0 -# define RX_MATCH_TAINTED(prog) 0 -# define RXp_MATCH_TAINTED_on(prog) NOOP -# define RX_MATCH_TAINTED_on(prog) NOOP -# define RX_MATCH_TAINTED_off(prog) NOOP +# define RX_ISTAINTED(rx_sv) 0 +# define RXp_ISTAINTED(prog) 0 +# define RX_TAINT_on(rx_sv) NOOP +# define RXp_MATCH_TAINTED(prog) 0 +# define RX_MATCH_TAINTED(rx_sv) 0 +# define RXp_MATCH_TAINTED_on(prog) NOOP +# define RX_MATCH_TAINTED_on(rx_sv) NOOP +# define RX_MATCH_TAINTED_off(rx_sv) NOOP #else -# define RX_ISTAINTED(prog) (RX_EXTFLAGS(prog) & RXf_TAINTED) -# define RX_TAINT_on(prog) (RX_EXTFLAGS(prog) |= RXf_TAINTED) -# define RXp_MATCH_TAINTED(prog) (RXp_EXTFLAGS(prog) & RXf_TAINTED_SEEN) -# define RX_MATCH_TAINTED(prog) (RX_EXTFLAGS(prog) & RXf_TAINTED_SEEN) -# define RXp_MATCH_TAINTED_on(prog) (RXp_EXTFLAGS(prog) |= RXf_TAINTED_SEEN) -# define RX_MATCH_TAINTED_on(prog) (RX_EXTFLAGS(prog) |= RXf_TAINTED_SEEN) -# define RX_MATCH_TAINTED_off(prog) (RX_EXTFLAGS(prog) &= ~RXf_TAINTED_SEEN) +# define RX_ISTAINTED(rx_sv) (RX_EXTFLAGS(rx_sv) & RXf_TAINTED) +# define RXp_ISTAINTED(prog) (RXp_EXTFLAGS(prog) & RXf_TAINTED) +# define RX_TAINT_on(rx_sv) (RX_EXTFLAGS(rx_sv) |= RXf_TAINTED) +# define RXp_MATCH_TAINTED(prog) (RXp_EXTFLAGS(prog) & RXf_TAINTED_SEEN) +# define RX_MATCH_TAINTED(rx_sv) (RX_EXTFLAGS(rx_sv) & RXf_TAINTED_SEEN) +# define RXp_MATCH_TAINTED_on(prog) (RXp_EXTFLAGS(prog) |= RXf_TAINTED_SEEN) +# define RX_MATCH_TAINTED_on(rx_sv) (RX_EXTFLAGS(rx_sv) |= RXf_TAINTED_SEEN) +# define RXp_MATCH_TAINTED_off(prog) (RXp_EXTFLAGS(prog) &= ~RXf_TAINTED_SEEN) +# define RX_MATCH_TAINTED_off(rx_sv) (RX_EXTFLAGS(rx_sv) &= ~RXf_TAINTED_SEEN) #endif -#define RX_HAS_CUTGROUP(prog) ((prog)->intflags & PREGf_CUTGROUP_SEEN) -#define RX_MATCH_TAINTED_set(prog, t) ((t) \ - ? RX_MATCH_TAINTED_on(prog) \ - : RX_MATCH_TAINTED_off(prog)) +#define RXp_HAS_CUTGROUP(prog) ((prog)->intflags & PREGf_CUTGROUP_SEEN) + +#define RX_MATCH_TAINTED_set(rx_sv, t) ((t) \ + ? RX_MATCH_TAINTED_on(rx_sv) \ + : RX_MATCH_TAINTED_off(rx_sv)) -#define RXp_MATCH_COPIED(prog) (RXp_EXTFLAGS(prog) & RXf_COPY_DONE) -#define RX_MATCH_COPIED(prog) (RX_EXTFLAGS(prog) & RXf_COPY_DONE) -#define RXp_MATCH_COPIED_on(prog) (RXp_EXTFLAGS(prog) |= RXf_COPY_DONE) -#define RX_MATCH_COPIED_on(prog) (RX_EXTFLAGS(prog) |= RXf_COPY_DONE) -#define RXp_MATCH_COPIED_off(prog) (RXp_EXTFLAGS(prog) &= ~RXf_COPY_DONE) -#define RX_MATCH_COPIED_off(prog) (RX_EXTFLAGS(prog) &= ~RXf_COPY_DONE) -#define RX_MATCH_COPIED_set(prog,t) ((t) \ - ? RX_MATCH_COPIED_on(prog) \ - : RX_MATCH_COPIED_off(prog)) +#define RXp_MATCH_COPIED(prog) (RXp_EXTFLAGS(prog) & RXf_COPY_DONE) +#define RX_MATCH_COPIED(rx_sv) (RX_EXTFLAGS(rx_sv) & RXf_COPY_DONE) +#define RXp_MATCH_COPIED_on(prog) (RXp_EXTFLAGS(prog) |= RXf_COPY_DONE) +#define RX_MATCH_COPIED_on(rx_sv) (RX_EXTFLAGS(rx_sv) |= RXf_COPY_DONE) +#define RXp_MATCH_COPIED_off(prog) (RXp_EXTFLAGS(prog) &= ~RXf_COPY_DONE) +#define RX_MATCH_COPIED_off(rx_sv) (RX_EXTFLAGS(rx_sv) &= ~RXf_COPY_DONE) +#define RX_MATCH_COPIED_set(rx_sv,t) ((t) \ + ? RX_MATCH_COPIED_on(rx_sv) \ + : RX_MATCH_COPIED_off(rx_sv)) -#define RXp_EXTFLAGS(rx) ((rx)->extflags) -#define RXp_COMPFLAGS(rx) ((rx)->compflags) +#define RXp_EXTFLAGS(rx) ((rx)->extflags) +#define RXp_COMPFLAGS(rx) ((rx)->compflags) /* For source compatibility. We used to store these explicitly. */ -#define RX_PRECOMP(prog) (RX_WRAPPED(prog) + ReANY(prog)->pre_prefix) -#define RX_PRECOMP_const(prog) (RX_WRAPPED_const(prog) + ReANY(prog)->pre_prefix) +#define RX_PRECOMP(rx_sv) (RX_WRAPPED(rx_sv) \ + + ReANY(rx_sv)->pre_prefix) +#define RX_PRECOMP_const(rx_sv) (RX_WRAPPED_const(rx_sv) \ + + ReANY(rx_sv)->pre_prefix) /* FIXME? Are we hardcoding too much here and constraining plugin extension writers? Specifically, the value 1 assumes that the wrapped version always has exactly one character at the end, a ')'. Will that always be true? */ -#define RX_PRELEN(prog) (RX_WRAPLEN(prog) - ReANY(prog)->pre_prefix - 1) -#define RX_WRAPPED(prog) ReANY(prog)->xpv_len_u.xpvlenu_pv -#define RX_WRAPPED_const(prog) ((const char *)RX_WRAPPED(prog)) -#define RX_WRAPLEN(prog) SvCUR(prog) -#define RX_CHECK_SUBSTR(prog) (ReANY(prog)->check_substr) -#define RX_REFCNT(prog) SvREFCNT(prog) -#define RX_EXTFLAGS(prog) RXp_EXTFLAGS(ReANY(prog)) -#define RX_COMPFLAGS(prog) RXp_COMPFLAGS(ReANY(prog)) -#define RX_ENGINE(prog) (ReANY(prog)->engine) -#define RX_SUBBEG(prog) (ReANY(prog)->subbeg) -#define RX_SUBOFFSET(prog) (ReANY(prog)->suboffset) -#define RX_SUBCOFFSET(prog) (ReANY(prog)->subcoffset) -#define RX_OFFS(prog) (ReANY(prog)->offs) -#define RX_NPARENS(prog) (ReANY(prog)->nparens) -#define RX_SUBLEN(prog) (ReANY(prog)->sublen) -#define RX_MINLEN(prog) (ReANY(prog)->minlen) -#define RX_MINLENRET(prog) (ReANY(prog)->minlenret) -#define RX_GOFS(prog) (ReANY(prog)->gofs) -#define RX_LASTPAREN(prog) (ReANY(prog)->lastparen) -#define RX_LASTCLOSEPAREN(prog) (ReANY(prog)->lastcloseparen) -#define RX_SAVED_COPY(prog) (ReANY(prog)->saved_copy) +#define RX_PRELEN(rx_sv) (RX_WRAPLEN(rx_sv) \ + - ReANY(rx_sv)->pre_prefix - 1) + +#define RX_WRAPPED(rx_sv) SvPVX(rx_sv) +#define RX_WRAPPED_const(rx_sv) SvPVX_const(rx_sv) +#define RX_WRAPLEN(rx_sv) SvCUR(rx_sv) +#define RX_CHECK_SUBSTR(rx_sv) (ReANY(rx_sv)->check_substr) +#define RX_REFCNT(rx_sv) SvREFCNT(rx_sv) +#define RX_EXTFLAGS(rx_sv) RXp_EXTFLAGS(ReANY(rx_sv)) +#define RX_COMPFLAGS(rx_sv) RXp_COMPFLAGS(ReANY(rx_sv)) +#define RXp_ENGINE(prog) ((prog)->engine) +#define RX_ENGINE(rx_sv) (RXp_ENGINE(ReANY(rx_sv))) +#define RXp_SUBBEG(prog) (prog->subbeg) +#define RX_SUBBEG(rx_sv) (RXp_SUBBEG(ReANY(rx_sv))) +#define RXp_SUBOFFSET(prog) (prog->suboffset) +#define RX_SUBOFFSET(rx_sv) (RXp_SUBOFFSET(ReANY(rx_sv))) +#define RX_SUBCOFFSET(rx_sv) (ReANY(rx_sv)->subcoffset) +#define RXp_OFFS(prog) (prog->offs) +#define RX_OFFS(rx_sv) (RXp_OFFS(ReANY(rx_sv))) +#define RXp_NPARENS(prog) (prog->nparens) +#define RX_NPARENS(rx_sv) (RXp_NPARENS(ReANY(rx_sv))) +#define RX_SUBLEN(rx_sv) (ReANY(rx_sv)->sublen) +#define RXp_MINLEN(prog) (prog->minlen) +#define RX_MINLEN(rx_sv) (RXp_MINLEN(ReANY(rx_sv))) +#define RXp_MINLENRET(prog) (prog->minlenret) +#define RX_MINLENRET(rx_sv) (RXp_MINLENRET(ReANY(rx_sv))) +#define RXp_GOFS(prog) (prog->gofs) +#define RX_GOFS(rx_sv) (RXp_GOFS(ReANY(rx_sv))) +#define RX_LASTPAREN(rx_sv) (ReANY(rx_sv)->lastparen) +#define RX_LASTCLOSEPAREN(rx_sv) (ReANY(rx_sv)->lastcloseparen) +#define RXp_SAVED_COPY(prog) (prog->saved_copy) +#define RX_SAVED_COPY(rx_sv) (RXp_SAVED_COPY(ReANY(rx_sv))) /* last match was zero-length */ -#define RX_ZERO_LEN(prog) \ - (RX_OFFS(prog)[0].start + (SSize_t)RX_GOFS(prog) \ - == RX_OFFS(prog)[0].end) +#define RXp_ZERO_LEN(prog) \ + (RXp_OFFS(prog)[0].start + (SSize_t)RXp_GOFS(prog) \ + == RXp_OFFS(prog)[0].end) +#define RX_ZERO_LEN(rx_sv) (RXp_ZERO_LEN(ReANY(rx_sv))) #endif /* PLUGGABLE_RE_EXTENSION */ /* Stuff that needs to be included in the pluggable extension goes below here */ #ifdef PERL_ANY_COW -#define RX_MATCH_COPY_FREE(rx) \ - STMT_START {if (RX_SAVED_COPY(rx)) { \ - SV_CHECK_THINKFIRST_COW_DROP(RX_SAVED_COPY(rx)); \ +#define RXp_MATCH_COPY_FREE(prog) \ + STMT_START {if (RXp_SAVED_COPY(prog)) { \ + SV_CHECK_THINKFIRST_COW_DROP(RXp_SAVED_COPY(prog)); \ } \ - if (RX_MATCH_COPIED(rx)) { \ - Safefree(RX_SUBBEG(rx)); \ - RX_MATCH_COPIED_off(rx); \ + if (RXp_MATCH_COPIED(prog)) { \ + Safefree(RXp_SUBBEG(prog)); \ + RXp_MATCH_COPIED_off(prog); \ }} STMT_END #else -#define RX_MATCH_COPY_FREE(rx) \ - STMT_START {if (RX_MATCH_COPIED(rx)) { \ - Safefree(RX_SUBBEG(rx)); \ - RX_MATCH_COPIED_off(rx); \ +#define RXp_MATCH_COPY_FREE(prog) \ + STMT_START {if (RXp_MATCH_COPIED(prog)) { \ + Safefree(RXp_SUBBEG(prog)); \ + RXp_MATCH_COPIED_off(prog); \ }} STMT_END #endif - -#define RXp_MATCH_UTF8(prog) (RXp_EXTFLAGS(prog) & RXf_MATCH_UTF8) -#define RX_MATCH_UTF8(prog) (RX_EXTFLAGS(prog) & RXf_MATCH_UTF8) -#define RX_MATCH_UTF8_on(prog) (RX_EXTFLAGS(prog) |= RXf_MATCH_UTF8) -#define RX_MATCH_UTF8_off(prog) (RX_EXTFLAGS(prog) &= ~RXf_MATCH_UTF8) -#define RX_MATCH_UTF8_set(prog, t) ((t) \ - ? RX_MATCH_UTF8_on(prog) \ - : RX_MATCH_UTF8_off(prog)) +#define RX_MATCH_COPY_FREE(rx_sv) RXp_MATCH_COPY_FREE(ReANY(rx_sv)) + +#define RXp_MATCH_UTF8(prog) (RXp_EXTFLAGS(prog) & RXf_MATCH_UTF8) +#define RX_MATCH_UTF8(rx_sv) (RX_EXTFLAGS(rx_sv) & RXf_MATCH_UTF8) +#define RXp_MATCH_UTF8_on(prog) (RXp_EXTFLAGS(prog) |= RXf_MATCH_UTF8) +#define RX_MATCH_UTF8_on(rx_sv) (RXp_MATCH_UTF8_on(ReANY(rx_sv))) +#define RXp_MATCH_UTF8_off(prog) (RXp_EXTFLAGS(prog) &= ~RXf_MATCH_UTF8) +#define RX_MATCH_UTF8_off(rx_sv) (RXp_MATCH_UTF8_off(ReANY(rx_sv)) +#define RXp_MATCH_UTF8_set(prog, t) ((t) \ + ? RXp_MATCH_UTF8_on(prog) \ + : RXp_MATCH_UTF8_off(prog)) +#define RX_MATCH_UTF8_set(rx_sv, t) (RXp_MATCH_UTF8_set(ReANY(rx_sv), t)) /* Whether the pattern stored at RX_WRAPPED is in UTF-8 */ -#define RX_UTF8(prog) SvUTF8(prog) +#define RX_UTF8(rx_sv) SvUTF8(rx_sv) /* bits in flags arg of Perl_regexec_flags() */