X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/cccd1425414e6518c1fc8b7bcaccfb119320c513..8cdde9f826664af3e1c4c5f5f1bd9642d7aee812:/regexp.h diff --git a/regexp.h b/regexp.h index 8f43d19..51630e4 100644 --- a/regexp.h +++ b/regexp.h @@ -18,6 +18,8 @@ /* we don't want to include this stuff if we are inside of an external regex engine based on the core one - like re 'debug'*/ +#include "utf8.h" + struct regnode { U8 flags; U8 type; @@ -44,7 +46,7 @@ struct reg_substr_data { struct reg_substr_datum data[3]; /* Actual array */ }; -#ifdef PERL_OLD_COPY_ON_WRITE +#ifdef PERL_ANY_COW #define SV_SAVED_COPY SV *saved_copy; /* If non-NULL, SV which is COW from original */ #else #define SV_SAVED_COPY @@ -102,8 +104,8 @@ struct reg_code_block { /* Information about the match that the perl core uses to */ \ /* manage things */ \ U32 extflags; /* Flags used both externally and internally */ \ - I32 minlen; /* mininum possible length of string to match */\ - I32 minlenret; /* mininum possible length of $& */ \ + 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 */ \ /* substring data about strings that must appear in the */ \ /* final match, used for optimisations */ \ @@ -117,7 +119,6 @@ struct reg_code_block { /* during matching */ \ U32 lastparen; /* last open paren matched */ \ U32 lastcloseparen; /* last close paren matched */ \ - regexp_paren_pair *swap; /* Unused: 5.10.1 and later */ \ /* Array of offsets for (@-) and (@+) */ \ regexp_paren_pair *offs; \ /* saved or original string so \digit works forever. */ \ @@ -408,6 +409,8 @@ get_regex_charset_name(const U32 flags, STRLEN* const lenp) #define RXf_INTUIT_TAIL (1<<(RXf_BASE_SHIFT+14)) #define RXf_USE_INTUIT (RXf_USE_INTUIT_NOML|RXf_USE_INTUIT_ML) +#define RXf_MODIFIES_VARS (1<<(RXf_BASE_SHIFT+15)) + /* Copy and tainted info */ #define RXf_COPY_DONE (1<<(RXf_BASE_SHIFT+16)) @@ -431,11 +434,25 @@ get_regex_charset_name(const U32 flags, STRLEN* const lenp) * */ +#if 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 +#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) +#endif + #define RX_HAS_CUTGROUP(prog) ((prog)->intflags & PREGf_CUTGROUP_SEEN) -#define RXp_MATCH_TAINTED(prog) (RXp_EXTFLAGS(prog) & RXf_TAINTED_SEEN) -#define RX_MATCH_TAINTED(prog) (RX_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_MATCH_TAINTED_set(prog, t) ((t) \ ? RX_MATCH_TAINTED_on(prog) \ : RX_MATCH_TAINTED_off(prog)) @@ -453,82 +470,37 @@ get_regex_charset_name(const U32 flags, STRLEN* const lenp) #define RXp_EXTFLAGS(rx) ((rx)->extflags) /* For source compatibility. We used to store these explicitly. */ -#define RX_PRECOMP(prog) (RX_WRAPPED(prog) + ((struct regexp *)SvANY(prog))->pre_prefix) -#define RX_PRECOMP_const(prog) (RX_WRAPPED_const(prog) + ((struct regexp *)SvANY(prog))->pre_prefix) +#define RX_PRECOMP(prog) (RX_WRAPPED(prog) + ReANY(prog)->pre_prefix) +#define RX_PRECOMP_const(prog) (RX_WRAPPED_const(prog) + ReANY(prog)->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) - ((struct regexp *)SvANY(prog))->pre_prefix - 1) -#define RX_WRAPPED(prog) SvPVX(prog) -#define RX_WRAPPED_const(prog) SvPVX_const(prog) +#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) (((struct regexp *)SvANY(prog))->check_substr) +#define RX_CHECK_SUBSTR(prog) (ReANY(prog)->check_substr) #define RX_REFCNT(prog) SvREFCNT(prog) -#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) -# define RX_EXTFLAGS(prog) \ - (*({ \ - const REGEXP *const _rx_extflags = (prog); \ - assert(SvTYPE(_rx_extflags) == SVt_REGEXP); \ - &RXp_EXTFLAGS(SvANY(_rx_extflags)); \ - })) -# define RX_ENGINE(prog) \ - (*({ \ - const REGEXP *const _rx_engine = (prog); \ - assert(SvTYPE(_rx_engine) == SVt_REGEXP); \ - &SvANY(_rx_engine)->engine; \ - })) -# define RX_SUBBEG(prog) \ - (*({ \ - const REGEXP *const _rx_subbeg = (prog); \ - assert(SvTYPE(_rx_subbeg) == SVt_REGEXP); \ - &SvANY(_rx_subbeg)->subbeg; \ - })) -# define RX_SUBOFFSET(prog) \ - (*({ \ - const REGEXP *const _rx_suboffset = (prog); \ - assert(SvTYPE(_rx_suboffset) == SVt_REGEXP); \ - &SvANY(_rx_suboffset)->suboffset; \ - })) -# define RX_SUBCOFFSET(prog) \ - (*({ \ - const REGEXP *const _rx_subcoffset = (prog); \ - assert(SvTYPE(_rx_subcoffset) == SVt_REGEXP); \ - &SvANY(_rx_subcoffset)->subcoffset; \ - })) -# define RX_OFFS(prog) \ - (*({ \ - const REGEXP *const _rx_offs = (prog); \ - assert(SvTYPE(_rx_offs) == SVt_REGEXP); \ - &SvANY(_rx_offs)->offs; \ - })) -# define RX_NPARENS(prog) \ - (*({ \ - const REGEXP *const _rx_nparens = (prog); \ - assert(SvTYPE(_rx_nparens) == SVt_REGEXP); \ - &SvANY(_rx_nparens)->nparens; \ - })) -#else -# define RX_EXTFLAGS(prog) RXp_EXTFLAGS((struct regexp *)SvANY(prog)) -# define RX_ENGINE(prog) (((struct regexp *)SvANY(prog))->engine) -# define RX_SUBBEG(prog) (((struct regexp *)SvANY(prog))->subbeg) -# define RX_SUBOFFSET(prog) (((struct regexp *)SvANY(prog))->suboffset) -# define RX_SUBCOFFSET(prog) (((struct regexp *)SvANY(prog))->subcoffset) -# define RX_OFFS(prog) (((struct regexp *)SvANY(prog))->offs) -# define RX_NPARENS(prog) (((struct regexp *)SvANY(prog))->nparens) -#endif -#define RX_SUBLEN(prog) (((struct regexp *)SvANY(prog))->sublen) -#define RX_MINLEN(prog) (((struct regexp *)SvANY(prog))->minlen) -#define RX_MINLENRET(prog) (((struct regexp *)SvANY(prog))->minlenret) -#define RX_GOFS(prog) (((struct regexp *)SvANY(prog))->gofs) -#define RX_LASTPAREN(prog) (((struct regexp *)SvANY(prog))->lastparen) -#define RX_LASTCLOSEPAREN(prog) (((struct regexp *)SvANY(prog))->lastcloseparen) -#define RX_SAVED_COPY(prog) (((struct regexp *)SvANY(prog))->saved_copy) +#define RX_EXTFLAGS(prog) RXp_EXTFLAGS(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) #endif /* PLUGGABLE_RE_EXTENSION */ /* Stuff that needs to be included in the pluggable extension goes below here */ -#ifdef PERL_OLD_COPY_ON_WRITE +#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)); \ @@ -586,6 +558,7 @@ get_regex_charset_name(const U32 flags, STRLEN* const lenp) # define ReREFCNT_dec(re) SvREFCNT_dec(re) # define ReREFCNT_inc(re) ((REGEXP *) SvREFCNT_inc(re)) #endif +#define ReANY(re) S_ReANY((const REGEXP *)(re)) /* FIXME for plugins. */ @@ -607,6 +580,8 @@ typedef struct { SV *sv; char *ganch; char *cutpoint; + bool is_utf8_pat; + bool warned; /* we have issued a recursion warning; no need for more */ } regmatch_info; @@ -678,9 +653,7 @@ typedef struct regmatch_state { struct regmatch_state *prev_eval; struct regmatch_state *prev_curlyx; REGEXP *prev_rex; - U32 toggle_reg_flags; /* what bits in PL_reg_flags to - flip when transitioning between - inner and outer rexen */ + bool saved_utf8_pat; /* saved copy of is_utf8_pat */ CHECKPOINT cp; /* remember current savestack indexes */ CHECKPOINT lastcp; U32 close_paren; /* which close bracket is our end */ @@ -738,7 +711,7 @@ typedef struct regmatch_state { struct { /* this first element must match u.yes */ struct regmatch_state *prev_yes_state; - I32 c1, c2; /* case fold search */ + int c1, c2; /* case fold search */ CHECKPOINT cp; U32 lastparen; U32 lastcloseparen; @@ -747,6 +720,8 @@ typedef struct regmatch_state { bool minmod; regnode *A, *B; /* the nodes corresponding to /A*B/ */ regnode *me; /* the curlym node */ + U8 c1_utf8[UTF8_MAXBYTES+1]; /* */ + U8 c2_utf8[UTF8_MAXBYTES+1]; } curlym; struct { @@ -754,12 +729,14 @@ typedef struct regmatch_state { CHECKPOINT cp; U32 lastparen; U32 lastcloseparen; - I32 c1, c2; /* case fold search */ + int c1, c2; /* case fold search */ char *maxpos; /* highest possible point in string to match */ char *oldloc; /* the previous locinput */ int count; int min, max; /* {m,n} */ regnode *A, *B; /* the nodes corresponding to /A*B/ */ + U8 c1_utf8[UTF8_MAXBYTES+1]; /* */ + U8 c2_utf8[UTF8_MAXBYTES+1]; } curly; /* and CURLYN/PLUS/STAR */ } u; @@ -777,7 +754,6 @@ typedef struct regmatch_slab { struct regmatch_slab *prev, *next; } regmatch_slab; -#define PL_reg_flags PL_reg_state.re_state_reg_flags #define PL_bostr PL_reg_state.re_state_bostr #define PL_regeol PL_reg_state.re_state_regeol #define PL_reg_match_utf8 PL_reg_state.re_state_reg_match_utf8 @@ -793,15 +769,17 @@ typedef struct regmatch_slab { #define PL_reg_leftiter PL_reg_state.re_state_reg_leftiter #define PL_reg_poscache PL_reg_state.re_state_reg_poscache #define PL_reg_poscache_size PL_reg_state.re_state_reg_poscache_size -#define PL_regsize PL_reg_state.re_state_regsize #define PL_reg_starttry PL_reg_state.re_state_reg_starttry #define PL_nrs PL_reg_state.re_state_nrs struct re_save_state { - U32 re_state_reg_flags; /* from regexec.c */ bool re_state_eval_setup_done; /* from regexec.c */ bool re_state_reg_match_utf8; /* from regexec.c */ bool re_reparsing; /* runtime (?{}) fed back into parser */ + /* Space for U8 */ + I32 re_state_reg_oldpos; /* from regexec.c */ + I32 re_state_reg_maxiter; /* max wait until caching pos */ + I32 re_state_reg_leftiter; /* wait until caching pos */ char *re_state_bostr; char *re_state_regeol; /* End of input, for $ check. */ MAGIC *re_state_reg_magic; /* from regexec.c */ @@ -812,13 +790,9 @@ struct re_save_state { STRLEN re_state_reg_oldsavedoffset; /* old offset of saved substr during match */ STRLEN re_state_reg_oldsavedcoffset;/* old coffset of saved substr during match */ STRLEN re_state_reg_poscache_size; /* size of pos cache of WHILEM */ - I32 re_state_reg_oldpos; /* from regexec.c */ - I32 re_state_reg_maxiter; /* max wait until caching pos */ - I32 re_state_reg_leftiter; /* wait until caching pos */ - U32 re_state_regsize; /* from regexec.c */ char *re_state_reg_poscache; /* cache of pos of WHILEM */ char *re_state_reg_starttry; /* from regexec.c */ -#ifdef PERL_OLD_COPY_ON_WRITE +#ifdef PERL_ANY_COW SV *re_state_nrs; /* was placeholder: unused since 5.8.0 (5.7.2 patch #12027 for bug ID 20010815.012). Used to save rx->saved_copy */ #endif };