bug-grep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Suggested patch: move dfa internals into dfa.c


From: Aharon Robbins
Subject: Suggested patch: move dfa internals into dfa.c
Date: Wed, 07 Apr 2010 21:49:19 +0300

Hi. The code

        enum token_enum;
        typedef token_enum token;

isn't acceptable to at least two otherwise more-or-less C89 compilers.

So, I went whole-hog and moved all the dfa internals into dfa.c. This
fixes the long-standing wish in dfa.h about not exposing internals.

Grep passes its test suite with this change, at least on my creaking-along
Fedora 7 laptop. :-)

Attached is a patch formatted per the HACKING file's instructions. It's
my *very first* use of git, so be kind.

Arnold
--------------------------------------
>From bc44560f893d7c86308479eb8070a4987360976e Mon Sep 17 00:00:00 2001
From: Arnold D. Robbins <address@hidden>
Date: Wed, 7 Apr 2010 21:42:39 +0300
Subject: [PATCH] dfa.h: Moved essentially all the dfa internals out of dfa.h. 
New routines added as needed.
 dfa.c: The dfa internals are now totally local to this file. A few new 
routines added for access to features.
 dfasearch.c: Modified for changes in interface.

---
 src/dfa.c       |  276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/dfa.h       |  274 +++---------------------------------------------------
 src/dfasearch.c |   16 ++--
 3 files changed, 299 insertions(+), 267 deletions(-)

diff --git a/src/dfa.c b/src/dfa.c
index 5a4b2e3..9f6f165 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -68,10 +68,86 @@
 # undef clrbit
 #endif
 
+/* Number of bits in an unsigned char. */
+#ifndef CHARBITS
+#define CHARBITS 8
+#endif
+
+/* First integer value that is greater than any character code. */
+#define NOTCHAR (1 << CHARBITS)
+
+/* INTBITS need not be exact, just a lower bound. */
+#ifndef INTBITS
+#define INTBITS (CHARBITS * sizeof (int))
+#endif
+
+/* Number of ints required to hold a bit for every character. */
+#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS)
+
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
+# define __attribute__(x)
+#endif
+
+/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
+typedef int charclass[CHARCLASS_INTS];
+
+/* Sets are stored in an array in the compiled dfa; the index of the
+   array corresponding to a given set token is given by SET_INDEX(t). */
+#define SET_INDEX(t) ((t) - CSET)
+
+/* Sometimes characters can only be matched depending on the surrounding
+   context.  Such context decisions depend on what the previous character
+   was, and the value of the current (lookahead) character.  Context
+   dependent constraints are encoded as 8 bit integers.  Each bit that
+   is set indicates that the constraint succeeds in the corresponding
+   context.
+
+   bit 7 - previous and current are newlines
+   bit 6 - previous was newline, current isn't
+   bit 5 - previous wasn't newline, current is
+   bit 4 - neither previous nor current is a newline
+   bit 3 - previous and current are word-constituents
+   bit 2 - previous was word-constituent, current isn't
+   bit 1 - previous wasn't word-constituent, current is
+   bit 0 - neither previous nor current is word-constituent
+
+   Word-constituent characters are those that satisfy isalnum().
+
+   The macro SUCCEEDS_IN_CONTEXT determines whether a a given constraint
+   succeeds in a particular context.  Prevn is true if the previous character
+   was a newline, currn is true if the lookahead character is a newline.
+   Prevl and currl similarly depend upon whether the previous and current
+   characters are word-constituent letters. */
+#define MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \
+  ((constraint) & 1 << (((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4))
+#define MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \
+  ((constraint) & 1 << (((prevl) ? 2 : 0) + ((currl) ? 1 : 0)))
+#define SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \
+  (MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn)                \
+   && MATCHES_LETTER_CONTEXT(constraint, prevl, currl))
+
+/* The following macros give information about what a constraint depends on. */
+#define PREV_NEWLINE_DEPENDENT(constraint) \
+  (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30))
+#define PREV_LETTER_DEPENDENT(constraint) \
+  (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03))
+
+/* Tokens that match the empty string subject to some constraint actually
+   work by applying that constraint to determine what may follow them,
+   taking into account what has gone before.  The following values are
+   the constraints corresponding to the special tokens previously defined. */
+#define NO_CONSTRAINT 0xff
+#define BEGLINE_CONSTRAINT 0xcf
+#define ENDLINE_CONSTRAINT 0xaf
+#define BEGWORD_CONSTRAINT 0xf2
+#define ENDWORD_CONSTRAINT 0xf4
+#define LIMWORD_CONSTRAINT 0xf6
+#define NOTLIMWORD_CONSTRAINT 0xf9
+
 /* The regexp is parsed into an array of tokens in postfix form.  Some tokens
    are operators and others are terminal symbols.  Most (but not all) of these
    codes are returned by the lexical analyzer. */
