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 b41c0a4..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.
@@ -70,6 +70,7 @@ typedef struct regexp_paren_pair {
         /* 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 */ \
@@ -88,7 +89,7 @@ typedef struct regexp_paren_pair {
        /* 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 *swap;        /* Unused: 5.10.1 and later */  \
        /* Array of offsets for (@-) and (@+) */                        \
        regexp_paren_pair *offs;                                        \
        /* saved or original string so \digit works forever. */         \
@@ -97,26 +98,16 @@ typedef struct regexp_paren_pair {
        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 */               \
-       unsigned pre_prefix:4;                                          \
+       PERL_BITFIELD32 pre_prefix:4;                                   \
        /* number of eval groups in the pattern - for security checks */\
-       unsigned seen_evals:28
+       PERL_BITFIELD32 seen_evals:28
 
 typedef struct regexp {
        _XPV_HEAD;
-       _XPVMG_HEAD;
        _REGEXP_COMMON;
 } regexp;
 
-struct regexp_allocated {
-       _XPV_ALLOCATED_HEAD;
-       _XPVMG_HEAD;
-       _REGEXP_COMMON;
-};
-
-/*        HV *paren_names;      Optional hash of paren names
-         now stored in the IV union */
-
-#define RXp_PAREN_NAMES(rx)    ((rx)->xiv_u.xivu_hv)
+#define RXp_PAREN_NAMES(rx)    ((rx)->paren_names)
 
 /* used for high speed searches */
 typedef struct re_scream_pos_data_s
@@ -129,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);
@@ -187,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
@@ -224,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
@@ -232,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.
  *
  */
 
@@ -272,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"
 
@@ -285,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.
  *
  */
 
@@ -344,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.
  *
  */
 
@@ -371,21 +364,55 @@ and check for NULL.
 
 /* 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)
 /* 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_EXTFLAGS(prog)      RXp_EXTFLAGS((struct regexp *)SvANY(prog))
 #define RX_REFCNT(prog)                SvREFCNT(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)
+#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_SUBBEG(prog)                (((struct regexp *)SvANY(prog))->subbeg)
 #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)
@@ -425,25 +452,27 @@ and check for NULL.
 
 /* 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. */
 
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
+#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 zwapp = (re);                                     \
-       (REGEXP *) SvREFCNT_inc(zwapp);                                 \
+       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 boff = (re);                                      \
-       SvREFCNT_dec(boff);                                             \
+       REGEXP *const _rerefcnt_dec = (re);                             \
+       SvREFCNT_dec(_rerefcnt_dec);                                    \
     })
 #else
 #  define ReREFCNT_dec(re)     SvREFCNT_dec(re)
@@ -460,13 +489,6 @@ 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 */
 
@@ -527,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
@@ -577,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 */