struct regexp;
struct reg_substr_datum {
- I32 min_offset;
- I32 max_offset;
+ SSize_t min_offset; /* min pos (in chars) that substr must appear */
+ SSize_t max_offset /* max pos (in chars) that substr must appear */;
SV *substr; /* non-utf8 variant */
SV *utf8_substr; /* utf8 variant */
- I32 end_shift;
+ SSize_t end_shift; /* how many fixed chars must end the string */
};
struct reg_substr_data {
+ U8 check_ix; /* index into data[] of check substr */
struct reg_substr_datum data[3]; /* Actual array */
};
/* offsets within a string of a particular /(.)/ capture */
typedef struct regexp_paren_pair {
- I32 start;
- I32 end;
+ SSize_t start;
+ SSize_t end;
/* 'start_tmp' records a new opening position before the matching end
* has been found, so that the old start and end values are still
* valid, e.g.
* "abc" =~ /(.(?{print "[$1]"}))+/
*outputs [][a][b]
* This field is not part of the API. */
- I32 start_tmp;
+ SSize_t start_tmp;
} regexp_paren_pair;
#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_UTF8_C)
/* Information about the match that the perl core uses to */ \
/* manage things */ \
U32 extflags; /* Flags used both externally and internally */ \
- I32 minlen; /* mininum possible number of chars in string to match */\
- I32 minlenret; /* mininum possible number of chars in $& */ \
- U32 gofs; /* chars left of pos that we search from */ \
+ 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; \
/* saved or original string so \digit works forever. */ \
char *subbeg; \
SV_SAVED_COPY /* If non-NULL, SV which is COW from original */\
- I32 sublen; /* Length of string pointed by subbeg */ \
- I32 suboffset; /* byte offset of subbeg from logical start of str */ \
- I32 subcoffset; /* suboffset equiv, but in chars (for @-/@+) */ \
+ 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 */ \
typedef struct re_scream_pos_data_s
{
char **scream_olds; /* match pos */
- I32 *scream_pos; /* Internal iterator of scream. */
+ SSize_t *scream_pos; /* Internal iterator of scream. */
} re_scream_pos_data;
/* regexp_engine structure. This is the dispatch table for regexes.
typedef struct regexp_engine {
REGEXP* (*comp) (pTHX_ SV * const pattern, U32 flags);
I32 (*exec) (pTHX_ REGEXP * const rx, char* stringarg, char* strend,
- char* strbeg, I32 minend, SV* screamer,
+ char* strbeg, SSize_t minend, SV* sv,
void* data, U32 flags);
char* (*intuit) (pTHX_
REGEXP * const rx,
#endif
REGEXP* (*op_comp) (pTHX_ SV ** const patternp, int pat_count,
OP *expr, const struct regexp_engine* eng,
- REGEXP *VOL old_re,
+ REGEXP *old_re,
bool *is_bare_re, U32 orig_rx_flags, U32 pm_flags);
} regexp_engine;
=for apidoc Am|REGEXP *|SvRX|SV *sv
-Convenience macro to get the REGEXP from a SV. This is approximately
+Convenience macro to get the REGEXP from a SV. This is approximately
equivalent to the following snippet:
if (SvMAGICAL(sv))
#include "op_reg_common.h"
-#define RXf_PMf_STD_PMMOD (RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_FOLD|RXf_PMf_EXTENDED)
+#define RXf_PMf_STD_PMMOD (RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_FOLD|RXf_PMf_EXTENDED|RXf_PMf_NOCAPTURE)
-#define CASE_STD_PMMOD_FLAGS_PARSE_SET(pmfl) \
- 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; break
+#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 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)
+ *(pmfl) &= ~(RXf_PMf_FOLD|RXf_PMf_MULTILINE|RXf_PMf_SINGLELINE|RXf_PMf_EXTENDED|RXf_PMf_CHARSET|RXf_PMf_NOCAPTURE)
/* chars and strings used as regex pattern modifiers
* Singular is a 'c'har, plural is a "string"
#define DEFAULT_PAT_MOD '^' /* Short for all the default modifiers */
#define EXEC_PAT_MOD 'e'
#define KEEPCOPY_PAT_MOD 'p'
+#define NOCAPTURE_PAT_MOD 'n'
#define ONCE_PAT_MOD 'o'
#define GLOBAL_PAT_MOD 'g'
#define CONTINUE_PAT_MOD 'c'
#define ONCE_PAT_MODS "o"
#define KEEPCOPY_PAT_MODS "p"
+#define NOCAPTURE_PAT_MODS "n"
#define EXEC_PAT_MODS "e"
#define LOOP_PAT_MODS "gc"
#define NONDESTRUCT_PAT_MODS "r"
/* This string is expected by regcomp.c to be ordered so that the first
* character is the flag in bit RXf_PMf_STD_PMMOD_SHIFT of extflags; the next
* character is bit +1, etc. */
-#define STD_PAT_MODS "msix"
+#define STD_PAT_MODS "msixxn"
#define CHARSET_PAT_MODS ASCII_RESTRICT_PAT_MODS DEPENDS_PAT_MODS LOCALE_PAT_MODS UNICODE_PAT_MODS
* extflags; the next character is in bit +1, etc. */
#define INT_PAT_MODS STD_PAT_MODS KEEPCOPY_PAT_MODS
-#define EXT_PAT_MODS ONCE_PAT_MODS KEEPCOPY_PAT_MODS
+#define EXT_PAT_MODS ONCE_PAT_MODS KEEPCOPY_PAT_MODS NOCAPTURE_PAT_MODS
#define QR_PAT_MODS STD_PAT_MODS EXT_PAT_MODS CHARSET_PAT_MODS
#define M_PAT_MODS QR_PAT_MODS LOOP_PAT_MODS
#define S_PAT_MODS M_PAT_MODS EXEC_PAT_MODS NONDESTRUCT_PAT_MODS
*
*/
-/* Leave some space, so future bit allocations can go either in the shared or
- * unshared area without affecting binary compatibility */
-#define RXf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT)
-
/*
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
*/
-#define RXf_SPLIT (1<<(RXf_BASE_SHIFT-1))
-#if RXf_SPLIT != RXf_PMf_SPLIT
-# error "RXf_SPLIT does not match RXf_PMf_SPLIT"
-#endif
-
-/* Manually decorate this function with gcc-style attributes just to
- * avoid having to restructure the header files and their called order,
- * as proto.h would have to be included before this file, and isn't */
-
-PERL_STATIC_INLINE const char *
-get_regex_charset_name(const U32 flags, STRLEN* const lenp)
- __attribute__warn_unused_result__;
-
-#define MAX_CHARSET_NAME_LENGTH 2
+#define RXf_SPLIT RXf_PMf_SPLIT
+
+/* Currently the regex flags occupy a single 32-bit word. Not all bits are
+ * currently used. The lower bits are shared with their corresponding PMf flag
+ * bits, up to but not including _RXf_PMf_SHIFT_NEXT. The unused bits
+ * immediately follow; finally the used RXf-only (unshared) bits, so that the
+ * highest bit in the word is used. This gathers all the unused bits as a pool
+ * in the middle, like so: 11111111111111110000001111111111
+ * where the '1's represent used bits, and the '0's unused. This design allows
+ * us to allocate off one end of the pool if we need to add a shared bit, and
+ * off the other end if we need a non-shared bit, without disturbing the other
+ * bits. This maximizes the likelihood of being able to change things without
+ * breaking binary compatibility.
+ *
+ * To add shared bits, do so in op_reg_common.h. This should change
+ * _RXf_PMf_SHIFT_NEXT so that things won't compile. Then come to regexp.h and
+ * op.h and adjust the constant adders in the definitions of RXf_BASE_SHIFT and
+ * Pmf_BASE_SHIFT down by the number of shared bits you added. That's it.
+ * Things should be binary compatible. But if either of these gets to having
+ * to subtract rather than add, leave at 0 and instead adjust all the entries
+ * that are in terms of it. But if the first one of those is already
+ * RXf_BASE_SHIFT+0, there are no bits left, and a redesign is in order.
+ *
+ * To remove unshared bits, just delete its entry. If you're where breaking
+ * binary compatibility is ok to do, you might want to adjust things to move
+ * the newly opened space so that it gets absorbed into the common pool.
+ *
+ * To add unshared bits, first use up any gaps in the middle. Otherwise,
+ * allocate off the low end until you get to RXf_BASE_SHIFT+0. If that isn't
+ * enough, move RXf_BASE_SHIFT down (if possible) and add the new bit at the
+ * other end instead; this preserves binary compatibility.
+ *
+ * For the regexp bits, PL_reg_extflags_name[] in regnodes.h has a comment
+ * giving which bits are used/unused */
-PERL_STATIC_INLINE const char *
-get_regex_charset_name(const U32 flags, STRLEN* const lenp)
-{
- /* Returns a string that corresponds to the name of the regex character set
- * given by 'flags', and *lenp is set the length of that string, which
- * cannot exceed MAX_CHARSET_NAME_LENGTH characters */
-
- *lenp = 1;
- switch (get_regex_charset(flags)) {
- case REGEX_DEPENDS_CHARSET: return DEPENDS_PAT_MODS;
- case REGEX_LOCALE_CHARSET: return LOCALE_PAT_MODS;
- case REGEX_UNICODE_CHARSET: return UNICODE_PAT_MODS;
- case REGEX_ASCII_RESTRICTED_CHARSET: return ASCII_RESTRICT_PAT_MODS;
- case REGEX_ASCII_MORE_RESTRICTED_CHARSET:
- *lenp = 2;
- return ASCII_MORE_RESTRICT_PAT_MODS;
- default:
- return "?"; /* Unknown */
- }
-}
-
-/* Anchor and GPOS related stuff */
-#define RXf_ANCH_BOL (1<<(RXf_BASE_SHIFT+0))
-#define RXf_ANCH_MBOL (1<<(RXf_BASE_SHIFT+1))
-#define RXf_ANCH_SBOL (1<<(RXf_BASE_SHIFT+2))
-#define RXf_ANCH_GPOS (1<<(RXf_BASE_SHIFT+3))
-#define RXf_GPOS_SEEN (1<<(RXf_BASE_SHIFT+4))
-#define RXf_GPOS_FLOAT (1<<(RXf_BASE_SHIFT+5))
-/* two bits here */
-#define RXf_ANCH (RXf_ANCH_BOL|RXf_ANCH_MBOL|RXf_ANCH_GPOS|RXf_ANCH_SBOL)
-#define RXf_GPOS_CHECK (RXf_GPOS_SEEN|RXf_ANCH_GPOS)
-#define RXf_ANCH_SINGLE (RXf_ANCH_SBOL|RXf_ANCH_GPOS)
+#define RXf_BASE_SHIFT (_RXf_PMf_SHIFT_NEXT + 2)
/* What we have seen */
-#define RXf_NO_INPLACE_SUBST (1<<(RXf_BASE_SHIFT+6))
-#define RXf_EVAL_SEEN (1<<(RXf_BASE_SHIFT+7))
-#define RXf_CANY_SEEN (1<<(RXf_BASE_SHIFT+8))
+#define RXf_NO_INPLACE_SUBST (1U<<(RXf_BASE_SHIFT+2))
+#define RXf_EVAL_SEEN (1U<<(RXf_BASE_SHIFT+3))
/* Special */
-#define RXf_NOSCAN (1<<(RXf_BASE_SHIFT+9))
-#define RXf_CHECK_ALL (1<<(RXf_BASE_SHIFT+10))
+#define RXf_UNBOUNDED_QUANTIFIER_SEEN (1U<<(RXf_BASE_SHIFT+4))
+#define RXf_CHECK_ALL (1U<<(RXf_BASE_SHIFT+5))
/* UTF8 related */
-#define RXf_MATCH_UTF8 (1<<(RXf_BASE_SHIFT+11)) /* $1 etc are utf8 */
+#define RXf_MATCH_UTF8 (1U<<(RXf_BASE_SHIFT+6)) /* $1 etc are utf8 */
/* Intuit related */
-#define RXf_USE_INTUIT_NOML (1<<(RXf_BASE_SHIFT+12))
-#define RXf_USE_INTUIT_ML (1<<(RXf_BASE_SHIFT+13))
-#define RXf_INTUIT_TAIL (1<<(RXf_BASE_SHIFT+14))
+#define RXf_USE_INTUIT_NOML (1U<<(RXf_BASE_SHIFT+7))
+#define RXf_USE_INTUIT_ML (1U<<(RXf_BASE_SHIFT+8))
+#define RXf_INTUIT_TAIL (1U<<(RXf_BASE_SHIFT+9))
#define RXf_USE_INTUIT (RXf_USE_INTUIT_NOML|RXf_USE_INTUIT_ML)
+/* Do we have some sort of anchor? */
+#define RXf_IS_ANCHORED (1U<<(RXf_BASE_SHIFT+10))
+
/* Copy and tainted info */
-#define RXf_COPY_DONE (1<<(RXf_BASE_SHIFT+16))
+#define RXf_COPY_DONE (1U<<(RXf_BASE_SHIFT+11))
-/* during execution: pattern temporarily tainted by executing locale ops;
- * post-execution: $1 et al are tainted */
-#define RXf_TAINTED_SEEN (1<<(RXf_BASE_SHIFT+17))
+/* post-execution: $1 et al are tainted */
+#define RXf_TAINTED_SEEN (1U<<(RXf_BASE_SHIFT+12))
/* this pattern was tainted during compilation */
-#define RXf_TAINTED (1<<(RXf_BASE_SHIFT+18))
+#define RXf_TAINTED (1U<<(RXf_BASE_SHIFT+13))
/* Flags indicating special patterns */
-#define RXf_START_ONLY (1<<(RXf_BASE_SHIFT+19)) /* Pattern is /^/ */
-#define RXf_SKIPWHITE (1<<(RXf_BASE_SHIFT+20)) /* Pattern is for a split " " */
-#define RXf_WHITE (1<<(RXf_BASE_SHIFT+21)) /* Pattern is /\s+/ */
-#define RXf_NULL (1U<<(RXf_BASE_SHIFT+22)) /* Pattern is // */
-#if RXf_BASE_SHIFT+22 > 31
-# error Too many RXf_PMf bits used. See regnodes.h for any spare in middle
+#define RXf_START_ONLY (1U<<(RXf_BASE_SHIFT+14)) /* Pattern is /^/ */
+#define RXf_SKIPWHITE (1U<<(RXf_BASE_SHIFT+15)) /* Pattern is for a */
+ /* split " " */
+#define RXf_WHITE (1U<<(RXf_BASE_SHIFT+16)) /* Pattern is /\s+/ */
+#define RXf_NULL (1U<<(RXf_BASE_SHIFT+17)) /* Pattern is // */
+
+/* See comments at the beginning of these defines about adding bits. The
+ * highest bit position should be used, so that if RXf_BASE_SHIFT gets
+ * increased, the #error below will be triggered so that you will be reminded
+ * to adjust things at the other end to keep the bit positions unchanged */
+#if RXf_BASE_SHIFT+17 > 31
+# error Too many RXf_PMf bits used. See comments at beginning of these for what to do
#endif
/*
*
*/
-#if NO_TAINT_SUPPORT
+#ifdef NO_TAINT_SUPPORT
# define RX_ISTAINTED(prog) 0
# define RX_TAINT_on(prog) NOOP
# define RXp_MATCH_TAINTED(prog) 0
#define RX_SAVED_COPY(prog) (ReANY(prog)->saved_copy)
/* last match was zero-length */
#define RX_ZERO_LEN(prog) \
- (RX_OFFS(prog)[0].start + RX_GOFS(prog) == (UV)RX_OFFS(prog)[0].end)
+ (RX_OFFS(prog)[0].start + (SSize_t)RX_GOFS(prog) \
+ == RX_OFFS(prog)[0].end)
#endif /* PLUGGABLE_RE_EXTENSION */
/* Whether the pattern stored at RX_WRAPPED is in UTF-8 */
#define RX_UTF8(prog) SvUTF8(prog)
-#define REXEC_COPY_STR 0x01 /* Need to copy the string. */
-#define REXEC_CHECKED 0x02 /* check_substr already checked. */
-#define REXEC_SCREAM 0x04 /* use scream table. */
-#define REXEC_IGNOREPOS 0x08 /* \G matches at start. */
-#define REXEC_NOT_FIRST 0x10 /* This is another iteration of //g. */
- /* under REXEC_COPY_STR, it's ok for the
- * engine (modulo PL_sawamperand etc)
- * to skip copying ... */
-#define REXEC_COPY_SKIP_PRE 0x20 /* ...the $` part of the string, or */
-#define REXEC_COPY_SKIP_POST 0x40 /* ...the $' part of the string */
+
+/* bits in flags arg of Perl_regexec_flags() */
+
+#define REXEC_COPY_STR 0x01 /* Need to copy the string for captures. */
+#define REXEC_CHECKED 0x02 /* re_intuit_start() already called. */
+#define REXEC_SCREAM 0x04 /* currently unused. */
+#define REXEC_IGNOREPOS 0x08 /* use stringarg, not pos(), for \G match */
+#define REXEC_NOT_FIRST 0x10 /* This is another iteration of //g:
+ no need to copy string again */
+
+ /* under REXEC_COPY_STR, it's ok for the
+ engine (modulo PL_sawamperand etc)
+ to skip copying: ... */
+#define REXEC_COPY_SKIP_PRE 0x20 /* ...the $` part of the string, or */
+#define REXEC_COPY_SKIP_POST 0x40 /* ...the $' part of the string */
+#define REXEC_FAIL_ON_UNDERFLOW 0x80 /* fail the match if $& would start before
+ the start pos (so s/.\G// would fail
+ on second iteration */
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define ReREFCNT_inc(re) \
STRLEN suboffset; /* saved suboffset field from rex */
STRLEN subcoffset; /* saved subcoffset field from rex */
MAGIC *pos_magic; /* pos() magic attached to $_ */
- I32 pos; /* the original value of pos() in pos_magic */
+ SSize_t pos; /* the original value of pos() in pos_magic */
+ U8 pos_flags; /* flags to be restored; currently only MGf_BYTES*/
} regmatch_info_aux_eval;