-enum token_enum
+typedef enum
 {
   END = -1,                    /* END is a terminal symbol that matches the
                                   end of input; any value of END or less in
@@ -162,7 +238,186 @@ enum token_enum
   CSET                         /* CSET and (and any value greater) is a
                                   terminal symbol that matches any of a
                                   class of characters. */
+} token;
+
+
+/* States of the recognizer correspond to sets of positions in the parse
+   tree, together with the constraints under which they may be matched.
+   So a position is encoded as an index into the parse tree together with
+   a constraint. */
+typedef struct
+{
+  unsigned int index;          /* Index into the parse array. */
+  unsigned int constraint;     /* Constraint for matching this position. */
+} position;
+
+/* Sets of positions are stored as arrays. */
+typedef struct
+{
+  position *elems;             /* Elements of this position set. */
+  int nelem;                   /* Number of elements in this set. */
+} position_set;
+
+/* A state of the dfa consists of a set of positions, some flags,
+   and the token value of the lowest-numbered position of the state that
+   contains an END token. */
+typedef struct
+{
+  int hash;                    /* Hash of the positions of this state. */
+  position_set elems;          /* Positions this state could match. */
+  char newline;                        /* True if previous state matched 
newline. */
+  char letter;                 /* True if previous state matched a letter. */
+  char backref;                        /* True if this state matches a 
\<digit>. */
+  unsigned char constraint;    /* Constraint for this state to accept. */
+  int first_end;               /* Token value of the first END in elems. */
+#if MBS_SUPPORT
+  position_set mbps;           /* Positions which can match multibyte
+                                  characters.  e.g. period.
+                                 These staff are used only if
+                                 MB_CUR_MAX > 1.  */
+#endif
+} dfa_state;
+
+#if MBS_SUPPORT
+/* A bracket operator.
+   e.g. [a-c], [[:alpha:]], etc.  */
+struct mb_char_classes
+{
+  int cset;
+  int invert;
+  wchar_t *chars;              /* Normal characters.  */
+  int nchars;
+  wctype_t *ch_classes;                /* Character classes.  */
+  int nch_classes;
+  wchar_t *range_sts;          /* Range characters (start of the range).  */
+  wchar_t *range_ends;         /* Range characters (end of the range).  */
+  int nranges;
+  char **equivs;               /* Equivalent classes.  */
+  int nequivs;
+  char **coll_elems;
+  int ncoll_elems;             /* Collating elements.  */
 };
