#include "utf8.h"
+typedef SSize_t regnode_offset;
+
struct regnode {
U8 flags;
U8 type;
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<perlreapi> for further documentation
regexp's data array based on the data item's type.
*/
-#define _REGEXP_COMMON \
- /* what engine created this regexp? */ \
- const struct regexp_engine* engine; \
- REGEXP *mother_re; /* what re is this a lightweight copy of? */ \
- HV *paren_names; /* Optional hash of paren names */ \
- /* Information about the match that the perl core uses to */ \
- /* manage things */ \
- U32 extflags; /* Flags used both externally and internally */ \
- SSize_t minlen; /* mininum possible number of chars in string to match */\
- SSize_t minlenret; /* mininum possible number of chars in $& */ \
- STRLEN gofs; /* chars left of pos that we search from */ \
- /* substring data about strings that must appear in the */ \
- /* final match, used for optimisations */ \
- struct reg_substr_data *substrs; \
- U32 nparens; /* number of capture buffers */ \
- /* private engine specific data */ \
- U32 intflags; /* Engine Specific Internal flags */ \
- void *pprivate; /* Data private to the regex engine which */ \
- /* created this object. */ \
- /* Data about the last/current match. These are modified */ \
- /* during matching */ \
- U32 lastparen; /* last open paren matched */ \
- U32 lastcloseparen; /* last close paren matched */ \
- /* Array of offsets for (@-) and (@+) */ \
- regexp_paren_pair *offs; \
- /* saved or original string so \digit works forever. */ \
- char *subbeg; \
- SV_SAVED_COPY /* If non-NULL, SV which is COW from original */\
- SSize_t sublen; /* Length of string pointed by subbeg */ \
- SSize_t suboffset; /* byte offset of subbeg from logical start of str */ \
- SSize_t subcoffset; /* suboffset equiv, but in chars (for @-/@+) */ \
- /* Information about the match that isn't often used */ \
- SSize_t maxlen; /* mininum possible number of chars in string to match */\
- /* offset from wrapped to the start of precomp */ \
- PERL_BITFIELD32 pre_prefix:4; \
- /* original flags used to compile the pattern, may differ */ \
- /* from extflags in various ways */ \
- PERL_BITFIELD32 compflags:9; \
- CV *qr_anoncv /* the anon sub wrapped round qr/(?{..})/ */
-
typedef struct regexp {
- _XPV_HEAD;
- _REGEXP_COMMON;
+ _XPV_HEAD;
+ const struct regexp_engine* engine; /* what engine created this regexp? */
+ REGEXP *mother_re; /* what re is this a lightweight copy of? */
+ HV *paren_names; /* Optional hash of paren names */
+
+ /*----------------------------------------------------------------------
+ * Information about the match that the perl core uses to manage things
+ */
+
+ U32 extflags; /* Flags used both externally and internally */
+ U32 nparens; /* number of capture buffers */
+ SSize_t minlen; /* minimum possible number of chars in string to match */
+ SSize_t minlenret; /* mininum possible number of chars in $& */
+ STRLEN gofs; /* chars left of pos that we search from */
+ /* substring data about strings that must appear in
+ * the final match, used for optimisations */
+ struct reg_substr_data *substrs;
+
+ /* private engine specific data */
+
+ void *pprivate; /* Data private to the regex engine which
+ * created this object. */
+ U32 intflags; /* Engine Specific Internal flags */
+
+ /*----------------------------------------------------------------------
+ * Data about the last/current match. These are modified during matching
+ */
+
+ U32 lastparen; /* highest close paren matched ($+) */
+ regexp_paren_pair *offs; /* Array of offsets for (@-) and (@+) */
+ char **recurse_locinput; /* used to detect infinite recursion, XXX: move to internal */
+ U32 lastcloseparen; /* last close paren matched ($^N) */
+
+ /*---------------------------------------------------------------------- */
+
+ /* offset from wrapped to the start of precomp */
+ PERL_BITFIELD32 pre_prefix:4;
+
+ /* original flags used to compile the pattern, may differ from
+ * extflags in various ways */
+ PERL_BITFIELD32 compflags:9;
+
+ /*---------------------------------------------------------------------- */
+
+ char *subbeg; /* saved or original string so \digit works forever. */
+ SV_SAVED_COPY /* If non-NULL, SV which is COW from original */
+ SSize_t sublen; /* Length of string pointed by subbeg */
+ SSize_t suboffset; /* byte offset of subbeg from logical start of str */
+ SSize_t subcoffset; /* suboffset equiv, but in chars (for @-/@+) */
+ SSize_t maxlen; /* minimum possible number of chars in string to match */
+
+ /*---------------------------------------------------------------------- */
+
+
+ CV *qr_anoncv; /* the anon sub wrapped round qr/(?{..})/ */
} regexp;
+
#define RXp_PAREN_NAMES(rx) ((rx)->paren_names)
/* used for high speed searches */
const U32 flags,
re_scream_pos_data *data);
SV* (*checkstr) (pTHX_ REGEXP * const rx);
- void (*free) (pTHX_ REGEXP * const rx);
+ void (*rxfree) (pTHX_ REGEXP * const rx);
void (*numbered_buff_FETCH) (pTHX_ REGEXP * const rx, const I32 paren,
SV * const sv);
void (*numbered_buff_STORE) (pTHX_ REGEXP * const rx, const I32 paren,
#define RXapif_REGNAMES_COUNT 0x1000
/*
-=head1 REGEXP Functions
+=for apidoc_section REGEXP Functions
=for apidoc Am|REGEXP *|SvRX|SV *sv
if (SvTYPE(sv) == SVt_REGEXP)
return (REGEXP*) sv;
-NULL will be returned if a REGEXP* is not found.
+C<NULL> will be returned if a REGEXP* is not found.
=for apidoc Am|bool|SvRXOK|SV* sv
*/
#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
#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"
*/
/*
- 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
* For the regexp bits, PL_reg_extflags_name[] in regnodes.h has a comment
* giving which bits are used/unused */
-#define RXf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT + 3)
+#define RXf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT + 2)
/* What we have seen */
#define RXf_NO_INPLACE_SUBST (1U<<(RXf_BASE_SHIFT+2))
*/
#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 RXp_MATCH_TAINTED_off(prog) 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() */
the start pos (so s/.\G// would fail
on second iteration */
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#if defined(PERL_USE_GCC_BRACE_GROUPS)
# define ReREFCNT_inc(re) \
({ \
/* This is here to generate a casting warning if incorrect. */ \
# define ReREFCNT_dec(re) SvREFCNT_dec(re)
# define ReREFCNT_inc(re) ((REGEXP *) SvREFCNT_inc(re))
#endif
-#define ReANY(re) S_ReANY((const REGEXP *)(re))
+#define ReANY(re) Perl_ReANY((const REGEXP *)(re))
/* FIXME for plugins. */
STRLEN sublen; /* saved sublen field from rex */
STRLEN suboffset; /* saved suboffset field from rex */
STRLEN subcoffset; /* saved subcoffset field from rex */
+ SV *sv; /* $_ during (?{}) */
MAGIC *pos_magic; /* pos() magic attached to $_ */
SSize_t pos; /* the original value of pos() in pos_magic */
U8 pos_flags; /* flags to be restored; currently only MGf_BYTES*/
/* structures for holding and saving the state maintained by regmatch() */
#ifndef MAX_RECURSE_EVAL_NOCHANGE_DEPTH
-#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 1000
+#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 10
#endif
typedef I32 CHECKPOINT;
typedef struct regmatch_state {
int resume_state; /* where to jump to on return */
char *locinput; /* where to backtrack in string on failure */
+ char *loceol;
+ U8 *sr0; /* position of start of script run, or NULL */
union {
struct {
/* this first element must match u.yes */
struct regmatch_state *prev_yes_state;
- struct regmatch_state *prev_eval;
struct regmatch_state *prev_curlyx;
+ struct regmatch_state *prev_eval;
REGEXP *prev_rex;
CHECKPOINT cp; /* remember current savestack indexes */
CHECKPOINT lastcp;
- U32 close_paren; /* which close bracket is our end */
+ U32 close_paren; /* which close bracket is our end (+1) */
regnode *B; /* the node following us */
+ char *prev_recurse_locinput;
} eval;
struct {
struct regmatch_state *prev_yes_state;
I32 wanted;
I32 logical; /* saved copy of 'logical' var */
+ U8 count; /* number of beginning positions */
+ char *start;
+ char *end;
regnode *me; /* the IFMATCH/SUSPEND/UNLESSM node */
} ifmatch; /* and SUSPEND/UNLESSM */
} keeper;
/* quantifiers - these members are used for storing state for
- for the regops used to implement quantifiers */
+ the regops used to implement quantifiers */
struct {
/* this first element must match u.yes */
struct regmatch_state *prev_yes_state;
} u;
} regmatch_state;
+
+
/* how many regmatch_state structs to allocate as a single slab.
* We do it in 4K blocks for efficiency. The "3" is 2 for the next/prev
* pointers, plus 1 for any mythical malloc overhead. */
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/