This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlop.pod: Document current \000 \x behavior
[perl5.git] / regexp.h
index 17dfbb6..f87031c 100644 (file)
--- a/regexp.h
+++ b/regexp.h
@@ -1,7 +1,7 @@
 /*    regexp.h
  *
  *    Copyright (C) 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2003,
- *    2005, 2006, 2007, by Larry Wall and others
+ *    2005, 2006, 2007, 2008 by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -66,49 +66,49 @@ typedef struct regexp_paren_pair {
   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 */ \
+       I32 minlen;     /* mininum possible length of string to match */\
+       I32 minlenret;  /* mininum possible length of $& */             \
+       U32 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 */  \
+       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. */         \
+       char *subbeg;                                                   \
+       SV_SAVED_COPY   /* If non-NULL, SV which is COW from original */\
+       I32 sublen;     /* Length of string pointed by subbeg */        \
+       /* Information about the match that isn't often used */         \
+       /* offset from wrapped to the start of precomp */               \
+       PERL_BITFIELD32 pre_prefix:4;                                   \
+       /* number of eval groups in the pattern - for security checks */\
+       PERL_BITFIELD32 seen_evals:28
+
 typedef struct regexp {
-        /* what engine created this regexp? */
-       const struct regexp_engine* engine; 
-       struct regexp* mother_re; /* what re is this a lightweight copy of? */
-       
-       /* 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 $& */
-       U32 gofs;               /* chars left of pos that we search from */
-       struct reg_substr_data *substrs; /* substring data about strings that must appear
-                                   in the final match, used for optimisations */
-       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 */
-        regexp_paren_pair *swap;  /* Swap copy of *offs */ 
-        regexp_paren_pair *offs;  /* Array of offsets for (@-) and (@+) */
-
-       char *subbeg;           /* saved or original string 
-                                  so \digit works forever. */
-       SV_SAVED_COPY           /* If non-NULL, SV which is COW from original */
-       I32 sublen;             /* Length of string pointed by subbeg */
-        
-        
-        /* Information about the match that isn't often used */
-       /* wrapped can't be const char*, as it is returned by sv_2pv_flags */
-       char *wrapped;          /* wrapped version of the pattern */
-       I32 wraplen;            /* length of wrapped */
-       unsigned pre_prefix:4;  /* offset from wrapped to the start of precomp */
-       unsigned seen_evals:28; /* number of eval groups in the pattern - for security checks */ 
-        HV *paren_names;       /* Optional hash of paren names */
-        
-        /* Refcount of this regexp */
-       I32 refcnt;             /* Refcount of this regexp */
+       _XPV_HEAD;
+       _REGEXP_COMMON;
 } regexp;
 