+#endif
+
+/* A compiled regular expression. */
+struct dfa
+{
+  /* Fields filled by the scanner. */
+  charclass *charclasses;      /* Array of character sets for CSET tokens. */
+  int cindex;                  /* Index for adding new charclasses. */
+  int calloc;                  /* Number of charclasses currently allocated. */
+
+  /* Fields filled by the parser. */
+  token *tokens;               /* Postfix parse array. */
+  int tindex;                  /* Index for adding new tokens. */
+  int talloc;                  /* Number of tokens currently allocated. */
+  int depth;                   /* Depth required of an evaluation stack
+                                  used for depth-first traversal of the
+                                  parse tree. */
+  int nleaves;                 /* Number of leaves on the parse tree. */
+  int nregexps;                        /* Count of parallel regexps being built
+                                  with dfaparse(). */
+#if MBS_SUPPORT
+  unsigned int mb_cur_max;     /* Cached value of MB_CUR_MAX.  */
+
+  /* The following are used only if MB_CUR_MAX > 1.  */
+
+  /* The value of multibyte_prop[i] is defined by following rule.
+       if tokens[i] < NOTCHAR
+         bit 0 : tokens[i] is the first byte of a character, including
+                 single-byte characters.
+         bit 1 : tokens[i] is the last byte of a character, including
+                 single-byte characters.
+
+       if tokens[i] = MBCSET
+         ("the index of mbcsets correspnd to this operator" << 2) + 3
+
+     e.g.
+     tokens
+        = 'single_byte_a', 'multi_byte_A', single_byte_b'
+        = 'sb_a', 'mb_A(1st byte)', 'mb_A(2nd byte)', 'mb_A(3rd byte)', 'sb_b'
+     multibyte_prop
+        = 3     , 1               ,  0              ,  2              , 3
+  */
+  int nmultibyte_prop;
+  int *multibyte_prop;
+
+  /* Array of the bracket expression in the DFA.  */
+  struct mb_char_classes *mbcsets;
+  int nmbcsets;
+  int mbcsets_alloc;
+#endif
+
+  /* Fields filled by the state builder. */
+  dfa_state *states;           /* States of the dfa. */
+  int sindex;                  /* Index for adding new states. */
+  int salloc;                  /* Number of states currently allocated. */
+
+  /* Fields filled by the parse tree->NFA conversion. */
+  position_set *follows;       /* Array of follow sets, indexed by position
+                                  index.  The follow of a position is the set
+                                  of positions containing characters that
+                                  could conceivably follow a character
+                                  matching the given position in a string
+                                  matching the regexp.  Allocated to the
+                                  maximum possible position index. */
+  int searchflag;              /* True if we are supposed to build a searching
+                                  as opposed to an exact matcher.  A searching
+                                  matcher finds the first and shortest string
+                                  matching a regexp anywhere in the buffer,
+                                  whereas an exact matcher finds the longest
+                                  string matching, but anchored to the
+                                  beginning of the buffer. */
+
+  /* Fields filled by dfaexec. */
+  int tralloc;                 /* Number of transition tables that have
+                                  slots so far. */
+  int trcount;                 /* Number of transition tables that have
+                                  actually been built. */
+  int **trans;                 /* Transition tables for states that can
+                                  never accept.  If the transitions for a
+                                  state have not yet been computed, or the
+                                  state could possibly accept, its entry in
+                                  this table is NULL. */
+  int **realtrans;             /* Trans always points to realtrans + 1; this
+                                  is so trans[-1] can contain NULL. */
+  int **fails;                 /* Transition tables after failing to accept
+                                  on a state that potentially could do so. */
+  int *success;                        /* Table of acceptance conditions used 
in
+                                  dfaexec and computed in build_state. */
+  int *newlines;               /* Transitions on newlines.  The entry for a
+                                  newline in any transition table is always
+                                  -1 so we can count lines without wasting
+                                  too many cycles.  The transition for a
+                                  newline is stored separately and handled
+                                  as a special case.  Newline is also used
+                                  as a sentinel at the end of the buffer. */
+  struct dfamust *musts;       /* List of strings, at least one of which
+                                  is known to appear in any r.e. matching
+                                  the dfa. */
+
+#ifdef GAWK
+  int broken;                  /* True if using a feature where there
+                                  are bugs and gawk should use regex. */
+#endif
+};
+
+/* Some macros for user access to dfa internals. */
+
+/* ACCEPTING returns true if s could possibly be an accepting state of r. */
+#define ACCEPTING(s, r) ((r).states[s].constraint)
+
+/* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the
+   specified context. */
+#define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, dfa) \
+  SUCCEEDS_IN_CONTEXT((dfa).states[state].constraint,             \
+                      prevn, currn, prevl, currl)
+
+/* FIRST_MATCHING_REGEXP returns the index number of the first of parallel
+   regexps that a given state could accept.  Parallel regexps are numbered
+   starting at 1. */
+#define FIRST_MATCHING_REGEXP(state, dfa) (-(dfa).states[state].first_end)
+
 
 static void dfamust (struct dfa *dfa);
 static void regexp (int toplevel);
