This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regexp.h: Add some comments
[perl5.git] / regexp.h
index 4788dfe..6232356 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,43 +66,45 @@ 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 {
        _XPV_HEAD;
-       _XPVMG_HEAD;
-        /* what engine created this regexp? */
-       const struct regexp_engine* engine; 
-       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 */
-       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 */
+       _REGEXP_COMMON;
 } regexp;
 
 #define RXp_PAREN_NAMES(rx)    ((rx)->paren_names)
@@ -118,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);
@@ -176,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
@@ -213,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
@@ -221,13 +223,17 @@ 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.
  *
  */
 
 /* 0x3F of extflags is used by (RXf_)PMf_COMPILETIME
  * If you change these you need to change the equivalent flags in op.h, and
- * vice versa.  */
+/* vice versa.  These need to be ordered so that the msix are contiguous
+ * starting at bit 0, followed by the p; bit 0 is because of the shift below
+ * being 0; see STD_PAT_MODS and INT_PAT_MODS below for the contiguity cause */
+/* the flags above are transfered from the PMOP->op_pmflags member during
+ * compilation */
 #define RXf_PMf_MULTILINE      0x00000001 /* /m         */
 #define RXf_PMf_SINGLELINE     0x00000002 /* /s         */
 #define RXf_PMf_FOLD           0x00000004 /* /i         */
@@ -261,24 +267,32 @@ 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"
 
+/* This string is expected by regcomp.c to be ordered so that the first
+ * character is the flag in bit 0 of extflags; the next character is bit 1,
+ * etc. */
 #define STD_PAT_MODS        "msix"
 
+/* This string is expected by XS_re_regexp_pattern() in universal.c to be ordered
+ * so that the first character is the flag in bit 0 of extflags; the next
+ * character is bit 1, etc. */
 #define INT_PAT_MODS    STD_PAT_MODS    KEEPCOPY_PAT_MODS
 
 #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.
  *
  */
 
@@ -333,7 +347,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.
  *
  */
 
@@ -360,21 +374,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)
@@ -414,29 +462,31 @@ 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);                                     \
-       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)
-#  define ReREFCNT_inc(re)     SvREFCNT_inc(re)
+#  define ReREFCNT_inc(re)     ((REGEXP *) SvREFCNT_inc(re))
 #endif
 
 /* FIXME for plugins. */
@@ -449,13 +499,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 */
 
@@ -516,11 +559,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
@@ -566,12 +613,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 */