+#define RXp_PAREN_NAMES(rx)    ((rx)->paren_names)
+
 /* used for high speed searches */
 typedef struct re_scream_pos_data_s
 {
@@ -120,7 +120,7 @@ typedef struct re_scream_pos_data_s
  * Any regex engine implementation must be able to build one of these.
  */
 typedef struct regexp_engine {
-    REGEXP* (*comp) (pTHX_ const SV * const pattern, const U32 flags);
+    REGEXP* (*comp) (pTHX_ SV * const pattern, U32 flags);
     I32     (*exec) (pTHX_ REGEXP * const rx, char* stringarg, char* strend,
                      char* strbeg, I32 minend, SV* screamer,
                      void* data, U32 flags);
@@ -178,7 +178,7 @@ typedef struct regexp_engine {
 /* Whether this is being called from a re:: function */
 #define RXapif_REGNAME         0x0400
 #define RXapif_REGNAMES        0x0800
-#define RXapif_REGNAMES_COUNT  0x1000 
+#define RXapif_REGNAMES_COUNT  0x1000
 
 /*
 =head1 REGEXP Functions
@@ -215,7 +215,7 @@ and check for NULL.
 #define SvRXOK(sv) (Perl_get_re_arg(aTHX_ sv) ? TRUE : FALSE)
 
 
-/* Flags stored in regexp->extflags 
+/* Flags stored in regexp->extflags
  * These are used by code external to the regexp engine
  *
  * Note that flags starting with RXf_PMf_ have exact equivalents
@@ -223,7 +223,7 @@ and check for NULL.
  * numerically here only for clarity.
  *
  * NOTE: if you modify any RXf flags you should run regen.pl or regcomp.pl
- * so that regnodes.h is updated with the changes. 
+ * so that regnodes.h is updated with the changes.
  *
  */
 
@@ -263,11 +263,13 @@ and check for NULL.
 #define SINGLE_PAT_MOD       's'
 #define IGNORE_PAT_MOD       'i'
 #define XTENDED_PAT_MOD      'x'
+#define NONDESTRUCT_PAT_MOD  'r'
 
 #define ONCE_PAT_MODS        "o"
 #define KEEPCOPY_PAT_MODS    "p"
 #define EXEC_PAT_MODS        "e"
 #define LOOP_PAT_MODS        "gc"
+#define NONDESTRUCT_PAT_MODS "r"
 
 #define STD_PAT_MODS        "msix"
 
@@ -276,11 +278,11 @@ and check for NULL.
 #define EXT_PAT_MODS    ONCE_PAT_MODS   KEEPCOPY_PAT_MODS
 #define QR_PAT_MODS     STD_PAT_MODS    EXT_PAT_MODS
 #define M_PAT_MODS      QR_PAT_MODS     LOOP_PAT_MODS
-#define S_PAT_MODS      M_PAT_MODS      EXEC_PAT_MODS
+#define S_PAT_MODS      M_PAT_MODS      EXEC_PAT_MODS      NONDESTRUCT_PAT_MODS
 
 /*
  * NOTE: if you modify any RXf flags you should run regen.pl or regcomp.pl
- * so that regnodes.h is updated with the changes. 
+ * so that regnodes.h is updated with the changes.
  *
  */
 
@@ -306,7 +308,6 @@ and check for NULL.
 #define RXf_CHECK_ALL          0x00040000
 
 /* UTF8 related */
-#define RXf_UTF8               0x00080000
 #define RXf_MATCH_UTF8         0x00100000
 
 /* Intuit related */
@@ -336,7 +337,7 @@ and check for NULL.
 
 /*
  * NOTE: if you modify any RXf flags you should run regen.pl or regcomp.pl
- * so that regnodes.h is updated with the changes. 
+ * so that regnodes.h is updated with the changes.
  *
  */
 
@@ -359,35 +360,66 @@ and check for NULL.
                                         ? RX_MATCH_COPIED_on(prog) \
                                         : RX_MATCH_COPIED_off(prog))
 
-#define RXp_PRECOMP(rx)                ((rx)->wrapped + (rx)->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 RXp_PRELEN(rx)         ((rx)->wraplen - (rx)->pre_prefix - 1)
-#define RXp_WRAPPED(rx)                ((rx)->wrapped)
-#define RXp_WRAPLEN(rx)                ((rx)->wraplen)
 #define RXp_EXTFLAGS(rx)       ((rx)->extflags)
 
 /* For source compatibility. We used to store these explicitly.  */
-#define RX_PRECOMP(prog)       ((prog)->wrapped + (prog)->pre_prefix)
-#define RX_PRELEN(prog)                ((prog)->wraplen - (prog)->pre_prefix - 1)
-#define RX_WRAPPED(prog)       ((prog)->wrapped)
-#define RX_WRAPLEN(prog)       ((prog)->wraplen)
-#define RX_CHECK_SUBSTR(prog)  ((prog)->check_substr)
-#define RX_EXTFLAGS(prog)      ((prog)->extflags)
-#define RX_REFCNT(prog)                ((prog)->refcnt)
-#define RX_ENGINE(prog)                ((prog)->engine)
-#define RX_SUBBEG(prog)                ((prog)->subbeg)
-#define RX_OFFS(prog)          ((prog)->offs)
-#define RX_NPARENS(prog)       ((prog)->nparens)
-#define RX_SUBLEN(prog)                ((prog)->sublen)
-#define RX_SUBBEG(prog)                ((prog)->subbeg)
-#define RX_MINLEN(prog)                ((prog)->minlen)
-#define RX_MINLENRET(prog)     ((prog)->minlenret)
-#define RX_GOFS(prog)          ((prog)->gofs)
-#define RX_LASTPAREN(prog)     ((prog)->lastparen)
-#define RX_LASTCLOSEPAREN(prog)        ((prog)->lastcloseparen)
-#define RX_SEEN_EVALS(prog)    ((prog)->seen_evals)
+#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)
+/* 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_WRAPLEN(prog)       SvCUR(prog)
+#define RX_CHECK_SUBSTR(prog)  (((struct regexp *)SvANY(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_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_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_SEEN_EVALS(prog)    (((struct regexp *)SvANY(prog))->seen_evals)
+#define RX_SAVED_COPY(prog)    (((struct regexp *)SvANY(prog))->saved_copy)
 
 #endif /* PLUGGABLE_RE_EXTENSION */
 
@@ -395,8 +427,8 @@ and check for NULL.
 
 #ifdef PERL_OLD_COPY_ON_WRITE
 #define RX_MATCH_COPY_FREE(rx) \
-       STMT_START {if (rx->saved_copy) { \
-           SV_CHECK_THINKFIRST_COW_DROP(rx->saved_copy); \
+       STMT_START {if (RX_SAVED_COPY(rx)) { \
+           SV_CHECK_THINKFIRST_COW_DROP(RX_SAVED_COPY(rx)); \
        } \
        if (RX_MATCH_COPIED(rx)) { \
            Safefree(RX_SUBBEG(rx)); \
@@ -417,15 +449,37 @@ and check for NULL.
 #define RX_MATCH_UTF8_set(prog, t)     ((t) \
                        ? (RX_MATCH_UTF8_on(prog), (PL_reg_match_utf8 = 1)) \
                        : (RX_MATCH_UTF8_off(prog), (PL_reg_match_utf8 = 0)))
-    
+
+/* 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. */
 
-#define ReREFCNT_inc(re) ((void)(re && re->refcnt++), re)
-#define ReREFCNT_dec(re) CALLREGFREE(re)
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define ReREFCNT_inc(re)                                             \
+    ({                                                                 \
+       /* This is here to generate a casting warning if incorrect.  */ \
+       REGEXP *const _rerefcnt_inc = (re);                             \
+       assert(SvTYPE(_rerefcnt_inc) == SVt_REGEXP);                    \
+       SvREFCNT_inc(_rerefcnt_inc);                                    \
+       _rerefcnt_inc;                                                  \
+    })
+#  define ReREFCNT_dec(re)                                             \
+    ({                                                                 \
+       /* This is here to generate a casting warning if incorrect.  */ \
+       REGEXP *const _rerefcnt_dec = (re);                             \
+       SvREFCNT_dec(_rerefcnt_dec);                                    \
+    })
+#else
+#  define ReREFCNT_dec(re)     SvREFCNT_dec(re)
+#  define ReREFCNT_inc(re)     ((REGEXP *) SvREFCNT_inc(re))
+#endif
+
+/* FIXME for plugins. */
 
 #define FBMcf_TAIL_DOLLAR      1
 #define FBMcf_TAIL_DOLLARM     2
@@ -435,18 +489,11 @@ and check for NULL.
 
 #define FBMrf_MULTILINE        1
 
-/* an accepting state/position*/
-struct _reg_trie_accepted {
-    U8   *endpos;
-    U16  wordnum;
-};
-typedef struct _reg_trie_accepted reg_trie_accepted;
-
 /* some basic information about the current match that is created by
  * Perl_regexec_flags and then passed to regtry(), regmatch() etc */
 
 typedef struct {
-    regexp *prog;
+    REGEXP *prog;
     char *bol;
     char *till;
     SV *sv;
@@ -502,11 +549,15 @@ typedef struct regmatch_state {
            U32 lastparen;
            CHECKPOINT cp;
 
-           reg_trie_accepted *accept_buff; /* accepting states we have seen */
-           U32         accepted; /* how many accepting states we have seen */
+           U32         accepted; /* how many accepting states left */
            U16         *jump;  /* positive offsets from me */
            regnode     *B;     /* node following the trie */
            regnode     *me;    /* Which node am I - needed for jump tries*/
+           U8          *firstpos;/* pos in string of first trie match */
+           U32         firstchars;/* len in chars of firstpos from start */
+           U16         nextword;/* next word to try */
+           U16         topword; /* longest accepted word */
+           bool        longfold;/* saw a fold with a 1->n char mapping */
        } trie;
 
         /* special types - these members are used to store state for special
@@ -516,7 +567,7 @@ typedef struct regmatch_state {
            struct regmatch_state *prev_yes_state;
            struct regmatch_state *prev_eval;
            struct regmatch_state *prev_curlyx;
-           regexp      *prev_rex;
+           REGEXP      *prev_rex;
            U32         toggle_reg_flags; /* what bits in PL_reg_flags to
                                            flip when transitioning between
                                            inner and outer rexen */
@@ -552,12 +603,11 @@ typedef struct regmatch_state {
            /* this first element must match u.yes */
            struct regmatch_state *prev_yes_state;
            struct regmatch_state *prev_curlyx; /* previous cur_curlyx */
-           regnode     *A, *B; /* the nodes corresponding to /A*B/  */
+           regnode     *me;    /* the CURLYX node  */
+           regnode     *B;     /* the B node in /A*B/  */
            CHECKPOINT  cp;     /* remember current savestack index */
            bool        minmod;
            int         parenfloor;/* how far back to strip paren data */
-           int         min;    /* the minimal number of A's to match */
-           int         max;    /* the maximal number of A's to match */
 
            /* these two are modified by WHILEM */
            int         count;  /* how many instances of A we've matched */