@@ -3677,4 +3932,23 @@ dfamust (struct dfa *d)
     }
   free(mp);
 }
+
+struct dfa *
+dfaalloc()
+{
+  return xmalloc (sizeof(struct dfa));
+}
+
+struct dfamust *
+dfamusts (struct dfa *d)
+{
+  return d->musts;
+}
+
+#ifdef GAWK
+int dfabroken (struct dfa * d)
+{
+  return d->broken;
+}
+#endif
 /* vim:set shiftwidth=2: */
diff --git a/src/dfa.h b/src/dfa.h
index afa258b..0721cc0 100644
--- a/src/dfa.h
+++ b/src/dfa.h
@@ -18,127 +18,6 @@
 
 /* Written June, 1988 by Mike Haertel */
 
-/* FIXME:
-   2.  We should not export so much of the DFA internals.
-   In addition to clobbering modularity, we eat up valuable
-   name space. */
-
-/* Number of bits in an unsigned char. */
-#ifndef CHARBITS
-#define CHARBITS 8
-#endif
-
-/* First integer value that is greater than any character code. */
-#define NOTCHAR (1 << CHARBITS)
-
-/* INTBITS need not be exact, just a lower bound. */
-#ifndef INTBITS
-#define INTBITS (CHARBITS * sizeof (int))
-#endif
-
-/* Number of ints required to hold a bit for every character. */
-#define CHARCLASS_INTS ((NOTCHAR + INTBITS - 1) / INTBITS)
-
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
-# define __attribute__(x)
-#endif
-
-/* Sets of unsigned characters are stored as bit vectors in arrays of ints. */
-typedef int charclass[CHARCLASS_INTS];
-
-enum token_enum;
-typedef enum token_enum token;
-
-/* Sets are stored in an array in the compiled dfa; the index of the
-   array corresponding to a given set token is given by SET_INDEX(t). */
-#define SET_INDEX(t) ((t) - CSET)
-
-/* Sometimes characters can only be matched depending on the surrounding
-   context.  Such context decisions depend on what the previous character
-   was, and the value of the current (lookahead) character.  Context
-   dependent constraints are encoded as 8 bit integers.  Each bit that
-   is set indicates that the constraint succeeds in the corresponding
-   context.
-
-   bit 7 - previous and current are newlines
-   bit 6 - previous was newline, current isn't
-   bit 5 - previous wasn't newline, current is
-   bit 4 - neither previous nor current is a newline
-   bit 3 - previous and current are word-constituents
-   bit 2 - previous was word-constituent, current isn't
-   bit 1 - previous wasn't word-constituent, current is
-   bit 0 - neither previous nor current is word-constituent
-
-   Word-constituent characters are those that satisfy isalnum().
-
-   The macro SUCCEEDS_IN_CONTEXT determines whether a a given constraint
-   succeeds in a particular context.  Prevn is true if the previous character
-   was a newline, currn is true if the lookahead character is a newline.
-   Prevl and currl similarly depend upon whether the previous and current
-   characters are word-constituent letters. */
-#define MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn) \
-  ((constraint) & 1 << (((prevn) ? 2 : 0) + ((currn) ? 1 : 0) + 4))
-#define MATCHES_LETTER_CONTEXT(constraint, prevl, currl) \
-  ((constraint) & 1 << (((prevl) ? 2 : 0) + ((currl) ? 1 : 0)))
-#define SUCCEEDS_IN_CONTEXT(constraint, prevn, currn, prevl, currl) \
-  (MATCHES_NEWLINE_CONTEXT(constraint, prevn, currn)                \
-   && MATCHES_LETTER_CONTEXT(constraint, prevl, currl))
-
-/* The following macros give information about what a constraint depends on. */
-#define PREV_NEWLINE_DEPENDENT(constraint) \
-  (((constraint) & 0xc0) >> 2 != ((constraint) & 0x30))
-#define PREV_LETTER_DEPENDENT(constraint) \
-  (((constraint) & 0x0c) >> 2 != ((constraint) & 0x03))
-
-/* Tokens that match the empty string subject to some constraint actually
-   work by applying that constraint to determine what may follow them,
-   taking into account what has gone before.  The following values are
-   the constraints corresponding to the special tokens previously defined. */
-#define NO_CONSTRAINT 0xff
-#define BEGLINE_CONSTRAINT 0xcf
-#define ENDLINE_CONSTRAINT 0xaf
-#define BEGWORD_CONSTRAINT 0xf2
-#define ENDWORD_CONSTRAINT 0xf4
-#define LIMWORD_CONSTRAINT 0xf6
-#define NOTLIMWORD_CONSTRAINT 0xf9
-
-/* States of the recognizer correspond to sets of positions in the parse
-   tree, together with the constraints under which they may be matched.
-   So a position is encoded as an index into the parse tree together with
-   a constraint. */
-typedef struct
-{
-  unsigned int index;          /* Index into the parse array. */
-  unsigned int constraint;     /* Constraint for matching this position. */
-} position;
-
-/* Sets of positions are stored as arrays. */
-typedef struct
-{
-  position *elems;             /* Elements of this position set. */
-  int nelem;                   /* Number of elements in this set. */
-} position_set;
-
-/* A state of the dfa consists of a set of positions, some flags,
-   and the token value of the lowest-numbered position of the state that
-   contains an END token. */
-typedef struct
-{
-  int hash;                    /* Hash of the positions of this state. */
-  position_set elems;          /* Positions this state could match. */
-  char newline;                        /* True if previous state matched 
newline. */
-  char letter;                 /* True if previous state matched a letter. */
-  char backref;                        /* True if this state matches a 
\<digit>. */
-  unsigned char constraint;    /* Constraint for this state to accept. */
-  int first_end;               /* Token value of the first END in elems. */
-#if MBS_SUPPORT
-  position_set mbps;           /* Positions which can match multibyte
-                                  characters.  e.g. period.
-                                 These staff are used only if
-                                 MB_CUR_MAX > 1.  */
-#endif
-} dfa_state;
-
 /* Element of a list of strings, at least one of which is known to
    appear in any R.E. matching the DFA. */
 struct dfamust
@@ -148,147 +27,18 @@ struct dfamust
   struct dfamust *next;
 };
 
-#if MBS_SUPPORT
-/* A bracket operator.
-   e.g. [a-c], [[:alpha:]], etc.  */
-struct mb_char_classes
-{
-  int cset;
-  int invert;
-  wchar_t *chars;              /* Normal characters.  */
-  int nchars;
-  wctype_t *ch_classes;                /* Character classes.  */
-  int nch_classes;
-  wchar_t *range_sts;          /* Range characters (start of the range).  */
-  wchar_t *range_ends;         /* Range characters (end of the range).  */
-  int nranges;
-  char **equivs;               /* Equivalent classes.  */
-  int nequivs;
-  char **coll_elems;
-  int ncoll_elems;             /* Collating elements.  */
-};
-#endif
-
-/* A compiled regular expression. */
-struct dfa
-{
-  /* Fields filled by the scanner. */
-  charclass *charclasses;      /* Array of character sets for CSET tokens. */
-  int cindex;                  /* Index for adding new charclasses. */
-  int calloc;                  /* Number of charclasses currently allocated. */
-
-  /* Fields filled by the parser. */
-  token *tokens;               /* Postfix parse array. */
-  int tindex;                  /* Index for adding new tokens. */
-  int talloc;                  /* Number of tokens currently allocated. */
-  int depth;                   /* Depth required of an evaluation stack
-                                  used for depth-first traversal of the
-                                  parse tree. */
-  int nleaves;                 /* Number of leaves on the parse tree. */
-  int nregexps;                        /* Count of parallel regexps being built
-                                  with dfaparse(). */
-#if MBS_SUPPORT
-  unsigned int mb_cur_max;     /* Cached value of MB_CUR_MAX.  */
-
-  /* The following are used only if MB_CUR_MAX > 1.  */
-
-  /* The value of multibyte_prop[i] is defined by following rule.
-       if tokens[i] < NOTCHAR
-         bit 0 : tokens[i] is the first byte of a character, including
-                 single-byte characters.
-         bit 1 : tokens[i] is the last byte of a character, including
-                 single-byte characters.
-
-       if tokens[i] = MBCSET
-         ("the index of mbcsets correspnd to this operator" << 2) + 3
-
-     e.g.
-     tokens
-        = 'single_byte_a', 'multi_byte_A', single_byte_b'
-        = 'sb_a', 'mb_A(1st byte)', 'mb_A(2nd byte)', 'mb_A(3rd byte)', 'sb_b'
-     multibyte_prop
-        = 3     , 1               ,  0              ,  2              , 3
-  */
-  int nmultibyte_prop;
-  int *multibyte_prop;
-
-  /* Array of the bracket expression in the DFA.  */
-  struct mb_char_classes *mbcsets;
-  int nmbcsets;
-  int mbcsets_alloc;
-#endif
-
-  /* Fields filled by the state builder. */
-  dfa_state *states;           /* States of the dfa. */
-  int sindex;                  /* Index for adding new states. */
-  int salloc;                  /* Number of states currently allocated. */
-
-  /* Fields filled by the parse tree->NFA conversion. */
-  position_set *follows;       /* Array of follow sets, indexed by position
-                                  index.  The follow of a position is the set
-                                  of positions containing characters that
-                                  could conceivably follow a character
-                                  matching the given position in a string
-                                  matching the regexp.  Allocated to the
-                                  maximum possible position index. */
-  int searchflag;              /* True if we are supposed to build a searching
-                                  as opposed to an exact matcher.  A searching
-                                  matcher finds the first and shortest string
-                                  matching a regexp anywhere in the buffer,
-                                  whereas an exact matcher finds the longest
-                                  string matching, but anchored to the
-                                  beginning of the buffer. */
+/* The dfa structure. It is completely opaque. */
+struct dfa;
 
-  /* Fields filled by dfaexec. */
-  int tralloc;                 /* Number of transition tables that have
-                                  slots so far. */
-  int trcount;                 /* Number of transition tables that have
-                                  actually been built. */
-  int **trans;                 /* Transition tables for states that can
-                                  never accept.  If the transitions for a
-                                  state have not yet been computed, or the
-                                  state could possibly accept, its entry in
-                                  this table is NULL. */
-  int **realtrans;             /* Trans always points to realtrans + 1; this
-                                  is so trans[-1] can contain NULL. */
-  int **fails;                 /* Transition tables after failing to accept
-                                  on a state that potentially could do so. */
-  int *success;                        /* Table of acceptance conditions used 
in
-                                  dfaexec and computed in build_state. */
-  int *newlines;               /* Transitions on newlines.  The entry for a
-                                  newline in any transition table is always
-                                  -1 so we can count lines without wasting
-                                  too many cycles.  The transition for a
-                                  newline is stored separately and handled
-                                  as a special case.  Newline is also used
-                                  as a sentinel at the end of the buffer. */
-  struct dfamust *musts;       /* List of strings, at least one of which
-                                  is known to appear in any r.e. matching
-                                  the dfa. */
-
-#ifdef GAWK
-  int broken;                  /* True if using a feature where there
-                                  are bugs and gawk should use regex. */
-#endif
-};
-
-/* Some macros for user access to dfa internals. */
-
-/* ACCEPTING returns true if s could possibly be an accepting state of r. */
-#define ACCEPTING(s, r) ((r).states[s].constraint)
-
-/* ACCEPTS_IN_CONTEXT returns true if the given state accepts in the
-   specified context. */
-#define ACCEPTS_IN_CONTEXT(prevn, currn, prevl, currl, state, dfa) \
-  SUCCEEDS_IN_CONTEXT((dfa).states[state].constraint,             \
-                      prevn, currn, prevl, currl)
+/* Entry points. */
 
-/* FIRST_MATCHING_REGEXP returns the index number of the first of parallel
-   regexps that a given state could accept.  Parallel regexps are numbered
-   starting at 1. */
-#define FIRST_MATCHING_REGEXP(state, dfa) (-(dfa).states[state].first_end)
+/* Allocate a struct dfa.  The struct dfa is completely opaque.
+   The returned pointer should be passed directly to free() after
+   calling dfafree() on it. */
+extern struct dfa *dfaalloc ();
 
-/* Entry points. */
+/* Return the dfamusts associated with a dfa. */
+extern struct dfamust *dfamusts (struct dfa *);
 
 /* dfasyntax() takes three arguments; the first sets the syntax bits described
    earlier in this file, the second sets the case-folding flag, and the
@@ -340,3 +90,9 @@ extern void dfastate (int, struct dfa *, int []);
    takes a single argument, a NUL-terminated string describing the error.
    The user must supply a dfaerror.  */
 extern void dfaerror (const char *) __attribute__ ((noreturn));
+
+#ifdef GAWK
+/* Returns true if the regex is one where the dfa matcher
+   is broken and thus should not be used. */
+extern int dfabroken (struct dfa *);
+#endif
diff --git a/src/dfasearch.c b/src/dfasearch.c
index 08f3767..cf87b90 100644
--- a/src/dfasearch.c
+++ b/src/dfasearch.c
@@ -31,7 +31,7 @@
 static kwset_t kwset;
 
 /* DFA compiled regexp. */
-static struct dfa dfa;
+static struct dfa *dfa;
 
 /* The Regex compiled patterns.  */
 static struct patterns
@@ -86,13 +86,14 @@ kwsmusts (void)
   struct dfamust const *dm;
   char const *err;
 
-  if (dfa.musts)
+  dm = dfamusts (dfa);
+  if (dm)
     {
       kwsinit (&kwset);
       /* First, we compile in the substrings known to be exact
         matches.  The kwset matcher will return the index
         of the matching string that it chooses. */
-      for (dm = dfa.musts; dm; dm = dm->next)
+      for (; dm; dm = dm->next)
        {
          if (!dm->exact)
            continue;
@@ -102,7 +103,7 @@ kwsmusts (void)
        }
       /* Now, we compile the substrings that will require
         the use of the regexp matcher.  */
-      for (dm = dfa.musts; dm; dm = dm->next)
+      for (dm = dfamusts (dfa); dm; dm = dm->next)
        {
          if (dm->exact)
            continue;
@@ -192,7 +193,8 @@ GEAcompile (char const *pattern, size_t size, reg_syntax_t 
syntax_bits)
   else
     motif = NULL;
 
-  dfacomp (pattern, size, &dfa, 1);
+  dfa = dfaalloc ();
+  dfacomp (pattern, size, dfa, 1);
   kwsmusts ();
 
   free(motif);
@@ -257,13 +259,13 @@ EGexecute (char const *buf, size_t size, size_t 
*match_size,
 #endif
                     goto success;
                 }
-             if (dfaexec (&dfa, beg, (char *) end, 0, NULL, &backref) == NULL)
+             if (dfaexec (dfa, beg, (char *) end, 0, NULL, &backref) == NULL)
                continue;
            }
          else
            {
              /* No good fixed strings; start with DFA. */
-             char const *next_beg = dfaexec (&dfa, beg, (char *) buflim,
+             char const *next_beg = dfaexec (dfa, beg, (char *) buflim,
                                              0, NULL, &backref);
              if (next_beg == NULL)
                break;
-- 
1.5.3.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]