/[cvs]/ccvs/lib/regcomp.c
ViewVC logotype

Diff of /ccvs/lib/regcomp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by dprice, Fri Aug 12 20:58:10 2005 UTC revision 1.2 by dprice, Sun Sep 4 05:58:56 2005 UTC
# Line 18  Line 18 
18     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19    
20  static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,  static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
21                                            int length, reg_syntax_t syntax);                                            Idx length, reg_syntax_t syntax);
22  static void re_compile_fastmap_iter (regex_t *bufp,  static void re_compile_fastmap_iter (regex_t *bufp,
23                                       const re_dfastate_t *init_state,                                       const re_dfastate_t *init_state,
24                                       char *fastmap);                                       char *fastmap);
25  static reg_errcode_t init_dfa (re_dfa_t *dfa, int pat_len);  static reg_errcode_t init_dfa (re_dfa_t *dfa, Idx pat_len);
 static void init_word_char (re_dfa_t *dfa);  
26  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
27  static void free_charset (re_charset_t *cset);  static void free_charset (re_charset_t *cset);
28  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
# Line 33  static reg_errcode_t create_initial_stat Line 32  static reg_errcode_t create_initial_stat
32  static void optimize_utf8 (re_dfa_t *dfa);  static void optimize_utf8 (re_dfa_t *dfa);
33  #endif  #endif
34  static reg_errcode_t analyze (regex_t *preg);  static reg_errcode_t analyze (regex_t *preg);
 static reg_errcode_t create_initial_state (re_dfa_t *dfa);  
35  static reg_errcode_t preorder (bin_tree_t *root,  static reg_errcode_t preorder (bin_tree_t *root,
36                                 reg_errcode_t (fn (void *, bin_tree_t *)),                                 reg_errcode_t (fn (void *, bin_tree_t *)),
37                                 void *extra);                                 void *extra);
# Line 47  static bin_tree_t *lower_subexp (reg_err Line 45  static bin_tree_t *lower_subexp (reg_err
45  static reg_errcode_t calc_first (void *extra, bin_tree_t *node);  static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
46  static reg_errcode_t calc_next (void *extra, bin_tree_t *node);  static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
47  static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);  static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
48  static reg_errcode_t duplicate_node_closure (re_dfa_t *dfa, int top_org_node,  static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
49                                               int top_clone_node, int root_node,  static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
                                              unsigned int constraint);  
 static reg_errcode_t duplicate_node (int *new_idx, re_dfa_t *dfa, int org_idx,  
                                      unsigned int constraint);  
 static int search_duplicated_node (re_dfa_t *dfa, int org_node,  
50                                     unsigned int constraint);                                     unsigned int constraint);
51  static reg_errcode_t calc_eclosure (re_dfa_t *dfa);  static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
52  static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,  static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
53                                           int node, int root);                                           Idx node, bool root);
54  static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);  static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
55  static int fetch_number (re_string_t *input, re_token_t *token,  static Idx fetch_number (re_string_t *input, re_token_t *token,
                          reg_syntax_t syntax);  
 static void fetch_token (re_token_t *result, re_string_t *input,  
56                           reg_syntax_t syntax);                           reg_syntax_t syntax);
57  static int peek_token (re_token_t *token, re_string_t *input,  static int peek_token (re_token_t *token, re_string_t *input,
58                          reg_syntax_t syntax);                          reg_syntax_t syntax);
 static int peek_token_bracket (re_token_t *token, re_string_t *input,  
                                reg_syntax_t syntax);  
59  static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,  static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
60                            reg_syntax_t syntax, reg_errcode_t *err);                            reg_syntax_t syntax, reg_errcode_t *err);
61  static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,  static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
62                                    re_token_t *token, reg_syntax_t syntax,                                    re_token_t *token, reg_syntax_t syntax,
63                                    int nest, reg_errcode_t *err);                                    Idx nest, reg_errcode_t *err);
64  static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,  static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
65                                   re_token_t *token, reg_syntax_t syntax,                                   re_token_t *token, reg_syntax_t syntax,
66                                   int nest, reg_errcode_t *err);                                   Idx nest, reg_errcode_t *err);
67  static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,  static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
68                                       re_token_t *token, reg_syntax_t syntax,                                       re_token_t *token, reg_syntax_t syntax,
69                                       int nest, reg_errcode_t *err);                                       Idx nest, reg_errcode_t *err);
70  static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,  static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
71                                    re_token_t *token, reg_syntax_t syntax,                                    re_token_t *token, reg_syntax_t syntax,
72                                    int nest, reg_errcode_t *err);                                    Idx nest, reg_errcode_t *err);
73  static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,  static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
74                                   re_dfa_t *dfa, re_token_t *token,                                   re_dfa_t *dfa, re_token_t *token,
75                                   reg_syntax_t syntax, reg_errcode_t *err);                                   reg_syntax_t syntax, reg_errcode_t *err);
# Line 91  static reg_errcode_t parse_bracket_eleme Line 81  static reg_errcode_t parse_bracket_eleme
81                                              re_token_t *token, int token_len,                                              re_token_t *token, int token_len,
82                                              re_dfa_t *dfa,                                              re_dfa_t *dfa,
83                                              reg_syntax_t syntax,                                              reg_syntax_t syntax,
84                                              int accept_hyphen);                                              bool accept_hyphen);
85  static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,  static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
86                                            re_string_t *regexp,                                            re_string_t *regexp,
87                                            re_token_t *token);                                            re_token_t *token);
 #ifndef _LIBC  
 # ifdef RE_ENABLE_I18N  
 static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,  
                                       re_charset_t *mbcset, int *range_alloc,  
                                       bracket_elem_t *start_elem,  
                                       bracket_elem_t *end_elem);  
 static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,  
                                              re_charset_t *mbcset,  
                                              int *coll_sym_alloc,  
                                              const unsigned char *name);  
 # else /* not RE_ENABLE_I18N */  
 static reg_errcode_t build_range_exp (re_bitset_ptr_t sbcset,  
                                       bracket_elem_t *start_elem,  
                                       bracket_elem_t *end_elem);  
 static reg_errcode_t build_collating_symbol (re_bitset_ptr_t sbcset,  
                                              const unsigned char *name);  
 # endif /* not RE_ENABLE_I18N */  
 #endif /* not _LIBC */  
88  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
89  static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,  static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
90                                          re_charset_t *mbcset,                                          re_charset_t *mbcset,
91                                          int *equiv_class_alloc,                                          Idx *equiv_class_alloc,
92                                          const unsigned char *name);                                          const unsigned char *name);
93  static reg_errcode_t build_charclass (unsigned RE_TRANSLATE_TYPE trans,  static reg_errcode_t build_charclass (unsigned REG_TRANSLATE_TYPE trans,
94                                        re_bitset_ptr_t sbcset,                                        re_bitset_ptr_t sbcset,
95                                        re_charset_t *mbcset,                                        re_charset_t *mbcset,
96                                        int *char_class_alloc,                                        Idx *char_class_alloc,
97                                        const unsigned char *class_name,                                        const unsigned char *class_name,
98                                        reg_syntax_t syntax);                                        reg_syntax_t syntax);
99  #else  /* not RE_ENABLE_I18N */  #else  /* not RE_ENABLE_I18N */
100  static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,  static reg_errcode_t build_equiv_class (re_bitset_ptr_t sbcset,
101                                          const unsigned char *name);                                          const unsigned char *name);
102  static reg_errcode_t build_charclass (unsigned RE_TRANSLATE_TYPE trans,  static reg_errcode_t build_charclass (unsigned REG_TRANSLATE_TYPE trans,
103                                        re_bitset_ptr_t sbcset,                                        re_bitset_ptr_t sbcset,
104                                        const unsigned char *class_name,                                        const unsigned char *class_name,
105                                        reg_syntax_t syntax);                                        reg_syntax_t syntax);
106  #endif /* not RE_ENABLE_I18N */  #endif /* not RE_ENABLE_I18N */
107  static bin_tree_t *build_charclass_op (re_dfa_t *dfa,  static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
108                                         unsigned RE_TRANSLATE_TYPE trans,                                         unsigned REG_TRANSLATE_TYPE trans,
109                                         const unsigned char *class_name,                                         const unsigned char *class_name,
110                                         const unsigned char *extra,                                         const unsigned char *extra,
111                                         int non_match, reg_errcode_t *err);                                         bool non_match, reg_errcode_t *err);
112  static bin_tree_t *create_tree (re_dfa_t *dfa,  static bin_tree_t *create_tree (re_dfa_t *dfa,
113                                  bin_tree_t *left, bin_tree_t *right,                                  bin_tree_t *left, bin_tree_t *right,
114                                  re_token_type_t type);                                  re_token_type_t type);
# Line 234  const size_t __re_error_msgid_idx[] attr Line 206  const size_t __re_error_msgid_idx[] attr
206     compiles PATTERN (of length LENGTH) and puts the result in BUFP.     compiles PATTERN (of length LENGTH) and puts the result in BUFP.
207     Returns 0 if the pattern was valid, otherwise an error string.     Returns 0 if the pattern was valid, otherwise an error string.
208    
209     Assumes the `allocated' (and perhaps `buffer') and `translate' fields     Assumes the `re_allocated' (and perhaps `re_buffer') and `translate' fields
210     are set in BUFP on entry.  */     are set in BUFP on entry.  */
211    
212  const char *  const char *
213  re_compile_pattern (pattern, length, bufp)  re_compile_pattern (const char *pattern, size_t length,
214      const char *pattern;                      struct re_pattern_buffer *bufp)
     size_t length;  
     struct re_pattern_buffer *bufp;  
215  {  {
216    reg_errcode_t ret;    reg_errcode_t ret;
217    
218    /* And GNU code determines whether or not to get register information    /* And GNU code determines whether or not to get register information
219       by passing null for the REGS argument to re_match, etc., not by       by passing null for the REGS argument to re_match, etc., not by
220       setting no_sub, unless RE_NO_SUB is set.  */       setting re_no_sub, unless REG_NO_SUB is set.  */
221    bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);    bufp->re_no_sub = !!(re_syntax_options & REG_NO_SUB);
222    
223    /* Match anchors at newline.  */    /* Match anchors at newline.  */
224    bufp->newline_anchor = 1;    bufp->re_newline_anchor = 1;
225    
226    ret = re_compile_internal (bufp, pattern, length, re_syntax_options);    ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
227    
# Line 279  reg_syntax_t re_syntax_options; Line 249  reg_syntax_t re_syntax_options;
249     defined in regex.h.  We return the old syntax.  */     defined in regex.h.  We return the old syntax.  */
250    
251  reg_syntax_t  reg_syntax_t
252  re_set_syntax (syntax)  re_set_syntax (reg_syntax_t syntax)
     reg_syntax_t syntax;  
253  {  {
254    reg_syntax_t ret = re_syntax_options;    reg_syntax_t ret = re_syntax_options;
255    
# Line 292  weak_alias (__re_set_syntax, re_set_synt Line 261  weak_alias (__re_set_syntax, re_set_synt
261  #endif  #endif
262    
263  int  int
264  re_compile_fastmap (bufp)  re_compile_fastmap (struct re_pattern_buffer *bufp)
     struct re_pattern_buffer *bufp;  
265  {  {
266    re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;    re_dfa_t *dfa = (re_dfa_t *) bufp->re_buffer;
267    char *fastmap = bufp->fastmap;    char *fastmap = bufp->re_fastmap;
268    
269    memset (fastmap, '\0', sizeof (char) * SBC_MAX);    memset (fastmap, '\0', sizeof (char) * SBC_MAX);
270    re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);    re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
# Line 306  re_compile_fastmap (bufp) Line 274  re_compile_fastmap (bufp)
274      re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);      re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
275    if (dfa->init_state != dfa->init_state_begbuf)    if (dfa->init_state != dfa->init_state_begbuf)
276      re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);      re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
277    bufp->fastmap_accurate = 1;    bufp->re_fastmap_accurate = 1;
278    return 0;    return 0;
279  }  }
280  #ifdef _LIBC  #ifdef _LIBC
# Line 315  weak_alias (__re_compile_fastmap, re_com Line 283  weak_alias (__re_compile_fastmap, re_com
283    
284  static inline void  static inline void
285  __attribute ((always_inline))  __attribute ((always_inline))
286  re_set_fastmap (char *fastmap, int icase, int ch)  re_set_fastmap (char *fastmap, bool icase, int ch)
287  {  {
288    fastmap[ch] = 1;    fastmap[ch] = 1;
289    if (icase)    if (icase)
# Line 326  re_set_fastmap (char *fastmap, int icase Line 294  re_set_fastmap (char *fastmap, int icase
294     Compile fastmap for the initial_state INIT_STATE.  */     Compile fastmap for the initial_state INIT_STATE.  */
295    
296  static void  static void
297  re_compile_fastmap_iter (bufp, init_state, fastmap)  re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
298       regex_t *bufp;                           char *fastmap)
299       const re_dfastate_t *init_state;  {
300       char *fastmap;    re_dfa_t *dfa = (re_dfa_t *) bufp->re_buffer;
301  {    Idx node_cnt;
302    re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;    bool icase = (dfa->mb_cur_max == 1 && (bufp->re_syntax & REG_IGNORE_CASE));
   int node_cnt;  
   int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));  
303    for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)    for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
304      {      {
305        int node = init_state->nodes.elems[node_cnt];        Idx node = init_state->nodes.elems[node_cnt];
306        re_token_type_t type = dfa->nodes[node].type;        re_token_type_t type = dfa->nodes[node].type;
307    
308        if (type == CHARACTER)        if (type == CHARACTER)
309          {          {
310            re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);            re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
311  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
312            if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)            if ((bufp->re_syntax & REG_IGNORE_CASE) && dfa->mb_cur_max > 1)
313              {              {
314                unsigned char *buf = alloca (dfa->mb_cur_max), *p;                unsigned char buf[MB_LEN_MAX];
315                  unsigned char *p;
316                wchar_t wc;                wchar_t wc;
317                mbstate_t state;                mbstate_t state;
318    
# Line 360  re_compile_fastmap_iter (bufp, init_stat Line 327  re_compile_fastmap_iter (bufp, init_stat
327                             &state) == p - buf                             &state) == p - buf
328                    && (__wcrtomb ((char *) buf, towlower (wc), &state)                    && (__wcrtomb ((char *) buf, towlower (wc), &state)
329                        != (size_t) -1))                        != (size_t) -1))
330                  re_set_fastmap (fastmap, 0, buf[0]);                  re_set_fastmap (fastmap, false, buf[0]);
331              }              }
332  #endif  #endif
333          }          }
# Line 369  re_compile_fastmap_iter (bufp, init_stat Line 336  re_compile_fastmap_iter (bufp, init_stat
336            int i, j, ch;            int i, j, ch;
337            for (i = 0, ch = 0; i < BITSET_UINTS; ++i)            for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
338              for (j = 0; j < UINT_BITS; ++j, ++ch)              for (j = 0; j < UINT_BITS; ++j, ++ch)
339                if (dfa->nodes[node].opr.sbcset[i] & (1 << j))                if (dfa->nodes[node].opr.sbcset[i] & (1u << j))
340                  re_set_fastmap (fastmap, icase, ch);                  re_set_fastmap (fastmap, icase, ch);
341          }          }
342  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
343        else if (type == COMPLEX_BRACKET)        else if (type == COMPLEX_BRACKET)
344          {          {
345            int i;            Idx i;
346            re_charset_t *cset = dfa->nodes[node].opr.mbcset;            re_charset_t *cset = dfa->nodes[node].opr.mbcset;
347            if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes            if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
348                || cset->nranges || cset->nchar_classes)                || cset->nranges || cset->nchar_classes)
# Line 411  re_compile_fastmap_iter (bufp, init_stat Line 378  re_compile_fastmap_iter (bufp, init_stat
378                memset (&state, '\0', sizeof (state));                memset (&state, '\0', sizeof (state));
379                if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)                if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
380                  re_set_fastmap (fastmap, icase, *(unsigned char *) buf);                  re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
381                if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)                if ((bufp->re_syntax & REG_IGNORE_CASE) && dfa->mb_cur_max > 1)
382                  {                  {
383                    if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)                    if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
384                        != (size_t) -1)                        != (size_t) -1)
385                      re_set_fastmap (fastmap, 0, *(unsigned char *) buf);                      re_set_fastmap (fastmap, false, *(unsigned char *) buf);
386                  }                  }
387              }              }
388          }          }
# Line 428  re_compile_fastmap_iter (bufp, init_stat Line 395  re_compile_fastmap_iter (bufp, init_stat
395          {          {
396            memset (fastmap, '\1', sizeof (char) * SBC_MAX);            memset (fastmap, '\1', sizeof (char) * SBC_MAX);
397            if (type == END_OF_RE)            if (type == END_OF_RE)
398              bufp->can_be_null = 1;              bufp->re_can_be_null = 1;
399            return;            return;
400          }          }
401      }      }
# Line 440  re_compile_fastmap_iter (bufp, init_stat Line 407  re_compile_fastmap_iter (bufp, init_stat
407     PREG is a regex_t *.  We do not expect any fields to be initialized,     PREG is a regex_t *.  We do not expect any fields to be initialized,
408     since POSIX says we shouldn't.  Thus, we set     since POSIX says we shouldn't.  Thus, we set
409    
410       `buffer' to the compiled pattern;       `re_buffer' to the compiled pattern;
411       `used' to the length of the compiled pattern;       `re_used' to the length of the compiled pattern;
412       `syntax' to RE_SYNTAX_POSIX_EXTENDED if the       `re_syntax' to REG_SYNTAX_POSIX_EXTENDED if the
413         REG_EXTENDED bit in CFLAGS is set; otherwise, to         REG_EXTENDED bit in CFLAGS is set; otherwise, to
414         RE_SYNTAX_POSIX_BASIC;         REG_SYNTAX_POSIX_BASIC;
415       `newline_anchor' to REG_NEWLINE being set in CFLAGS;       `re_newline_anchor' to REG_NEWLINE being set in CFLAGS;
416       `fastmap' to an allocated space for the fastmap;       `re_fastmap' to an allocated space for the fastmap;
417       `fastmap_accurate' to zero;       `re_fastmap_accurate' to zero;
418       `re_nsub' to the number of subexpressions in PATTERN.       `re_nsub' to the number of subexpressions in PATTERN.
419    
420     PATTERN is the address of the pattern string.     PATTERN is the address of the pattern string.
# Line 471  re_compile_fastmap_iter (bufp, init_stat Line 438  re_compile_fastmap_iter (bufp, init_stat
438     the return codes and their meanings.)  */     the return codes and their meanings.)  */
439    
440  int  int
441  regcomp (preg, pattern, cflags)  regcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags)
     regex_t *__restrict preg;  
     const char *__restrict pattern;  
     int cflags;  
442  {  {
443    reg_errcode_t ret;    reg_errcode_t ret;
444    reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED    reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? REG_SYNTAX_POSIX_EXTENDED
445                           : RE_SYNTAX_POSIX_BASIC);                          : REG_SYNTAX_POSIX_BASIC);
446    
447    preg->buffer = NULL;    preg->re_buffer = NULL;
448    preg->allocated = 0;    preg->re_allocated = 0;
449    preg->used = 0;    preg->re_used = 0;
450    
451    /* Try to allocate space for the fastmap.  */    /* Try to allocate space for the fastmap.  */
452    preg->fastmap = re_malloc (char, SBC_MAX);    preg->re_fastmap = re_malloc (char, SBC_MAX);
453    if (BE (preg->fastmap == NULL, 0))    if (BE (preg->re_fastmap == NULL, 0))
454      return REG_ESPACE;      return REG_ESPACE;
455    
456    syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;    syntax |= (cflags & REG_ICASE) ? REG_IGNORE_CASE : 0;
457    
458    /* If REG_NEWLINE is set, newlines are treated differently.  */    /* If REG_NEWLINE is set, newlines are treated differently.  */
459    if (cflags & REG_NEWLINE)    if (cflags & REG_NEWLINE)
460      { /* REG_NEWLINE implies neither . nor [^...] match newline.  */      { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
461        syntax &= ~RE_DOT_NEWLINE;        syntax &= ~REG_DOT_NEWLINE;
462        syntax |= RE_HAT_LISTS_NOT_NEWLINE;        syntax |= REG_HAT_LISTS_NOT_NEWLINE;
463        /* It also changes the matching behavior.  */        /* It also changes the matching behavior.  */
464        preg->newline_anchor = 1;        preg->re_newline_anchor = 1;
465      }      }
466    else    else
467      preg->newline_anchor = 0;      preg->re_newline_anchor = 0;
468    preg->no_sub = !!(cflags & REG_NOSUB);    preg->re_no_sub = !!(cflags & REG_NOSUB);
469    preg->translate = NULL;    preg->re_translate = NULL;
470    
471    ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);    ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
472    
# Line 511  regcomp (preg, pattern, cflags) Line 475  regcomp (preg, pattern, cflags)
475    if (ret == REG_ERPAREN)    if (ret == REG_ERPAREN)
476      ret = REG_EPAREN;      ret = REG_EPAREN;
477    
478    /* We have already checked preg->fastmap != NULL.  */    /* We have already checked preg->re_fastmap != NULL.  */
479    if (BE (ret == REG_NOERROR, 1))    if (BE (ret == REG_NOERROR, 1))
480      /* Compute the fastmap now, since regexec cannot modify the pattern      /* Compute the fastmap now, since regexec cannot modify the pattern
481         buffer.  This function never fails in this implementation.  */         buffer.  This function never fails in this implementation.  */
# Line 519  regcomp (preg, pattern, cflags) Line 483  regcomp (preg, pattern, cflags)
483    else    else
484      {      {
485        /* Some error occurred while compiling the expression.  */        /* Some error occurred while compiling the expression.  */
486        re_free (preg->fastmap);        re_free (preg->re_fastmap);
487        preg->fastmap = NULL;        preg->re_fastmap = NULL;
488      }      }
489    
490    return (int) ret;    return (int) ret;
# Line 533  weak_alias (__regcomp, regcomp) Line 497  weak_alias (__regcomp, regcomp)
497     from either regcomp or regexec.   We don't use PREG here.  */     from either regcomp or regexec.   We don't use PREG here.  */
498    
499  size_t  size_t
500  regerror (errcode, preg, errbuf, errbuf_size)  regerror (int errcode, const regex_t *__restrict preg,
501      int errcode;            char *__restrict errbuf, size_t errbuf_size)
     const regex_t *preg;  
     char *errbuf;  
     size_t errbuf_size;  
502  {  {
503    const char *msg;    const char *msg;
504    size_t msg_size;    size_t msg_size;
# Line 597  static const bitset utf8_sb_map = Line 558  static const bitset utf8_sb_map =
558  static void  static void
559  free_dfa_content (re_dfa_t *dfa)  free_dfa_content (re_dfa_t *dfa)
560  {  {
561    int i, j;    Idx i, j;
562    
563    if (dfa->nodes)    if (dfa->nodes)
564      for (i = 0; i < dfa->nodes_len; ++i)      for (i = 0; i < dfa->nodes_len; ++i)
# Line 645  free_dfa_content (re_dfa_t *dfa) Line 606  free_dfa_content (re_dfa_t *dfa)
606  /* Free dynamically allocated space used by PREG.  */  /* Free dynamically allocated space used by PREG.  */
607    
608  void  void
609  regfree (preg)  regfree (regex_t *preg)
     regex_t *preg;  
610  {  {
611    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
612    if (BE (dfa != NULL, 1))    if (BE (dfa != NULL, 1))
613      free_dfa_content (dfa);      free_dfa_content (dfa);
614    preg->buffer = NULL;    preg->re_buffer = NULL;
615    preg->allocated = 0;    preg->re_allocated = 0;
616    
617    re_free (preg->fastmap);    re_free (preg->re_fastmap);
618    preg->fastmap = NULL;    preg->re_fastmap = NULL;
619    
620    re_free (preg->translate);    re_free (preg->re_translate);
621    preg->translate = NULL;    preg->re_translate = NULL;
622  }  }
623  #ifdef _LIBC  #ifdef _LIBC
624  weak_alias (__regfree, regfree)  weak_alias (__regfree, regfree)
# Line 679  char * Line 639  char *
639     regcomp/regexec above without link errors.  */     regcomp/regexec above without link errors.  */
640  weak_function  weak_function
641  # endif  # endif
642  re_comp (s)  re_comp (const char *s)
      const char *s;  
643  {  {
644    reg_errcode_t ret;    reg_errcode_t ret;
645    char *fastmap;    char *fastmap;
646    
647    if (!s)    if (!s)
648      {      {
649        if (!re_comp_buf.buffer)        if (!re_comp_buf.re_buffer)
650          return gettext ("No previous regular expression");          return gettext ("No previous regular expression");
651        return 0;        return 0;
652      }      }
653    
654    if (re_comp_buf.buffer)    if (re_comp_buf.re_buffer)
655      {      {
656        fastmap = re_comp_buf.fastmap;        fastmap = re_comp_buf.re_fastmap;
657        re_comp_buf.fastmap = NULL;        re_comp_buf.re_fastmap = NULL;
658        __regfree (&re_comp_buf);        __regfree (&re_comp_buf);
659        memset (&re_comp_buf, '\0', sizeof (re_comp_buf));        memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
660        re_comp_buf.fastmap = fastmap;        re_comp_buf.re_fastmap = fastmap;
661      }      }
662    
663    if (re_comp_buf.fastmap == NULL)    if (re_comp_buf.re_fastmap == NULL)
664      {      {
665        re_comp_buf.fastmap = (char *) malloc (SBC_MAX);        re_comp_buf.re_fastmap = (char *) malloc (SBC_MAX);
666        if (re_comp_buf.fastmap == NULL)        if (re_comp_buf.re_fastmap == NULL)
667          return (char *) gettext (__re_error_msgid          return (char *) gettext (__re_error_msgid
668                                   + __re_error_msgid_idx[(int) REG_ESPACE]);                                   + __re_error_msgid_idx[(int) REG_ESPACE]);
669      }      }
# Line 713  re_comp (s) Line 672  re_comp (s)
672       don't need to initialize the pattern buffer fields which affect it.  */       don't need to initialize the pattern buffer fields which affect it.  */
673    
674    /* Match anchors at newlines.  */    /* Match anchors at newlines.  */
675    re_comp_buf.newline_anchor = 1;    re_comp_buf.re_newline_anchor = 1;
676    
677    ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);    ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
678    
# Line 738  libc_freeres_fn (free_mem) Line 697  libc_freeres_fn (free_mem)
697     SYNTAX indicate regular expression's syntax.  */     SYNTAX indicate regular expression's syntax.  */
698    
699  static reg_errcode_t  static reg_errcode_t
700  re_compile_internal (preg, pattern, length, syntax)  re_compile_internal (regex_t *preg, const char *pattern, Idx length,
701       regex_t *preg;                       reg_syntax_t syntax)
      const char * pattern;  
      int length;  
      reg_syntax_t syntax;  
702  {  {
703    reg_errcode_t err = REG_NOERROR;    reg_errcode_t err = REG_NOERROR;
704    re_dfa_t *dfa;    re_dfa_t *dfa;
705    re_string_t regexp;    re_string_t regexp;
706    
707    /* Initialize the pattern buffer.  */    /* Initialize the pattern buffer.  */
708    preg->fastmap_accurate = 0;    preg->re_fastmap_accurate = 0;
709    preg->syntax = syntax;    preg->re_syntax = syntax;
710    preg->not_bol = preg->not_eol = 0;    preg->re_not_bol = preg->re_not_eol = 0;
711    preg->used = 0;    preg->re_used = 0;
712    preg->re_nsub = 0;    preg->re_nsub = 0;
713    preg->can_be_null = 0;    preg->re_can_be_null = 0;
714    preg->regs_allocated = REGS_UNALLOCATED;    preg->re_regs_allocated = REG_UNALLOCATED;
715    
716    /* Initialize the dfa.  */    /* Initialize the dfa.  */
717    dfa = (re_dfa_t *) preg->buffer;    dfa = (re_dfa_t *) preg->re_buffer;
718    if (BE (preg->allocated < sizeof (re_dfa_t), 0))    if (BE (preg->re_allocated < sizeof (re_dfa_t), 0))
719      {      {
720        /* If zero allocated, but buffer is non-null, try to realloc        /* If zero allocated, but buffer is non-null, try to realloc
721           enough space.  This loses if buffer's address is bogus, but           enough space.  This loses if buffer's address is bogus, but
722           that is the user's responsibility.  If ->buffer is NULL this           that is the user's responsibility.  If buffer is null this
723           is a simple allocation.  */           is a simple allocation.  */
724        dfa = re_realloc (preg->buffer, re_dfa_t, 1);        dfa = re_realloc (preg->re_buffer, re_dfa_t, 1);
725        if (dfa == NULL)        if (dfa == NULL)
726          return REG_ESPACE;          return REG_ESPACE;
727        preg->allocated = sizeof (re_dfa_t);        preg->re_allocated = sizeof (re_dfa_t);
728        preg->buffer = (unsigned char *) dfa;        preg->re_buffer = (unsigned char *) dfa;
729      }      }
730    preg->used = sizeof (re_dfa_t);    preg->re_used = sizeof (re_dfa_t);
731    
732    __libc_lock_init (dfa->lock);    __libc_lock_init (dfa->lock);
733    
# Line 779  re_compile_internal (preg, pattern, leng Line 735  re_compile_internal (preg, pattern, leng
735    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
736      {      {
737        free_dfa_content (dfa);        free_dfa_content (dfa);
738        preg->buffer = NULL;        preg->re_buffer = NULL;
739        preg->allocated = 0;        preg->re_allocated = 0;
740        return err;        return err;
741      }      }
742  #ifdef DEBUG  #ifdef DEBUG
# Line 788  re_compile_internal (preg, pattern, leng Line 744  re_compile_internal (preg, pattern, leng
744    strncpy (dfa->re_str, pattern, length + 1);    strncpy (dfa->re_str, pattern, length + 1);
745  #endif  #endif
746    
747    err = re_string_construct (&regexp, pattern, length, preg->translate,    err = re_string_construct (&regexp, pattern, length, preg->re_translate,
748                               syntax & RE_ICASE, dfa);                               syntax & REG_IGNORE_CASE, dfa);
749    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
750      {      {
751      re_compile_internal_free_return:      re_compile_internal_free_return:
752        free_workarea_compile (preg);        free_workarea_compile (preg);
753        re_string_destruct (&regexp);        re_string_destruct (&regexp);
754        free_dfa_content (dfa);        free_dfa_content (dfa);
755        preg->buffer = NULL;        preg->re_buffer = NULL;
756        preg->allocated = 0;        preg->re_allocated = 0;
757        return err;        return err;
758      }      }
759    
# Line 814  re_compile_internal (preg, pattern, leng Line 770  re_compile_internal (preg, pattern, leng
770    
771  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
772    /* If possible, do searching in single byte encoding to speed things up.  */    /* If possible, do searching in single byte encoding to speed things up.  */
773    if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)    if (dfa->is_utf8 && !(syntax & REG_IGNORE_CASE) && preg->re_translate == NULL)
774      optimize_utf8 (dfa);      optimize_utf8 (dfa);
775  #endif  #endif
776    
# Line 828  re_compile_internal (preg, pattern, leng Line 784  re_compile_internal (preg, pattern, leng
784    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
785      {      {
786        free_dfa_content (dfa);        free_dfa_content (dfa);
787        preg->buffer = NULL;        preg->re_buffer = NULL;
788        preg->allocated = 0;        preg->re_allocated = 0;
789      }      }
790    
791    return err;    return err;
# Line 839  re_compile_internal (preg, pattern, leng Line 795  re_compile_internal (preg, pattern, leng
795     as the initial length of some arrays.  */     as the initial length of some arrays.  */
796    
797  static reg_errcode_t  static reg_errcode_t
798  init_dfa (dfa, pat_len)  init_dfa (re_dfa_t *dfa, Idx pat_len)
      re_dfa_t *dfa;  
      int pat_len;  
799  {  {
800    int table_size;    __re_size_t table_size;
801  #ifndef _LIBC  #ifndef _LIBC
802    char *codeset_name;    char *codeset_name;
803  #endif  #endif
# Line 854  init_dfa (dfa, pat_len) Line 808  init_dfa (dfa, pat_len)
808    dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;    dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
809    
810    dfa->nodes_alloc = pat_len + 1;    dfa->nodes_alloc = pat_len + 1;
811    dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);    dfa->nodes = re_xmalloc (re_token_t, dfa->nodes_alloc);
   
   dfa->states_alloc = pat_len + 1;  
812    
813    /*  table_size = 2 ^ ceil(log pat_len) */    /*  table_size = 2 ^ ceil(log pat_len) */
814    for (table_size = 1; table_size > 0; table_size <<= 1)    for (table_size = 1; table_size <= pat_len; table_size <<= 1)
815      if (table_size > pat_len)      if (0 < (Idx) -1 && table_size == 0)
816        break;        return REG_ESPACE;
817    
818    dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);    dfa->state_table = re_calloc (struct re_state_table_entry, table_size);
819    dfa->state_hash_mask = table_size - 1;    dfa->state_hash_mask = table_size - 1;
820    
821    dfa->mb_cur_max = MB_CUR_MAX;    dfa->mb_cur_max = MB_CUR_MAX;
# Line 906  init_dfa (dfa, pat_len) Line 858  init_dfa (dfa, pat_len)
858          {          {
859            int i, j, ch;            int i, j, ch;
860    
861            dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1);            dfa->sb_char = re_calloc (unsigned int, BITSET_UINTS);
862            if (BE (dfa->sb_char == NULL, 0))            if (BE (dfa->sb_char == NULL, 0))
863              return REG_ESPACE;              return REG_ESPACE;
864    
# Line 919  init_dfa (dfa, pat_len) Line 871  init_dfa (dfa, pat_len)
871                {                {
872                  wint_t wch = __btowc (ch);                  wint_t wch = __btowc (ch);
873                  if (wch != WEOF)                  if (wch != WEOF)
874                    dfa->sb_char[i] |= 1 << j;                    dfa->sb_char[i] |= 1u << j;
875  # ifndef _LIBC  # ifndef _LIBC
876                  if (isascii (ch) && wch != ch)                  if (isascii (ch) && wch != ch)
877                    dfa->map_notascii = 1;                    dfa->map_notascii = 1;
# Line 939  init_dfa (dfa, pat_len) Line 891  init_dfa (dfa, pat_len)
891     character used by some operators like "\<", "\>", etc.  */     character used by some operators like "\<", "\>", etc.  */
892    
893  static void  static void
894  init_word_char (dfa)  init_word_char (re_dfa_t *dfa)
      re_dfa_t *dfa;  
895  {  {
896    int i, j, ch;    int i, j, ch;
897    dfa->word_ops_used = 1;    dfa->word_ops_used = 1;
898    for (i = 0, ch = 0; i < BITSET_UINTS; ++i)    for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
899      for (j = 0; j < UINT_BITS; ++j, ++ch)      for (j = 0; j < UINT_BITS; ++j, ++ch)
900        if (isalnum (ch) || ch == '_')        if (isalnum (ch) || ch == '_')
901          dfa->word_char[i] |= 1 << j;          dfa->word_char[i] |= 1u << j;
902  }  }
903    
904  /* Free the work area which are only used while compiling.  */  /* Free the work area which are only used while compiling.  */
905    
906  static void  static void
907  free_workarea_compile (preg)  free_workarea_compile (regex_t *preg)
      regex_t *preg;  
908  {  {
909    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
910    bin_tree_storage_t *storage, *next;    bin_tree_storage_t *storage, *next;
911    for (storage = dfa->str_tree_storage; storage; storage = next)    for (storage = dfa->str_tree_storage; storage; storage = next)
912      {      {
# Line 973  free_workarea_compile (preg) Line 923  free_workarea_compile (preg)
923  /* Create initial states for all contexts.  */  /* Create initial states for all contexts.  */
924    
925  static reg_errcode_t  static reg_errcode_t
926  create_initial_state (dfa)  create_initial_state (re_dfa_t *dfa)
      re_dfa_t *dfa;  
927  {  {
928    int first, i;    Idx first, i;
929    reg_errcode_t err;    reg_errcode_t err;
930    re_node_set init_nodes;    re_node_set init_nodes;
931    
# Line 995  create_initial_state (dfa) Line 944  create_initial_state (dfa)
944    if (dfa->nbackref > 0)    if (dfa->nbackref > 0)
945      for (i = 0; i < init_nodes.nelem; ++i)      for (i = 0; i < init_nodes.nelem; ++i)
946        {        {
947          int node_idx = init_nodes.elems[i];          Idx node_idx = init_nodes.elems[i];
948          re_token_type_t type = dfa->nodes[node_idx].type;          re_token_type_t type = dfa->nodes[node_idx].type;
949    
950          int clexp_idx;          Idx clexp_idx;
951          if (type != OP_BACK_REF)          if (type != OP_BACK_REF)
952            continue;            continue;
953          for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)          for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
# Line 1014  create_initial_state (dfa) Line 963  create_initial_state (dfa)
963    
964          if (type == OP_BACK_REF)          if (type == OP_BACK_REF)
965            {            {
966              int dest_idx = dfa->edests[node_idx].elems[0];              Idx dest_idx = dfa->edests[node_idx].elems[0];
967              if (!re_node_set_contains (&init_nodes, dest_idx))              if (!re_node_set_contains (&init_nodes, dest_idx))
968                {                {
969                  re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);                  re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
# Line 1056  create_initial_state (dfa) Line 1005  create_initial_state (dfa)
1005     DFA nodes where needed.  */     DFA nodes where needed.  */
1006    
1007  static void  static void
1008  optimize_utf8 (dfa)  optimize_utf8 (re_dfa_t *dfa)
      re_dfa_t *dfa;  
1009  {  {
1010    int node, i, mb_chars = 0, has_period = 0;    Idx node;
1011      int i;
1012      bool mb_chars = false;
1013      bool has_period = false;
1014    
1015    for (node = 0; node < dfa->nodes_len; ++node)    for (node = 0; node < dfa->nodes_len; ++node)
1016      switch (dfa->nodes[node].type)      switch (dfa->nodes[node].type)
1017        {        {
1018        case CHARACTER:        case CHARACTER:
1019          if (dfa->nodes[node].opr.c >= 0x80)          if (dfa->nodes[node].opr.c >= 0x80)
1020            mb_chars = 1;            mb_chars = true;
1021          break;          break;
1022        case ANCHOR:        case ANCHOR:
1023          switch (dfa->nodes[node].opr.idx)          switch (dfa->nodes[node].opr.idx)
# Line 1082  optimize_utf8 (dfa) Line 1033  optimize_utf8 (dfa)
1033            }            }
1034          break;          break;
1035        case OP_PERIOD:        case OP_PERIOD:
1036          has_period = 1;          has_period = true;
1037          break;          break;
1038        case OP_BACK_REF:        case OP_BACK_REF:
1039        case OP_ALT:        case OP_ALT:
# Line 1124  optimize_utf8 (dfa) Line 1075  optimize_utf8 (dfa)
1075     "eclosure", and "inveclosure".  */     "eclosure", and "inveclosure".  */
1076    
1077  static reg_errcode_t  static reg_errcode_t
1078  analyze (preg)  analyze (regex_t *preg)
      regex_t *preg;  
1079  {  {
1080    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
1081    reg_errcode_t ret;    reg_errcode_t ret;
1082    
1083    /* Allocate arrays.  */    /* Allocate arrays.  */
1084    dfa->nexts = re_malloc (int, dfa->nodes_alloc);    dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);
1085    dfa->org_indices = re_malloc (int, dfa->nodes_alloc);    dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
1086    dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);    dfa->edests = re_xmalloc (re_node_set, dfa->nodes_alloc);
1087    dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);    dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
1088    if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL    if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
1089            || dfa->eclosures == NULL, 0))            || dfa->eclosures == NULL, 0))
1090      return REG_ESPACE;      return REG_ESPACE;
1091    
1092    dfa->subexp_map = re_malloc (int, preg->re_nsub);    dfa->subexp_map = re_xmalloc (Idx, preg->re_nsub);
1093    if (dfa->subexp_map != NULL)    if (dfa->subexp_map != NULL)
1094      {      {
1095        int i;        Idx i;
1096        for (i = 0; i < preg->re_nsub; i++)        for (i = 0; i < preg->re_nsub; i++)
1097          dfa->subexp_map[i] = i;          dfa->subexp_map[i] = i;
1098        preorder (dfa->str_tree, optimize_subexps, dfa);        preorder (dfa->str_tree, optimize_subexps, dfa);
# Line 1172  analyze (preg) Line 1122  analyze (preg)
1122    
1123    /* We only need this during the prune_impossible_nodes pass in regexec.c;    /* We only need this during the prune_impossible_nodes pass in regexec.c;
1124       skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */       skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
1125    if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)    if ((!preg->re_no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
1126        || dfa->nbackref)        || dfa->nbackref)
1127      {      {
1128        dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);        dfa->inveclosures = re_xmalloc (re_node_set, dfa->nodes_len);
1129        if (BE (dfa->inveclosures == NULL, 0))        if (BE (dfa->inveclosures == NULL, 0))
1130          return REG_ESPACE;          return REG_ESPACE;
1131        ret = calc_inveclosure (dfa);        ret = calc_inveclosure (dfa);
# Line 1188  analyze (preg) Line 1138  analyze (preg)
1138     implement parse tree visits.  Instead, we use parent pointers and     implement parse tree visits.  Instead, we use parent pointers and
1139     some hairy code in these two functions.  */     some hairy code in these two functions.  */
1140  static reg_errcode_t  static reg_errcode_t
1141  postorder (root, fn, extra)  postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
1142       bin_tree_t *root;             void *extra)
      reg_errcode_t (fn (void *, bin_tree_t *));  
      void *extra;  
1143  {  {
1144    bin_tree_t *node, *prev;    bin_tree_t *node, *prev;
1145    
# Line 1222  postorder (root, fn, extra) Line 1170  postorder (root, fn, extra)
1170  }  }
1171    
1172  static reg_errcode_t  static reg_errcode_t
1173  preorder (root, fn, extra)  preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
1174       bin_tree_t *root;            void *extra)
      reg_errcode_t (fn (void *, bin_tree_t *));  
      void *extra;  
1175  {  {
1176    bin_tree_t *node;    bin_tree_t *node;
1177    
# Line 1257  preorder (root, fn, extra) Line 1203  preorder (root, fn, extra)
1203     re_search_internal to map the inner one's opr.idx to this one's.  Adjust     re_search_internal to map the inner one's opr.idx to this one's.  Adjust
1204     backreferences as well.  Requires a preorder visit.  */     backreferences as well.  Requires a preorder visit.  */
1205  static reg_errcode_t  static reg_errcode_t
1206  optimize_subexps (extra, node)  optimize_subexps (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
1207  {  {
1208    re_dfa_t *dfa = (re_dfa_t *) extra;    re_dfa_t *dfa = (re_dfa_t *) extra;
1209    
# Line 1273  optimize_subexps (extra, node) Line 1217  optimize_subexps (extra, node)
1217    else if (node->token.type == SUBEXP    else if (node->token.type == SUBEXP
1218             && node->left && node->left->token.type == SUBEXP)             && node->left && node->left->token.type == SUBEXP)
1219      {      {
1220        int other_idx = node->left->token.opr.idx;        Idx other_idx = node->left->token.opr.idx;
1221    
1222        node->left = node->left->left;        node->left = node->left->left;
1223        if (node->left)        if (node->left)
1224          node->left->parent = node;          node->left->parent = node;
1225    
1226        dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];        dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
1227        if (other_idx < 8 * sizeof (dfa->used_bkref_map))        if (other_idx < CHAR_BIT * sizeof dfa->used_bkref_map)
1228          dfa->used_bkref_map &= ~(1 << other_idx);          dfa->used_bkref_map &= ~(1u << other_idx);
1229      }      }
1230    
1231    return REG_NOERROR;    return REG_NOERROR;
# Line 1290  optimize_subexps (extra, node) Line 1234  optimize_subexps (extra, node)
1234  /* Lowering pass: Turn each SUBEXP node into the appropriate concatenation  /* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
1235     of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */     of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
1236  static reg_errcode_t  static reg_errcode_t
1237  lower_subexps (extra, node)  lower_subexps (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
1238  {  {
1239    regex_t *preg = (regex_t *) extra;    regex_t *preg = (regex_t *) extra;
1240    reg_errcode_t err = REG_NOERROR;    reg_errcode_t err = REG_NOERROR;
# Line 1314  lower_subexps (extra, node) Line 1256  lower_subexps (extra, node)
1256  }  }
1257    
1258  static bin_tree_t *  static bin_tree_t *
1259  lower_subexp (err, preg, node)  lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)
      reg_errcode_t *err;  
      regex_t *preg;  
      bin_tree_t *node;  
1260  {  {
1261    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
1262    bin_tree_t *body = node->left;    bin_tree_t *body = node->left;
1263    bin_tree_t *op, *cls, *tree1, *tree;    bin_tree_t *op, *cls, *tree1, *tree;
1264    
1265    if (preg->no_sub    if (preg->re_no_sub
1266        /* We do not optimize empty subexpressions, because otherwise we may        /* We do not optimize empty subexpressions, because otherwise we may
1267           have bad CONCAT nodes with NULL children.  This is obviously not           have bad CONCAT nodes with NULL children.  This is obviously not
1268           very common, so we do not lose much.  An example that triggers           very common, so we do not lose much.  An example that triggers
1269           this case is the sed "script" /\(\)/x.  */           this case is the sed "script" /\(\)/x.  */
1270        && node->left != NULL        && node->left != NULL
1271        && (node->token.opr.idx >= 8 * sizeof (dfa->used_bkref_map)        && (node->token.opr.idx >= CHAR_BIT * sizeof dfa->used_bkref_map
1272            || !(dfa->used_bkref_map & (1 << node->token.opr.idx))))            || !(dfa->used_bkref_map & (1u << node->token.opr.idx))))
1273      return node->left;      return node->left;
1274    
1275    /* Convert the SUBEXP node to the concatenation of an    /* Convert the SUBEXP node to the concatenation of an
# Line 1353  lower_subexp (err, preg, node) Line 1292  lower_subexp (err, preg, node)
1292  /* Pass 1 in building the NFA: compute FIRST and create unlinked automaton  /* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
1293     nodes.  Requires a postorder visit.  */     nodes.  Requires a postorder visit.  */
1294  static reg_errcode_t  static reg_errcode_t
1295  calc_first (extra, node)  calc_first (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
1296  {  {
1297    re_dfa_t *dfa = (re_dfa_t *) extra;    re_dfa_t *dfa = (re_dfa_t *) extra;
1298    if (node->token.type == CONCAT)    if (node->token.type == CONCAT)
# Line 1367  calc_first (extra, node) Line 1304  calc_first (extra, node)
1304      {      {
1305        node->first = node;        node->first = node;
1306        node->node_idx = re_dfa_add_node (dfa, node->token);        node->node_idx = re_dfa_add_node (dfa, node->token);
1307        if (BE (node->node_idx == -1, 0))        if (BE (node->node_idx == REG_MISSING, 0))
1308          return REG_ESPACE;          return REG_ESPACE;
1309      }      }
1310    return REG_NOERROR;    return REG_NOERROR;
# Line 1375  calc_first (extra, node) Line 1312  calc_first (extra, node)
1312    
1313  /* Pass 2: compute NEXT on the tree.  Preorder visit.  */  /* Pass 2: compute NEXT on the tree.  Preorder visit.  */
1314  static reg_errcode_t  static reg_errcode_t
1315  calc_next (extra, node)  calc_next (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
1316  {  {
1317    switch (node->token.type)    switch (node->token.type)
1318      {      {
# Line 1400  calc_next (extra, node) Line 1335  calc_next (extra, node)
1335    
1336  /* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */  /* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
1337  static reg_errcode_t  static reg_errcode_t
1338  link_nfa_nodes (extra, node)  link_nfa_nodes (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
1339  {  {
1340    re_dfa_t *dfa = (re_dfa_t *) extra;    re_dfa_t *dfa = (re_dfa_t *) extra;
1341    int idx = node->node_idx;    Idx idx = node->node_idx;
1342    reg_errcode_t err = REG_NOERROR;    reg_errcode_t err = REG_NOERROR;
1343    
1344    switch (node->token.type)    switch (node->token.type)
# Line 1420  link_nfa_nodes (extra, node) Line 1353  link_nfa_nodes (extra, node)
1353      case OP_DUP_ASTERISK:      case OP_DUP_ASTERISK:
1354      case OP_ALT:      case OP_ALT:
1355        {        {
1356          int left, right;          Idx left, right;
1357          dfa->has_plural_match = 1;          dfa->has_plural_match = 1;
1358          if (node->left != NULL)          if (node->left != NULL)
1359            left = node->left->first->node_idx;            left = node->left->first->node_idx;
# Line 1430  link_nfa_nodes (extra, node) Line 1363  link_nfa_nodes (extra, node)
1363            right = node->right->first->node_idx;            right = node->right->first->node_idx;
1364          else          else
1365            right = node->next->node_idx;            right = node->next->node_idx;
1366          assert (left > -1);          assert (REG_VALID_INDEX (left));
1367          assert (right > -1);          assert (REG_VALID_INDEX (right));
1368          err = re_node_set_init_2 (dfa->edests + idx, left, right);          err = re_node_set_init_2 (dfa->edests + idx, left, right);
1369        }        }
1370        break;        break;
# Line 1462  link_nfa_nodes (extra, node) Line 1395  link_nfa_nodes (extra, node)
1395     to their own constraint.  */     to their own constraint.  */
1396    
1397  static reg_errcode_t  static reg_errcode_t
1398  duplicate_node_closure (dfa, top_org_node, top_clone_node, root_node,  duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node,
1399                          init_constraint)                          Idx top_clone_node, Idx root_node,
1400       re_dfa_t *dfa;                          unsigned int init_constraint)
      int top_org_node, top_clone_node, root_node;  
      unsigned int init_constraint;  
1401  {  {
1402    reg_errcode_t err;    Idx org_node, clone_node;
1403    int org_node, clone_node, ret;    bool ok;
1404    unsigned int constraint = init_constraint;    unsigned int constraint = init_constraint;
1405    for (org_node = top_org_node, clone_node = top_clone_node;;)    for (org_node = top_org_node, clone_node = top_clone_node;;)
1406      {      {
1407        int org_dest, clone_dest;        Idx org_dest, clone_dest;
1408        if (dfa->nodes[org_node].type == OP_BACK_REF)        if (dfa->nodes[org_node].type == OP_BACK_REF)
1409          {          {
1410            /* If the back reference epsilon-transit, its destination must            /* If the back reference epsilon-transit, its destination must
# Line 1482  duplicate_node_closure (dfa, top_org_nod Line 1413  duplicate_node_closure (dfa, top_org_nod
1413               edests of the back reference.  */               edests of the back reference.  */
1414            org_dest = dfa->nexts[org_node];            org_dest = dfa->nexts[org_node];
1415            re_node_set_empty (dfa->edests + clone_node);            re_node_set_empty (dfa->edests + clone_node);
1416            err = duplicate_node (&clone_dest, dfa, org_dest, constraint);            clone_dest = duplicate_node (dfa, org_dest, constraint);
1417            if (BE (err != REG_NOERROR, 0))            if (BE (clone_dest == REG_MISSING, 0))
1418              return err;              return REG_ESPACE;
1419            dfa->nexts[clone_node] = dfa->nexts[org_node];            dfa->nexts[clone_node] = dfa->nexts[org_node];
1420            ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);            ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1421            if (BE (ret < 0, 0))            if (BE (! ok, 0))
1422              return REG_ESPACE;              return REG_ESPACE;
1423          }          }
1424        else if (dfa->edests[org_node].nelem == 0)        else if (dfa->edests[org_node].nelem == 0)
# Line 1512  duplicate_node_closure (dfa, top_org_nod Line 1443  duplicate_node_closure (dfa, top_org_nod
1443                    /* ...but if the node is root_node itself, it means the                    /* ...but if the node is root_node itself, it means the
1444                       epsilon closure have a loop, then tie it to the                       epsilon closure have a loop, then tie it to the
1445                       destination of the root_node.  */                       destination of the root_node.  */
1446                    ret = re_node_set_insert (dfa->edests + clone_node,                    ok = re_node_set_insert (dfa->edests + clone_node,
1447                                              org_dest);                                              org_dest);
1448                    if (BE (ret < 0, 0))                    if (BE (! ok, 0))
1449                      return REG_ESPACE;                      return REG_ESPACE;
1450                    break;                    break;
1451                  }                  }
1452                constraint |= dfa->nodes[org_node].opr.ctx_type;                constraint |= dfa->nodes[org_node].opr.ctx_type;
1453              }              }
1454            err = duplicate_node (&clone_dest, dfa, org_dest, constraint);            clone_dest = duplicate_node (dfa, org_dest, constraint);
1455            if (BE (err != REG_NOERROR, 0))            if (BE (clone_dest == REG_MISSING, 0))
1456              return err;              return REG_ESPACE;
1457            ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);            ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1458            if (BE (ret < 0, 0))            if (BE (! ok, 0))
1459              return REG_ESPACE;              return REG_ESPACE;
1460          }          }
1461        else /* dfa->edests[org_node].nelem == 2 */        else /* dfa->edests[org_node].nelem == 2 */
# Line 1535  duplicate_node_closure (dfa, top_org_nod Line 1466  duplicate_node_closure (dfa, top_org_nod
1466            re_node_set_empty (dfa->edests + clone_node);            re_node_set_empty (dfa->edests + clone_node);
1467            /* Search for a duplicated node which satisfies the constraint.  */            /* Search for a duplicated node which satisfies the constraint.  */
1468            clone_dest = search_duplicated_node (dfa, org_dest, constraint);            clone_dest = search_duplicated_node (dfa, org_dest, constraint);
1469            if (clone_dest == -1)            if (clone_dest == REG_MISSING)
1470              {              {
1471                /* There are no such a duplicated node, create a new one.  */                /* There are no such a duplicated node, create a new one.  */
1472                err = duplicate_node (&clone_dest, dfa, org_dest, constraint);                reg_errcode_t err;
1473                if (BE (err != REG_NOERROR, 0))                clone_dest = duplicate_node (dfa, org_dest, constraint);
1474                  return err;                if (BE (clone_dest == REG_MISSING, 0))
1475                ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);                  return REG_ESPACE;
1476                if (BE (ret < 0, 0))                ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1477                  if (BE (! ok, 0))
1478                  return REG_ESPACE;                  return REG_ESPACE;
1479                err = duplicate_node_closure (dfa, org_dest, clone_dest,                err = duplicate_node_closure (dfa, org_dest, clone_dest,
1480                                              root_node, constraint);                                              root_node, constraint);
# Line 1553  duplicate_node_closure (dfa, top_org_nod Line 1485  duplicate_node_closure (dfa, top_org_nod
1485              {              {
1486                /* There are a duplicated node which satisfy the constraint,                /* There are a duplicated node which satisfy the constraint,
1487                   use it to avoid infinite loop.  */                   use it to avoid infinite loop.  */
1488                ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);                ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1489                if (BE (ret < 0, 0))                if (BE (! ok, 0))
1490                  return REG_ESPACE;                  return REG_ESPACE;
1491              }              }
1492    
1493            org_dest = dfa->edests[org_node].elems[1];            org_dest = dfa->edests[org_node].elems[1];
1494            err = duplicate_node (&clone_dest, dfa, org_dest, constraint);            clone_dest = duplicate_node (dfa, org_dest, constraint);
1495            if (BE (err != REG_NOERROR, 0))            if (BE (clone_dest == REG_MISSING, 0))
1496              return err;              return REG_ESPACE;
1497            ret = re_node_set_insert (dfa->edests + clone_node, clone_dest);            ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
1498            if (BE (ret < 0, 0))            if (BE (! ok, 0))
1499              return REG_ESPACE;              return REG_ESPACE;
1500          }          }
1501        org_node = org_dest;        org_node = org_dest;
# Line 1575  duplicate_node_closure (dfa, top_org_nod Line 1507  duplicate_node_closure (dfa, top_org_nod
1507  /* Search for a node which is duplicated from the node ORG_NODE, and  /* Search for a node which is duplicated from the node ORG_NODE, and
1508     satisfies the constraint CONSTRAINT.  */     satisfies the constraint CONSTRAINT.  */
1509    
1510  static int  static Idx
1511  search_duplicated_node (dfa, org_node, constraint)  search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
1512       re_dfa_t *dfa;                          unsigned int constraint)
      int org_node;  
      unsigned int constraint;  
1513  {  {
1514    int idx;    Idx idx;
1515    for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)    for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
1516      {      {
1517        if (org_node == dfa->org_indices[idx]        if (org_node == dfa->org_indices[idx]
1518            && constraint == dfa->nodes[idx].constraint)            && constraint == dfa->nodes[idx].constraint)
1519          return idx; /* Found.  */          return idx; /* Found.  */
1520      }      }
1521    return -1; /* Not found.  */    return REG_MISSING; /* Not found.  */
1522  }  }
1523    
1524  /* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.  /* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
1525     The new index will be stored in NEW_IDX and return REG_NOERROR if succeeded,     Return the index of the new node, or REG_MISSING if insufficient storage is
1526     otherwise return the error code.  */     available.  */
1527    
1528  static reg_errcode_t  static Idx
1529  duplicate_node (new_idx, dfa, org_idx, constraint)  duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
      re_dfa_t *dfa;  
      int *new_idx, org_idx;  
      unsigned int constraint;  
1530  {  {
1531    int dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);    Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
1532    if (BE (dup_idx == -1, 0))    if (BE (dup_idx != REG_MISSING, 1))
1533      return REG_ESPACE;      {
1534    dfa->nodes[dup_idx].constraint = constraint;        dfa->nodes[dup_idx].constraint = constraint;
1535    if (dfa->nodes[org_idx].type == ANCHOR)        if (dfa->nodes[org_idx].type == ANCHOR)
1536      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;          dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;
1537    dfa->nodes[dup_idx].duplicated = 1;        dfa->nodes[dup_idx].duplicated = 1;
1538    
1539    /* Store the index of the original node.  */        /* Store the index of the original node.  */
1540    dfa->org_indices[dup_idx] = org_idx;        dfa->org_indices[dup_idx] = org_idx;
1541    *new_idx = dup_idx;      }
1542    return REG_NOERROR;    return dup_idx;
1543  }  }
1544    
1545  static reg_errcode_t  static reg_errcode_t
1546  calc_inveclosure (dfa)  calc_inveclosure (re_dfa_t *dfa)
      re_dfa_t *dfa;  
1547  {  {
1548    int src, idx, ret;    Idx src, idx;
1549      bool ok;
1550    for (idx = 0; idx < dfa->nodes_len; ++idx)    for (idx = 0; idx < dfa->nodes_len; ++idx)
1551      re_node_set_init_empty (dfa->inveclosures + idx);      re_node_set_init_empty (dfa->inveclosures + idx);
1552    
1553    for (src = 0; src < dfa->nodes_len; ++src)    for (src = 0; src < dfa->nodes_len; ++src)
1554      {      {
1555        int *elems = dfa->eclosures[src].elems;        Idx *elems = dfa->eclosures[src].elems;
1556        for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)        for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
1557          {          {
1558            ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);            ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
1559            if (BE (ret == -1, 0))            if (BE (! ok, 0))
1560              return REG_ESPACE;              return REG_ESPACE;
1561          }          }
1562      }      }
# Line 1640  calc_inveclosure (dfa) Line 1567  calc_inveclosure (dfa)
1567  /* Calculate "eclosure" for all the node in DFA.  */  /* Calculate "eclosure" for all the node in DFA.  */
1568    
1569  static reg_errcode_t  static reg_errcode_t
1570  calc_eclosure (dfa)  calc_eclosure (re_dfa_t *dfa)
      re_dfa_t *dfa;  
1571  {  {
1572    int node_idx, incomplete;    Idx node_idx;
1573      bool incomplete;
1574  #ifdef DEBUG  #ifdef DEBUG
1575    assert (dfa->nodes_len > 0);    assert (dfa->nodes_len > 0);
1576  #endif  #endif
1577    incomplete = 0;    incomplete = false;
1578    /* For each nodes, calculate epsilon closure.  */    /* For each nodes, calculate epsilon closure.  */
1579    for (node_idx = 0; ; ++node_idx)    for (node_idx = 0; ; ++node_idx)
1580      {      {
# Line 1657  calc_eclosure (dfa) Line 1584  calc_eclosure (dfa)
1584          {          {
1585            if (!incomplete)            if (!incomplete)
1586              break;              break;
1587            incomplete = 0;            incomplete = false;
1588            node_idx = 0;            node_idx = 0;
1589          }          }
1590    
1591  #ifdef DEBUG  #ifdef DEBUG
1592        assert (dfa->eclosures[node_idx].nelem != -1);        assert (dfa->eclosures[node_idx].nelem != REG_MISSING);
1593  #endif  #endif
1594    
1595        /* If we have already calculated, skip it.  */        /* If we have already calculated, skip it.  */
1596        if (dfa->eclosures[node_idx].nelem != 0)        if (dfa->eclosures[node_idx].nelem != 0)
1597          continue;          continue;
1598        /* Calculate epsilon closure of `node_idx'.  */        /* Calculate epsilon closure of `node_idx'.  */
1599        err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1);        err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);
1600        if (BE (err != REG_NOERROR, 0))        if (BE (err != REG_NOERROR, 0))
1601          return err;          return err;
1602    
1603        if (dfa->eclosures[node_idx].nelem == 0)        if (dfa->eclosures[node_idx].nelem == 0)
1604          {          {
1605            incomplete = 1;            incomplete = true;
1606            re_node_set_free (&eclosure_elem);            re_node_set_free (&eclosure_elem);
1607          }          }
1608      }      }
# Line 1685  calc_eclosure (dfa) Line 1612  calc_eclosure (dfa)
1612  /* Calculate epsilon closure of NODE.  */  /* Calculate epsilon closure of NODE.  */
1613    
1614  static reg_errcode_t  static reg_errcode_t
1615  calc_eclosure_iter (new_set, dfa, node, root)  calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
      re_node_set *new_set;  
      re_dfa_t *dfa;  
      int node, root;  
1616  {  {
1617    reg_errcode_t err;    reg_errcode_t err;
1618    unsigned int constraint;    unsigned int constraint;
1619    int i, incomplete;    Idx i;
1620      bool incomplete;
1621      bool ok;
1622    re_node_set eclosure;    re_node_set eclosure;
1623    incomplete = 0;    incomplete = false;
1624    err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);    err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
1625    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
1626      return err;      return err;
1627    
1628    /* This indicates that we are calculating this node now.    /* This indicates that we are calculating this node now.
1629       We reference this value to avoid infinite loop.  */       We reference this value to avoid infinite loop.  */
1630    dfa->eclosures[node].nelem = -1;    dfa->eclosures[node].nelem = REG_MISSING;
1631    
1632    constraint = ((dfa->nodes[node].type == ANCHOR)    constraint = ((dfa->nodes[node].type == ANCHOR)
1633                  ? dfa->nodes[node].opr.ctx_type : 0);                  ? dfa->nodes[node].opr.ctx_type : 0);
# Line 1711  calc_eclosure_iter (new_set, dfa, node, Line 1637  calc_eclosure_iter (new_set, dfa, node,
1637        && dfa->edests[node].nelem        && dfa->edests[node].nelem
1638        && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)        && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
1639      {      {
1640        int org_node, cur_node;        Idx org_node, cur_node;
1641        org_node = cur_node = node;        org_node = cur_node = node;
1642        err = duplicate_node_closure (dfa, node, node, node, constraint);        err = duplicate_node_closure (dfa, node, node, node, constraint);
1643        if (BE (err != REG_NOERROR, 0))        if (BE (err != REG_NOERROR, 0))
# Line 1723  calc_eclosure_iter (new_set, dfa, node, Line 1649  calc_eclosure_iter (new_set, dfa, node,
1649      for (i = 0; i < dfa->edests[node].nelem; ++i)      for (i = 0; i < dfa->edests[node].nelem; ++i)
1650        {        {
1651          re_node_set eclosure_elem;          re_node_set eclosure_elem;
1652          int edest = dfa->edests[node].elems[i];          Idx edest = dfa->edests[node].elems[i];
1653          /* If calculating the epsilon closure of `edest' is in progress,          /* If calculating the epsilon closure of `edest' is in progress,
1654             return intermediate result.  */             return intermediate result.  */
1655          if (dfa->eclosures[edest].nelem == -1)          if (dfa->eclosures[edest].nelem == REG_MISSING)
1656            {            {
1657              incomplete = 1;              incomplete = true;
1658              continue;              continue;
1659            }            }
1660          /* If we haven't calculated the epsilon closure of `edest' yet,          /* If we haven't calculated the epsilon closure of `edest' yet,
1661             calculate now. Otherwise use calculated epsilon closure.  */             calculate now. Otherwise use calculated epsilon closure.  */
1662          if (dfa->eclosures[edest].nelem == 0)          if (dfa->eclosures[edest].nelem == 0)
1663            {            {
1664              err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0);              err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
1665              if (BE (err != REG_NOERROR, 0))              if (BE (err != REG_NOERROR, 0))
1666                return err;                return err;
1667            }            }
# Line 1747  calc_eclosure_iter (new_set, dfa, node, Line 1673  calc_eclosure_iter (new_set, dfa, node,
1673             the epsilon closure of this node is also incomplete.  */             the epsilon closure of this node is also incomplete.  */
1674          if (dfa->eclosures[edest].nelem == 0)          if (dfa->eclosures[edest].nelem == 0)
1675            {            {
1676              incomplete = 1;              incomplete = true;
1677              re_node_set_free (&eclosure_elem);              re_node_set_free (&eclosure_elem);
1678            }            }
1679        }        }
1680    
1681    /* Epsilon closures include itself.  */    /* Epsilon closures include itself.  */
1682    re_node_set_insert (&eclosure, node);    ok = re_node_set_insert (&eclosure, node);
1683      if (BE (! ok, 0))
1684        return REG_ESPACE;
1685    if (incomplete && !root)    if (incomplete && !root)
1686      dfa->eclosures[node].nelem = 0;      dfa->eclosures[node].nelem = 0;
1687    else    else
# Line 1768  calc_eclosure_iter (new_set, dfa, node, Line 1696  calc_eclosure_iter (new_set, dfa, node,
1696     We must not use this function inside bracket expressions.  */     We must not use this function inside bracket expressions.  */
1697    
1698  static void  static void
1699  fetch_token (result, input, syntax)  fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)
      re_token_t *result;  
      re_string_t *input;  
      reg_syntax_t syntax;  
1700  {  {
1701    re_string_skip_bytes (input, peek_token (result, input, syntax));    re_string_skip_bytes (input, peek_token (result, input, syntax));
1702  }  }
# Line 1780  fetch_token (result, input, syntax) Line 1705  fetch_token (result, input, syntax)
1705     We must not use this function inside bracket expressions.  */     We must not use this function inside bracket expressions.  */
1706    
1707  static int  static int
1708  peek_token (token, input, syntax)  peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
      re_token_t *token;  
      re_string_t *input;  
      reg_syntax_t syntax;  
1709  {  {
1710    unsigned char c;    unsigned char c;
1711    
# Line 1833  peek_token (token, input, syntax) Line 1755  peek_token (token, input, syntax)
1755        switch (c2)        switch (c2)
1756          {          {
1757          case '|':          case '|':
1758            if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))            if (!(syntax & REG_LIMITED_OPS) && !(syntax & REG_NO_BK_VBAR))
1759              token->type = OP_ALT;              token->type = OP_ALT;
1760            break;            break;
1761          case '1': case '2': case '3': case '4': case '5':          case '1': case '2': case '3': case '4': case '5':
1762          case '6': case '7': case '8': case '9':          case '6': case '7': case '8': case '9':
1763            if (!(syntax & RE_NO_BK_REFS))            if (!(syntax & REG_NO_BK_REFS))
1764              {              {
1765                token->type = OP_BACK_REF;                token->type = OP_BACK_REF;
1766                token->opr.idx = c2 - '1';                token->opr.idx = c2 - '1';
1767              }              }
1768            break;            break;
1769          case '<':          case '<':
1770            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1771              {              {
1772                token->type = ANCHOR;                token->type = ANCHOR;
1773                token->opr.ctx_type = WORD_FIRST;                token->opr.ctx_type = WORD_FIRST;
1774              }              }
1775            break;            break;
1776          case '>':          case '>':
1777            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1778              {              {
1779                token->type = ANCHOR;                token->type = ANCHOR;
1780                token->opr.ctx_type = WORD_LAST;                token->opr.ctx_type = WORD_LAST;
1781              }              }
1782            break;            break;
1783          case 'b':          case 'b':
1784            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1785              {              {
1786                token->type = ANCHOR;                token->type = ANCHOR;
1787                token->opr.ctx_type = WORD_DELIM;                token->opr.ctx_type = WORD_DELIM;
1788              }              }
1789            break;            break;
1790          case 'B':          case 'B':
1791            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1792              {              {
1793                token->type = ANCHOR;                token->type = ANCHOR;
1794                token->opr.ctx_type = NOT_WORD_DELIM;                token->opr.ctx_type = NOT_WORD_DELIM;
1795              }              }
1796            break;            break;
1797          case 'w':          case 'w':
1798            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1799              token->type = OP_WORD;              token->type = OP_WORD;
1800            break;            break;
1801          case 'W':          case 'W':
1802            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1803              token->type = OP_NOTWORD;              token->type = OP_NOTWORD;
1804            break;            break;
1805          case 's':          case 's':
1806            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1807              token->type = OP_SPACE;              token->type = OP_SPACE;
1808            break;            break;
1809          case 'S':          case 'S':
1810            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1811              token->type = OP_NOTSPACE;              token->type = OP_NOTSPACE;
1812            break;            break;
1813          case '`':          case '`':
1814            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1815              {              {
1816                token->type = ANCHOR;                token->type = ANCHOR;
1817                token->opr.ctx_type = BUF_FIRST;                token->opr.ctx_type = BUF_FIRST;
1818              }              }
1819            break;            break;
1820          case '\'':          case '\'':
1821            if (!(syntax & RE_NO_GNU_OPS))            if (!(syntax & REG_NO_GNU_OPS))
1822              {              {
1823                token->type = ANCHOR;                token->type = ANCHOR;
1824                token->opr.ctx_type = BUF_LAST;                token->opr.ctx_type = BUF_LAST;
1825              }              }
1826            break;            break;
1827          case '(':          case '(':
1828            if (!(syntax & RE_NO_BK_PARENS))            if (!(syntax & REG_NO_BK_PARENS))
1829              token->type = OP_OPEN_SUBEXP;              token->type = OP_OPEN_SUBEXP;
1830            break;            break;
1831          case ')':          case ')':
1832            if (!(syntax & RE_NO_BK_PARENS))            if (!(syntax & REG_NO_BK_PARENS))
1833              token->type = OP_CLOSE_SUBEXP;              token->type = OP_CLOSE_SUBEXP;
1834            break;            break;
1835          case '+':          case '+':
1836            if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))            if (!(syntax & REG_LIMITED_OPS) && (syntax & REG_BK_PLUS_QM))
1837              token->type = OP_DUP_PLUS;              token->type = OP_DUP_PLUS;
1838            break;            break;
1839          case '?':          case '?':
1840            if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))            if (!(syntax & REG_LIMITED_OPS) && (syntax & REG_BK_PLUS_QM))
1841              token->type = OP_DUP_QUESTION;              token->type = OP_DUP_QUESTION;
1842            break;            break;
1843          case '{':          case '{':
1844            if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))            if ((syntax & REG_INTERVALS) && (!(syntax & REG_NO_BK_BRACES)))
1845              token->type = OP_OPEN_DUP_NUM;              token->type = OP_OPEN_DUP_NUM;
1846            break;            break;
1847          case '}':          case '}':
1848            if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))            if ((syntax & REG_INTERVALS) && (!(syntax & REG_NO_BK_BRACES)))
1849              token->type = OP_CLOSE_DUP_NUM;              token->type = OP_CLOSE_DUP_NUM;
1850            break;            break;
1851          default:          default:
# Line 1946  peek_token (token, input, syntax) Line 1868  peek_token (token, input, syntax)
1868    switch (c)    switch (c)
1869      {      {
1870      case '\n':      case '\n':
1871        if (syntax & RE_NEWLINE_ALT)        if (syntax & REG_NEWLINE_ALT)
1872          token->type = OP_ALT;          token->type = OP_ALT;
1873        break;        break;
1874      case '|':      case '|':
1875        if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))        if (!(syntax & REG_LIMITED_OPS) && (syntax & REG_NO_BK_VBAR))
1876          token->type = OP_ALT;          token->type = OP_ALT;
1877        break;        break;
1878      case '*':      case '*':
1879        token->type = OP_DUP_ASTERISK;        token->type = OP_DUP_ASTERISK;
1880        break;        break;
1881      case '+':      case '+':
1882        if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))        if (!(syntax & REG_LIMITED_OPS) && !(syntax & REG_BK_PLUS_QM))
1883          token->type = OP_DUP_PLUS;          token->type = OP_DUP_PLUS;
1884        break;        break;
1885      case '?':      case '?':
1886        if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))        if (!(syntax & REG_LIMITED_OPS) && !(syntax & REG_BK_PLUS_QM))
1887          token->type = OP_DUP_QUESTION;          token->type = OP_DUP_QUESTION;
1888        break;        break;
1889      case '{':      case '{':
1890        if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))        if ((syntax & REG_INTERVALS) && (syntax & REG_NO_BK_BRACES))
1891          token->type = OP_OPEN_DUP_NUM;          token->type = OP_OPEN_DUP_NUM;
1892        break;        break;
1893      case '}':      case '}':
1894        if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))        if ((syntax & REG_INTERVALS) && (syntax & REG_NO_BK_BRACES))
1895          token->type = OP_CLOSE_DUP_NUM;          token->type = OP_CLOSE_DUP_NUM;
1896        break;        break;
1897      case '(':      case '(':
1898        if (syntax & RE_NO_BK_PARENS)        if (syntax & REG_NO_BK_PARENS)
1899          token->type = OP_OPEN_SUBEXP;          token->type = OP_OPEN_SUBEXP;
1900        break;        break;
1901      case ')':      case ')':
1902        if (syntax & RE_NO_BK_PARENS)        if (syntax & REG_NO_BK_PARENS)
1903          token->type = OP_CLOSE_SUBEXP;          token->type = OP_CLOSE_SUBEXP;
1904        break;        break;
1905      case '[':      case '[':
# Line 1987  peek_token (token, input, syntax) Line 1909  peek_token (token, input, syntax)
1909        token->type = OP_PERIOD;        token->type = OP_PERIOD;
1910        break;        break;
1911      case '^':      case '^':
1912        if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&        if (!(syntax & (REG_CONTEXT_INDEP_ANCHORS | REG_CARET_ANCHORS_HERE)) &&
1913            re_string_cur_idx (input) != 0)            re_string_cur_idx (input) != 0)
1914          {          {
1915            char prev = re_string_peek_byte (input, -1);            char prev = re_string_peek_byte (input, -1);
1916            if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')            if (!(syntax & REG_NEWLINE_ALT) || prev != '\n')
1917              break;              break;
1918          }          }
1919        token->type = ANCHOR;        token->type = ANCHOR;
1920        token->opr.ctx_type = LINE_FIRST;        token->opr.ctx_type = LINE_FIRST;
1921        break;        break;
1922      case '$':      case '$':
1923        if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&        if (!(syntax & REG_CONTEXT_INDEP_ANCHORS) &&
1924            re_string_cur_idx (input) + 1 != re_string_length (input))            re_string_cur_idx (input) + 1 != re_string_length (input))
1925          {          {
1926            re_token_t next;            re_token_t next;
# Line 2021  peek_token (token, input, syntax) Line 1943  peek_token (token, input, syntax)
1943     We must not use this function out of bracket expressions.  */     We must not use this function out of bracket expressions.  */
1944    
1945  static int  static int
1946  peek_token_bracket (token, input, syntax)  peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
      re_token_t *token;  
      re_string_t *input;  
      reg_syntax_t syntax;  
1947  {  {
1948    unsigned char c;    unsigned char c;
1949    if (re_string_eoi (input))    if (re_string_eoi (input))
# Line 2044  peek_token_bracket (token, input, syntax Line 1963  peek_token_bracket (token, input, syntax
1963      }      }
1964  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
1965    
1966    if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)    if (c == '\\' && (syntax & REG_BACKSLASH_ESCAPE_IN_LISTS)
1967        && re_string_cur_idx (input) + 1 < re_string_length (input))        && re_string_cur_idx (input) + 1 < re_string_length (input))
1968      {      {
1969        /* In this case, '\' escape a character.  */        /* In this case, '\' escape a character.  */
# Line 2074  peek_token_bracket (token, input, syntax Line 1993  peek_token_bracket (token, input, syntax
1993            token->type = OP_OPEN_EQUIV_CLASS;            token->type = OP_OPEN_EQUIV_CLASS;
1994            break;            break;
1995          case ':':          case ':':
1996            if (syntax & RE_CHAR_CLASSES)            if (syntax & REG_CHAR_CLASSES)
1997              {              {
1998                token->type = OP_OPEN_CHAR_CLASS;                token->type = OP_OPEN_CHAR_CLASS;
1999                break;                break;
# Line 2120  peek_token_bracket (token, input, syntax Line 2039  peek_token_bracket (token, input, syntax
2039     EOR means end of regular expression.  */     EOR means end of regular expression.  */
2040    
2041  static bin_tree_t *  static bin_tree_t *
2042  parse (regexp, preg, syntax, err)  parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
2043       re_string_t *regexp;         reg_errcode_t *err)
      regex_t *preg;  
      reg_syntax_t syntax;  
      reg_errcode_t *err;  
2044  {  {
2045    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
2046    bin_tree_t *tree, *eor, *root;    bin_tree_t *tree, *eor, *root;
2047    re_token_t current_token;    re_token_t current_token;
2048    dfa->syntax = syntax;    dfa->syntax = syntax;
2049    fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);    fetch_token (&current_token, regexp, syntax | REG_CARET_ANCHORS_HERE);
2050    tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);    tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
2051    if (BE (*err != REG_NOERROR && tree == NULL, 0))    if (BE (*err != REG_NOERROR && tree == NULL, 0))
2052      return NULL;      return NULL;
# Line 2157  parse (regexp, preg, syntax, err) Line 2073  parse (regexp, preg, syntax, err)
2073     ALT means alternative, which represents the operator `|'.  */     ALT means alternative, which represents the operator `|'.  */
2074    
2075  static bin_tree_t *  static bin_tree_t *
2076  parse_reg_exp (regexp, preg, token, syntax, nest, err)  parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
2077       re_string_t *regexp;                 reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
      regex_t *preg;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      int nest;  
      reg_errcode_t *err;  
2078  {  {
2079    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
2080    bin_tree_t *tree, *branch = NULL;    bin_tree_t *tree, *branch = NULL;
2081    tree = parse_branch (regexp, preg, token, syntax, nest, err);    tree = parse_branch (regexp, preg, token, syntax, nest, err);
2082    if (BE (*err != REG_NOERROR && tree == NULL, 0))    if (BE (*err != REG_NOERROR && tree == NULL, 0))
# Line 2173  parse_reg_exp (regexp, preg, token, synt Line 2084  parse_reg_exp (regexp, preg, token, synt
2084    
2085    while (token->type == OP_ALT)    while (token->type == OP_ALT)
2086      {      {
2087        fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);        fetch_token (token, regexp, syntax | REG_CARET_ANCHORS_HERE);
2088        if (token->type != OP_ALT && token->type != END_OF_RE        if (token->type != OP_ALT && token->type != END_OF_RE
2089            && (nest == 0 || token->type != OP_CLOSE_SUBEXP))            && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
2090          {          {
# Line 2203  parse_reg_exp (regexp, preg, token, synt Line 2114  parse_reg_exp (regexp, preg, token, synt
2114     CAT means concatenation.  */     CAT means concatenation.  */
2115    
2116  static bin_tree_t *  static bin_tree_t *
2117  parse_branch (regexp, preg, token, syntax, nest, err)  parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
2118       re_string_t *regexp;                reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
      regex_t *preg;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      int nest;  
      reg_errcode_t *err;  
2119  {  {
2120    bin_tree_t *tree, *exp;    bin_tree_t *tree, *exp;
2121    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
2122    tree = parse_expression (regexp, preg, token, syntax, nest, err);    tree = parse_expression (regexp, preg, token, syntax, nest, err);
2123    if (BE (*err != REG_NOERROR && tree == NULL, 0))    if (BE (*err != REG_NOERROR && tree == NULL, 0))
2124      return NULL;      return NULL;
# Line 2248  parse_branch (regexp, preg, token, synta Line 2154  parse_branch (regexp, preg, token, synta
2154  */  */
2155    
2156  static bin_tree_t *  static bin_tree_t *
2157  parse_expression (regexp, preg, token, syntax, nest, err)  parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
2158       re_string_t *regexp;                    reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
      regex_t *preg;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      int nest;  
      reg_errcode_t *err;  
2159  {  {
2160    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
2161    bin_tree_t *tree;    bin_tree_t *tree;
2162    switch (token->type)    switch (token->type)
2163      {      {
# Line 2313  parse_expression (regexp, preg, token, s Line 2214  parse_expression (regexp, preg, token, s
2214        dfa->has_mb_node = 1;        dfa->has_mb_node = 1;
2215        break;        break;
2216      case OP_OPEN_DUP_NUM:      case OP_OPEN_DUP_NUM:
2217        if (syntax & RE_CONTEXT_INVALID_DUP)        if (syntax & REG_CONTEXT_INVALID_DUP)
2218          {          {
2219            *err = REG_BADRPT;            *err = REG_BADRPT;
2220            return NULL;            return NULL;
# Line 2322  parse_expression (regexp, preg, token, s Line 2223  parse_expression (regexp, preg, token, s
2223      case OP_DUP_ASTERISK:      case OP_DUP_ASTERISK:
2224      case OP_DUP_PLUS:      case OP_DUP_PLUS:
2225      case OP_DUP_QUESTION:      case OP_DUP_QUESTION:
2226        if (syntax & RE_CONTEXT_INVALID_OPS)        if (syntax & REG_CONTEXT_INVALID_OPS)
2227          {          {
2228            *err = REG_BADRPT;            *err = REG_BADRPT;
2229            return NULL;            return NULL;
2230          }          }
2231        else if (syntax & RE_CONTEXT_INDEP_OPS)        else if (syntax & REG_CONTEXT_INDEP_OPS)
2232          {          {
2233            fetch_token (token, regexp, syntax);            fetch_token (token, regexp, syntax);
2234            return parse_expression (regexp, preg, token, syntax, nest, err);            return parse_expression (regexp, preg, token, syntax, nest, err);
# Line 2335  parse_expression (regexp, preg, token, s Line 2236  parse_expression (regexp, preg, token, s
2236        /* else fall through  */        /* else fall through  */
2237      case OP_CLOSE_SUBEXP:      case OP_CLOSE_SUBEXP:
2238        if ((token->type == OP_CLOSE_SUBEXP) &&        if ((token->type == OP_CLOSE_SUBEXP) &&
2239            !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))            !(syntax & REG_UNMATCHED_RIGHT_PAREN_ORD))
2240          {          {
2241            *err = REG_ERPAREN;            *err = REG_ERPAREN;
2242            return NULL;            return NULL;
# Line 2449  parse_expression (regexp, preg, token, s Line 2350  parse_expression (regexp, preg, token, s
2350        if (BE (*err != REG_NOERROR && tree == NULL, 0))        if (BE (*err != REG_NOERROR && tree == NULL, 0))
2351          return NULL;          return NULL;
2352        /* In BRE consecutive duplications are not allowed.  */        /* In BRE consecutive duplications are not allowed.  */
2353        if ((syntax & RE_CONTEXT_INVALID_DUP)        if ((syntax & REG_CONTEXT_INVALID_DUP)
2354            && (token->type == OP_DUP_ASTERISK            && (token->type == OP_DUP_ASTERISK
2355                || token->type == OP_OPEN_DUP_NUM))                || token->type == OP_OPEN_DUP_NUM))
2356          {          {
# Line 2469  parse_expression (regexp, preg, token, s Line 2370  parse_expression (regexp, preg, token, s
2370  */  */
2371    
2372  static bin_tree_t *  static bin_tree_t *
2373  parse_sub_exp (regexp, preg, token, syntax, nest, err)  parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
2374       re_string_t *regexp;                 reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
      regex_t *preg;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      int nest;  
      reg_errcode_t *err;  
2375  {  {
2376    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
2377    bin_tree_t *tree;    bin_tree_t *tree;
2378    size_t cur_nsub;    size_t cur_nsub;
2379    cur_nsub = preg->re_nsub++;    cur_nsub = preg->re_nsub++;
2380    
2381    fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);    fetch_token (token, regexp, syntax | REG_CARET_ANCHORS_HERE);
2382    
2383    /* The subexpression may be a null string.  */    /* The subexpression may be a null string.  */
2384    if (token->type == OP_CLOSE_SUBEXP)    if (token->type == OP_CLOSE_SUBEXP)
# Line 2495  parse_sub_exp (regexp, preg, token, synt Line 2391  parse_sub_exp (regexp, preg, token, synt
2391        if (BE (*err != REG_NOERROR, 0))        if (BE (*err != REG_NOERROR, 0))
2392          return NULL;          return NULL;
2393      }      }
2394    dfa->completed_bkref_map |= 1 << cur_nsub;  
2395      if (cur_nsub <= '9' - '1')
2396        dfa->completed_bkref_map |= 1 << cur_nsub;
2397    
2398    tree = create_tree (dfa, tree, NULL, SUBEXP);    tree = create_tree (dfa, tree, NULL, SUBEXP);
2399    if (BE (tree == NULL, 0))    if (BE (tree == NULL, 0))
# Line 2510  parse_sub_exp (regexp, preg, token, synt Line 2408  parse_sub_exp (regexp, preg, token, synt
2408  /* This function parse repetition operators like "*", "+", "{1,3}" etc.  */  /* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
2409    
2410  static bin_tree_t *  static bin_tree_t *
2411  parse_dup_op (elem, regexp, dfa, token, syntax, err)  parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
2412       bin_tree_t *elem;                re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)
      re_string_t *regexp;  
      re_dfa_t *dfa;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      reg_errcode_t *err;  
2413  {  {
2414    bin_tree_t *tree = NULL, *old_tree = NULL;    bin_tree_t *tree = NULL, *old_tree = NULL;
2415    int i, start, end, start_idx = re_string_cur_idx (regexp);    Idx i, start, end, start_idx = re_string_cur_idx (regexp);
2416    re_token_t start_token = *token;    re_token_t start_token = *token;
2417    
2418    if (token->type == OP_OPEN_DUP_NUM)    if (token->type == OP_OPEN_DUP_NUM)
2419      {      {
2420        end = 0;        end = 0;
2421        start = fetch_number (regexp, token, syntax);        start = fetch_number (regexp, token, syntax);
2422        if (start == -1)        if (start == REG_MISSING)
2423          {          {
2424            if (token->type == CHARACTER && token->opr.c == ',')            if (token->type == CHARACTER && token->opr.c == ',')
2425              start = 0; /* We treat "{,m}" as "{0,m}".  */              start = 0; /* We treat "{,m}" as "{0,m}".  */
# Line 2536  parse_dup_op (elem, regexp, dfa, token, Line 2429  parse_dup_op (elem, regexp, dfa, token,
2429                return NULL;                return NULL;
2430              }              }
2431          }          }
2432        if (BE (start != -2, 1))        if (BE (start != REG_ERROR, 1))
2433          {          {
2434            /* We treat "{n}" as "{n,n}".  */            /* We treat "{n}" as "{n,n}".  */
2435            end = ((token->type == OP_CLOSE_DUP_NUM) ? start            end = ((token->type == OP_CLOSE_DUP_NUM) ? start
2436                   : ((token->type == CHARACTER && token->opr.c == ',')                   : ((token->type == CHARACTER && token->opr.c == ',')
2437                      ? fetch_number (regexp, token, syntax) : -2));                      ? fetch_number (regexp, token, syntax) : REG_ERROR));
2438          }          }
2439        if (BE (start == -2 || end == -2, 0))        if (BE (start == REG_ERROR || end == REG_ERROR, 0))
2440          {          {
2441            /* Invalid sequence.  */            /* Invalid sequence.  */
2442            if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))            if (BE (!(syntax & REG_INVALID_INTERVAL_ORD), 0))
2443              {              {
2444                if (token->type == END_OF_RE)                if (token->type == END_OF_RE)
2445                  *err = REG_EBRACE;                  *err = REG_EBRACE;
# Line 2565  parse_dup_op (elem, regexp, dfa, token, Line 2458  parse_dup_op (elem, regexp, dfa, token,
2458            return elem;            return elem;
2459          }          }
2460    
2461        if (BE (end != -1 && start > end, 0))        if (BE (end != REG_MISSING && start > end, 0))
2462          {          {
2463            /* First number greater than second.  */            /* First number greater than second.  */
2464            *err = REG_BADBR;            *err = REG_BADBR;
# Line 2575  parse_dup_op (elem, regexp, dfa, token, Line 2468  parse_dup_op (elem, regexp, dfa, token,
2468    else    else
2469      {      {
2470        start = (token->type == OP_DUP_PLUS) ? 1 : 0;        start = (token->type == OP_DUP_PLUS) ? 1 : 0;
2471        end = (token->type == OP_DUP_QUESTION) ? 1 : -1;        end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING;
2472      }      }
2473    
2474    fetch_token (token, regexp, syntax);    fetch_token (token, regexp, syntax);
# Line 2613  parse_dup_op (elem, regexp, dfa, token, Line 2506  parse_dup_op (elem, regexp, dfa, token,
2506    if (elem->token.type == SUBEXP)    if (elem->token.type == SUBEXP)
2507      postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);      postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
2508    
2509    tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT));    tree = create_tree (dfa, elem, NULL,
2510                          (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT));
2511    if (BE (tree == NULL, 0))    if (BE (tree == NULL, 0))
2512      goto parse_dup_op_espace;      goto parse_dup_op_espace;
2513    
2514    /* This loop is actually executed only when end != -1,    /* This loop is actually executed only when end != REG_MISSING,
2515       to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have       to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
2516       already created the start+1-th copy.  */       already created the start+1-th copy.  */
2517    for (i = start + 2; i <= end; ++i)    if ((Idx) -1 < 0 || end != REG_MISSING)
2518      {      for (i = start + 2; i <= end; ++i)
2519        elem = duplicate_tree (elem, dfa);        {
2520        tree = create_tree (dfa, tree, elem, CONCAT);          elem = duplicate_tree (elem, dfa);
2521        if (BE (elem == NULL || tree == NULL, 0))          tree = create_tree (dfa, tree, elem, CONCAT);
2522          goto parse_dup_op_espace;          if (BE (elem == NULL || tree == NULL, 0))
2523              goto parse_dup_op_espace;
2524        tree = create_tree (dfa, tree, NULL, OP_ALT);  
2525        if (BE (tree == NULL, 0))          tree = create_tree (dfa, tree, NULL, OP_ALT);
2526          goto parse_dup_op_espace;          if (BE (tree == NULL, 0))
2527      }            goto parse_dup_op_espace;
2528          }
2529    
2530    if (old_tree)    if (old_tree)
2531      tree = create_tree (dfa, old_tree, tree, CONCAT);      tree = create_tree (dfa, old_tree, tree, CONCAT);
# Line 2655  parse_dup_op (elem, regexp, dfa, token, Line 2550  parse_dup_op (elem, regexp, dfa, token,
2550       update it.  */       update it.  */
2551    
2552  static reg_errcode_t  static reg_errcode_t
2553    build_range_exp (re_bitset_ptr_t sbcset,
2554  # ifdef RE_ENABLE_I18N  # ifdef RE_ENABLE_I18N
2555  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)                   re_charset_t *mbcset, Idx *range_alloc,
2556       re_charset_t *mbcset;  # endif
2557       int *range_alloc;                   bracket_elem_t *start_elem, bracket_elem_t *end_elem)
 # else /* not RE_ENABLE_I18N */  
 build_range_exp (sbcset, start_elem, end_elem)  
 # endif /* not RE_ENABLE_I18N */  
      re_bitset_ptr_t sbcset;  
      bracket_elem_t *start_elem, *end_elem;  
2558  {  {
2559    unsigned int start_ch, end_ch;    unsigned int start_ch, end_ch;
2560    /* Equivalence Classes and Character Classes can't be a range start/end.  */    /* Equivalence Classes and Character Classes can't be a range start/end.  */
# Line 2715  build_range_exp (sbcset, start_elem, end Line 2606  build_range_exp (sbcset, start_elem, end
2606            {            {
2607              /* There is not enough space, need realloc.  */              /* There is not enough space, need realloc.  */
2608              wchar_t *new_array_start, *new_array_end;              wchar_t *new_array_start, *new_array_end;
2609              int new_nranges;              Idx new_nranges;
2610    
2611              /* +1 in case of mbcset->nranges is 0.  */              new_nranges = mbcset->nranges;
             new_nranges = 2 * mbcset->nranges + 1;  
2612              /* Use realloc since mbcset->range_starts and mbcset->range_ends              /* Use realloc since mbcset->range_starts and mbcset->range_ends
2613                 are NULL if *range_alloc == 0.  */                 are NULL if *range_alloc == 0.  */
2614              new_array_start = re_realloc (mbcset->range_starts, wchar_t,              new_array_start = re_x2realloc (mbcset->range_starts, wchar_t,
2615                                            new_nranges);                                              &new_nranges);
2616              new_array_end = re_realloc (mbcset->range_ends, wchar_t,              new_array_end = re_realloc (mbcset->range_ends, wchar_t,
2617                                          new_nranges);                                          new_nranges);
2618    
# Line 2776  build_range_exp (sbcset, start_elem, end Line 2666  build_range_exp (sbcset, start_elem, end
2666     pointer argument since we may update it.  */     pointer argument since we may update it.  */
2667    
2668  static reg_errcode_t  static reg_errcode_t
2669    build_collating_symbol (re_bitset_ptr_t sbcset,
2670  # ifdef RE_ENABLE_I18N  # ifdef RE_ENABLE_I18N
2671  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)                          re_charset_t *mbcset, Idx *coll_sym_alloc,
2672       re_charset_t *mbcset;  # endif
2673       int *coll_sym_alloc;                          const unsigned char *name)
 # else /* not RE_ENABLE_I18N */  
 build_collating_symbol (sbcset, name)  
 # endif /* not RE_ENABLE_I18N */  
      re_bitset_ptr_t sbcset;  
      const unsigned char *name;  
2674  {  {
2675    size_t name_len = strlen ((const char *) name);    size_t name_len = strlen ((const char *) name);
2676    if (BE (name_len != 1, 0))    if (BE (name_len != 1, 0))
# Line 2801  build_collating_symbol (sbcset, name) Line 2687  build_collating_symbol (sbcset, name)
2687     "[[.a-a.]]" etc.  */     "[[.a-a.]]" etc.  */
2688    
2689  static bin_tree_t *  static bin_tree_t *
2690  parse_bracket_exp (regexp, dfa, token, syntax, err)  parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
2691       re_string_t *regexp;                     reg_syntax_t syntax, reg_errcode_t *err)
      re_dfa_t *dfa;  
      re_token_t *token;  
      reg_syntax_t syntax;  
      reg_errcode_t *err;  
2692  {  {
2693  #ifdef _LIBC  #ifdef _LIBC
2694    const unsigned char *collseqmb;    const unsigned char *collseqmb;
# Line 2822  parse_bracket_exp (regexp, dfa, token, s Line 2704  parse_bracket_exp (regexp, dfa, token, s
2704    
2705    auto inline int32_t    auto inline int32_t
2706    __attribute ((always_inline))    __attribute ((always_inline))
2707    seek_collating_symbol_entry (name, name_len)    seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
          const unsigned char *name;  
          size_t name_len;  
2708      {      {
2709        int32_t hash = elem_hash ((const char *) name, name_len);        int32_t hash = elem_hash ((const char *) name, name_len);
2710        int32_t elem = hash % table_size;        int32_t elem = hash % table_size;
# Line 2855  parse_bracket_exp (regexp, dfa, token, s Line 2735  parse_bracket_exp (regexp, dfa, token, s
2735    
2736    auto inline unsigned int    auto inline unsigned int
2737    __attribute ((always_inline))    __attribute ((always_inline))
2738    lookup_collation_sequence_value (br_elem)    lookup_collation_sequence_value (bracket_elem_t *br_elem)
          bracket_elem_t *br_elem;  
2739      {      {
2740        if (br_elem->type == SB_CHAR)        if (br_elem->type == SB_CHAR)
2741          {          {
# Line 2923  parse_bracket_exp (regexp, dfa, token, s Line 2802  parse_bracket_exp (regexp, dfa, token, s
2802    
2803    auto inline reg_errcode_t    auto inline reg_errcode_t
2804    __attribute ((always_inline))    __attribute ((always_inline))
2805    build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)    build_range_exp (re_bitset_ptr_t sbcset, re_charset_t *mbcset,
2806           re_charset_t *mbcset;                     Idx *range_alloc,
2807           int *range_alloc;                     bracket_elem_t *start_elem, bracket_elem_t *end_elem)
          re_bitset_ptr_t sbcset;  
          bracket_elem_t *start_elem, *end_elem;  
2808      {      {
2809        unsigned int ch;        unsigned int ch;
2810        uint32_t start_collseq;        uint32_t start_collseq;
# Line 2945  parse_bracket_exp (regexp, dfa, token, s Line 2822  parse_bracket_exp (regexp, dfa, token, s
2822        /* Check start/end collation sequence values.  */        /* Check start/end collation sequence values.  */
2823        if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))        if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
2824          return REG_ECOLLATE;          return REG_ECOLLATE;
2825        if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))        if (BE ((syntax & REG_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
2826          return REG_ERANGE;          return REG_ERANGE;
2827    
2828        /* Got valid collation sequence values, add them as a new entry.        /* Got valid collation sequence values, add them as a new entry.
# Line 2960  parse_bracket_exp (regexp, dfa, token, s Line 2837  parse_bracket_exp (regexp, dfa, token, s
2837                /* There is not enough space, need realloc.  */                /* There is not enough space, need realloc.  */
2838                uint32_t *new_array_start;                uint32_t *new_array_start;
2839                uint32_t *new_array_end;                uint32_t *new_array_end;
2840                int new_nranges;                Idx new_nranges;
2841    
2842                /* +1 in case of mbcset->nranges is 0.  */                new_nranges = mbcset->nranges;
2843                new_nranges = 2 * mbcset->nranges + 1;                new_array_start = re_x2realloc (mbcset->range_starts, uint32_t,
2844                new_array_start = re_realloc (mbcset->range_starts, uint32_t,                                                &new_nranges);
                                             new_nranges);  
2845                new_array_end = re_realloc (mbcset->range_ends, uint32_t,                new_array_end = re_realloc (mbcset->range_ends, uint32_t,
2846                                            new_nranges);                                            new_nranges);
2847    
# Line 3006  parse_bracket_exp (regexp, dfa, token, s Line 2882  parse_bracket_exp (regexp, dfa, token, s
2882    
2883    auto inline reg_errcode_t    auto inline reg_errcode_t
2884    __attribute ((always_inline))    __attribute ((always_inline))
2885    build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)    build_collating_symbol (re_bitset_ptr_t sbcset, re_charset_t *mbcset,
2886           re_charset_t *mbcset;                            Idx *coll_sym_alloc, const unsigned char *name)
          int *coll_sym_alloc;  
          re_bitset_ptr_t sbcset;  
          const unsigned char *name;  
2887      {      {
2888        int32_t elem, idx;        int32_t elem, idx;
2889        size_t name_len = strlen ((const char *) name);        size_t name_len = strlen ((const char *) name);
# Line 3039  parse_bracket_exp (regexp, dfa, token, s Line 2912  parse_bracket_exp (regexp, dfa, token, s
2912            if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))            if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
2913              {              {
2914                /* Not enough, realloc it.  */                /* Not enough, realloc it.  */
2915                /* +1 in case of mbcset->ncoll_syms is 0.  */                Idx new_coll_sym_alloc = mbcset->ncoll_syms;
               int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;  
2916                /* Use realloc since mbcset->coll_syms is NULL                /* Use realloc since mbcset->coll_syms is NULL
2917                   if *alloc == 0.  */                   if *alloc == 0.  */
2918                int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,                int32_t *new_coll_syms = re_x2realloc (mbcset->coll_syms, int32_t,
2919                                                     new_coll_sym_alloc);                                                       &new_coll_sym_alloc);
2920                if (BE (new_coll_syms == NULL, 0))                if (BE (new_coll_syms == NULL, 0))
2921                  return REG_ESPACE;                  return REG_ESPACE;
2922                mbcset->coll_syms = new_coll_syms;                mbcset->coll_syms = new_coll_syms;
# Line 3070  parse_bracket_exp (regexp, dfa, token, s Line 2942  parse_bracket_exp (regexp, dfa, token, s
2942    re_bitset_ptr_t sbcset;    re_bitset_ptr_t sbcset;
2943  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2944    re_charset_t *mbcset;    re_charset_t *mbcset;
2945    int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;    Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
2946    int equiv_class_alloc = 0, char_class_alloc = 0;    Idx equiv_class_alloc = 0, char_class_alloc = 0;
2947  #endif /* not RE_ENABLE_I18N */  #endif /* not RE_ENABLE_I18N */
2948    int non_match = 0;    bool non_match = false;
2949    bin_tree_t *work_tree;    bin_tree_t *work_tree;
2950    int token_len;    int token_len;
2951    int first_round = 1;    bool first_round = true;
2952  #ifdef _LIBC  #ifdef _LIBC
2953    collseqmb = (const unsigned char *)    collseqmb = (const unsigned char *)
2954      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
# Line 3094  parse_bracket_exp (regexp, dfa, token, s Line 2966  parse_bracket_exp (regexp, dfa, token, s
2966                                                     _NL_COLLATE_SYMB_EXTRAMB);                                                     _NL_COLLATE_SYMB_EXTRAMB);
2967      }      }
2968  #endif  #endif
2969    sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);    sbcset = re_calloc (unsigned int, BITSET_UINTS);
2970  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2971    mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);    mbcset = re_calloc (re_charset_t, 1);
2972  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
2973  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2974    if (BE (sbcset == NULL || mbcset == NULL, 0))    if (BE (sbcset == NULL || mbcset == NULL, 0))
# Line 3119  parse_bracket_exp (regexp, dfa, token, s Line 2991  parse_bracket_exp (regexp, dfa, token, s
2991  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2992        mbcset->non_match = 1;        mbcset->non_match = 1;
2993  #endif /* not RE_ENABLE_I18N */  #endif /* not RE_ENABLE_I18N */
2994        non_match = 1;        non_match = true;
2995        if (syntax & RE_HAT_LISTS_NOT_NEWLINE)        if (syntax & REG_HAT_LISTS_NOT_NEWLINE)
2996          bitset_set (sbcset, '\0');          bitset_set (sbcset, '\0');
2997        re_string_skip_bytes (regexp, token_len); /* Skip a token.  */        re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
2998        token_len = peek_token_bracket (token, regexp, syntax);        token_len = peek_token_bracket (token, regexp, syntax);
# Line 3141  parse_bracket_exp (regexp, dfa, token, s Line 3013  parse_bracket_exp (regexp, dfa, token, s
3013        unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];        unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
3014        unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];        unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
3015        reg_errcode_t ret;        reg_errcode_t ret;
3016        int token_len2 = 0, is_range_exp = 0;        int token_len2 = 0;
3017          bool is_range_exp = false;
3018        re_token_t token2;        re_token_t token2;
3019    
3020        start_elem.opr.name = start_name_buf;        start_elem.opr.name = start_name_buf;
# Line 3152  parse_bracket_exp (regexp, dfa, token, s Line 3025  parse_bracket_exp (regexp, dfa, token, s
3025            *err = ret;            *err = ret;
3026            goto parse_bracket_exp_free_return;            goto parse_bracket_exp_free_return;
3027          }          }
3028        first_round = 0;        first_round = false;
3029    
3030        /* Get information about the next token.  We need it in any case.  */        /* Get information about the next token.  We need it in any case.  */
3031        token_len = peek_token_bracket (token, regexp, syntax);        token_len = peek_token_bracket (token, regexp, syntax);
# Line 3181  parse_bracket_exp (regexp, dfa, token, s Line 3054  parse_bracket_exp (regexp, dfa, token, s
3054                    token->type = CHARACTER;                    token->type = CHARACTER;
3055                  }                  }
3056                else                else
3057                  is_range_exp = 1;                  is_range_exp = true;
3058              }              }
3059          }          }
3060    
3061        if (is_range_exp == 1)        if (is_range_exp == true)
3062          {          {
3063            end_elem.opr.name = end_name_buf;            end_elem.opr.name = end_name_buf;
3064            ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,            ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
3065                                         dfa, syntax, 1);                                         dfa, syntax, true);
3066            if (BE (ret != REG_NOERROR, 0))            if (BE (ret != REG_NOERROR, 0))
3067              {              {
3068                *err = ret;                *err = ret;
# Line 3227  parse_bracket_exp (regexp, dfa, token, s Line 3100  parse_bracket_exp (regexp, dfa, token, s
3100                  {                  {
3101                    wchar_t *new_mbchars;                    wchar_t *new_mbchars;
3102                    /* Not enough, realloc it.  */                    /* Not enough, realloc it.  */
3103                    /* +1 in case of mbcset->nmbchars is 0.  */                    mbchar_alloc = mbcset->nmbchars;
                   mbchar_alloc = 2 * mbcset->nmbchars + 1;  
3104                    /* Use realloc since array is NULL if *alloc == 0.  */                    /* Use realloc since array is NULL if *alloc == 0.  */
3105                    new_mbchars = re_realloc (mbcset->mbchars, wchar_t,                    new_mbchars = re_x2realloc (mbcset->mbchars, wchar_t,
3106                                              mbchar_alloc);                                                &mbchar_alloc);
3107                    if (BE (new_mbchars == NULL, 0))                    if (BE (new_mbchars == NULL, 0))
3108                      goto parse_bracket_exp_espace;                      goto parse_bracket_exp_espace;
3109                    mbcset->mbchars = new_mbchars;                    mbcset->mbchars = new_mbchars;
# Line 3357  parse_bracket_exp (regexp, dfa, token, s Line 3229  parse_bracket_exp (regexp, dfa, token, s
3229  /* Parse an element in the bracket expression.  */  /* Parse an element in the bracket expression.  */
3230    
3231  static reg_errcode_t  static reg_errcode_t
3232  parse_bracket_element (elem, regexp, token, token_len, dfa, syntax,  parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
3233                         accept_hyphen)                         re_token_t *token, int token_len, re_dfa_t *dfa,
3234       bracket_elem_t *elem;                         reg_syntax_t syntax, bool accept_hyphen)
      re_string_t *regexp;  
      re_token_t *token;  
      int token_len;  
      re_dfa_t *dfa;  
      reg_syntax_t syntax;  
      int accept_hyphen;  
3235  {  {
3236  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3237    int cur_char_size;    int cur_char_size;
# Line 3403  parse_bracket_element (elem, regexp, tok Line 3269  parse_bracket_element (elem, regexp, tok
3269     [=<equivalent_class>=].  */     [=<equivalent_class>=].  */
3270    
3271  static reg_errcode_t  static reg_errcode_t
3272  parse_bracket_symbol (elem, regexp, token)  parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
3273       bracket_elem_t *elem;                        re_token_t *token)
      re_string_t *regexp;  
      re_token_t *token;  
3274  {  {
3275    unsigned char ch, delim = token->opr.c;    unsigned char ch, delim = token->opr.c;
3276    int i = 0;    int i = 0;
# Line 3452  parse_bracket_symbol (elem, regexp, toke Line 3316  parse_bracket_symbol (elem, regexp, toke
3316       is a pointer argument sinse we may update it.  */       is a pointer argument sinse we may update it.  */
3317    
3318  static reg_errcode_t  static reg_errcode_t
3319    build_equiv_class (re_bitset_ptr_t sbcset,
3320  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3321  build_equiv_class (sbcset, mbcset, equiv_class_alloc, name)                     re_charset_t *mbcset, Idx *equiv_class_alloc,
3322       re_charset_t *mbcset;  #endif
3323       int *equiv_class_alloc;                     const unsigned char *name)
 #else /* not RE_ENABLE_I18N */  
 build_equiv_class (sbcset, name)  
 #endif /* not RE_ENABLE_I18N */  
      re_bitset_ptr_t sbcset;  
      const unsigned char *name;  
3324  {  {
3325  #if defined _LIBC  #if defined _LIBC
3326    uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);    uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
# Line 3517  build_equiv_class (sbcset, name) Line 3377  build_equiv_class (sbcset, name)
3377        if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))        if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
3378          {          {
3379            /* Not enough, realloc it.  */            /* Not enough, realloc it.  */
3380            /* +1 in case of mbcset->nequiv_classes is 0.  */            Idx new_equiv_class_alloc = mbcset->nequiv_classes;
           int new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;  
3381            /* Use realloc since the array is NULL if *alloc == 0.  */            /* Use realloc since the array is NULL if *alloc == 0.  */
3382            int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,            int32_t *new_equiv_classes = re_x2realloc (mbcset->equiv_classes,
3383                                                     int32_t,                                                       int32_t,
3384                                                     new_equiv_class_alloc);                                                       &new_equiv_class_alloc);
3385            if (BE (new_equiv_classes == NULL, 0))            if (BE (new_equiv_classes == NULL, 0))
3386              return REG_ESPACE;              return REG_ESPACE;
3387            mbcset->equiv_classes = new_equiv_classes;            mbcset->equiv_classes = new_equiv_classes;
# Line 3547  build_equiv_class (sbcset, name) Line 3406  build_equiv_class (sbcset, name)
3406       is a pointer argument sinse we may update it.  */       is a pointer argument sinse we may update it.  */
3407    
3408  static reg_errcode_t  static reg_errcode_t
3409    build_charclass (unsigned REG_TRANSLATE_TYPE trans, re_bitset_ptr_t sbcset,
3410  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3411  build_charclass (trans, sbcset, mbcset, char_class_alloc, class_name, syntax)                   re_charset_t *mbcset, Idx *char_class_alloc,
3412       re_charset_t *mbcset;  #endif
3413       int *char_class_alloc;                   const unsigned char *class_name, reg_syntax_t syntax)
 #else /* not RE_ENABLE_I18N */  
 build_charclass (trans, sbcset, class_name, syntax)  
 #endif /* not RE_ENABLE_I18N */  
      unsigned RE_TRANSLATE_TYPE trans;  
      re_bitset_ptr_t sbcset;  
      const unsigned char *class_name;  
      reg_syntax_t syntax;  
3414  {  {
3415    int i;    int i;
3416    const char *name = (const char *) class_name;    const char *name = (const char *) class_name;
3417    
3418    /* In case of REG_ICASE "upper" and "lower" match the both of    /* In case of REG_ICASE "upper" and "lower" match the both of
3419       upper and lower cases.  */       upper and lower cases.  */
3420    if ((syntax & RE_ICASE)    if ((syntax & REG_IGNORE_CASE)
3421        && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))        && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
3422      name = "alpha";      name = "alpha";
3423    
# Line 3573  build_charclass (trans, sbcset, class_na Line 3426  build_charclass (trans, sbcset, class_na
3426    if (BE (*char_class_alloc == mbcset->nchar_classes, 0))    if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
3427      {      {
3428        /* Not enough, realloc it.  */        /* Not enough, realloc it.  */
3429        /* +1 in case of mbcset->nchar_classes is 0.  */        Idx new_char_class_alloc = mbcset->nchar_classes;
       int new_char_class_alloc = 2 * mbcset->nchar_classes + 1;  
3430        /* Use realloc since array is NULL if *alloc == 0.  */        /* Use realloc since array is NULL if *alloc == 0.  */
3431        wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,        wctype_t *new_char_classes = re_x2realloc (mbcset->char_classes, wctype_t,
3432                                                 new_char_class_alloc);                                                   &new_char_class_alloc);
3433        if (BE (new_char_classes == NULL, 0))        if (BE (new_char_classes == NULL, 0))
3434          return REG_ESPACE;          return REG_ESPACE;
3435        mbcset->char_classes = new_char_classes;        mbcset->char_classes = new_char_classes;
# Line 3627  build_charclass (trans, sbcset, class_na Line 3479  build_charclass (trans, sbcset, class_na
3479  }  }
3480    
3481  static bin_tree_t *  static bin_tree_t *
3482  build_charclass_op (dfa, trans, class_name, extra, non_match, err)  build_charclass_op (re_dfa_t *dfa, unsigned REG_TRANSLATE_TYPE trans,
3483       re_dfa_t *dfa;                      const unsigned char *class_name,
3484       unsigned RE_TRANSLATE_TYPE trans;                      const unsigned char *extra,
3485       const unsigned char *class_name;                      bool non_match, reg_errcode_t *err)
      const unsigned char *extra;  
      int non_match;  
      reg_errcode_t *err;  
3486  {  {
3487    re_bitset_ptr_t sbcset;    re_bitset_ptr_t sbcset;
3488  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3489    re_charset_t *mbcset;    re_charset_t *mbcset;
3490    int alloc = 0;    Idx alloc = 0;
3491  #endif /* not RE_ENABLE_I18N */  #endif /* not RE_ENABLE_I18N */
3492    reg_errcode_t ret;    reg_errcode_t ret;
3493    re_token_t br_token;    re_token_t br_token;
3494    bin_tree_t *tree;    bin_tree_t *tree;
3495    
3496    sbcset = (re_bitset_ptr_t) calloc (sizeof (unsigned int), BITSET_UINTS);    sbcset = re_calloc (unsigned int, BITSET_UINTS);
3497  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3498    mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);    mbcset = re_calloc (re_charset_t, 1);
3499  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
3500    
3501  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
# Line 3663  build_charclass_op (dfa, trans, class_na Line 3512  build_charclass_op (dfa, trans, class_na
3512      {      {
3513  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3514        /*        /*
3515        if (syntax & RE_HAT_LISTS_NOT_NEWLINE)        if (syntax & REG_HAT_LISTS_NOT_NEWLINE)
3516          bitset_set(cset->sbcset, '\0');          bitset_set(cset->sbcset, '\0');
3517        */        */
3518        mbcset->non_match = 1;        mbcset->non_match = 1;
# Line 3743  build_charclass_op (dfa, trans, class_na Line 3592  build_charclass_op (dfa, trans, class_na
3592    
3593  /* This is intended for the expressions like "a{1,3}".  /* This is intended for the expressions like "a{1,3}".
3594     Fetch a number from `input', and return the number.     Fetch a number from `input', and return the number.
3595     Return -1, if the number field is empty like "{,1}".     Return REG_MISSING if the number field is empty like "{,1}".
3596     Return -2, If an error is occured.  */     Return REG_ERROR if an error occurred.  */
3597    
3598  static int  static Idx
3599  fetch_number (input, token, syntax)  fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
      re_string_t *input;  
      re_token_t *token;  
      reg_syntax_t syntax;  
3600  {  {
3601    int num = -1;    Idx num = REG_MISSING;
3602    unsigned char c;    unsigned char c;
3603    while (1)    while (1)
3604      {      {
3605        fetch_token (token, input, syntax);        fetch_token (token, input, syntax);
3606        c = token->opr.c;        c = token->opr.c;
3607        if (BE (token->type == END_OF_RE, 0))        if (BE (token->type == END_OF_RE, 0))
3608          return -2;          return REG_ERROR;
3609        if (token->type == OP_CLOSE_DUP_NUM || c == ',')        if (token->type == OP_CLOSE_DUP_NUM || c == ',')
3610          break;          break;
3611        num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)        num = ((token->type != CHARACTER || c < '0' || '9' < c
3612               ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0'));                || num == REG_ERROR)
3613        num = (num > RE_DUP_MAX) ? -2 : num;               ? REG_ERROR
3614                 : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0'));
3615          num = (num > REG_DUP_MAX) ? REG_ERROR : num;
3616      }      }
3617    return num;    return num;
3618  }  }
# Line 3790  free_charset (re_charset_t *cset) Line 3638  free_charset (re_charset_t *cset)
3638  /* Create a tree node.  */  /* Create a tree node.  */
3639    
3640  static bin_tree_t *  static bin_tree_t *
3641  create_tree (dfa, left, right, type)  create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
3642       re_dfa_t *dfa;               re_token_type_t type)
      bin_tree_t *left;  
      bin_tree_t *right;  
      re_token_type_t type;  
3643  {  {
3644    re_token_t t;    re_token_t t;
3645    t.type = type;    t.type = type;
# Line 3802  create_tree (dfa, left, right, type) Line 3647  create_tree (dfa, left, right, type)
3647  }  }
3648    
3649  static bin_tree_t *  static bin_tree_t *
3650  create_token_tree (dfa, left, right, token)  create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
3651       re_dfa_t *dfa;                     const re_token_t *token)
      bin_tree_t *left;  
      bin_tree_t *right;  
      const re_token_t *token;  
3652  {  {
3653    bin_tree_t *tree;    bin_tree_t *tree;
3654    if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))    if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
# Line 3829  create_token_tree (dfa, left, right, tok Line 3671  create_token_tree (dfa, left, right, tok
3671    tree->token.opt_subexp = 0;    tree->token.opt_subexp = 0;
3672    tree->first = NULL;    tree->first = NULL;
3673    tree->next = NULL;    tree->next = NULL;
3674    tree->node_idx = -1;    tree->node_idx = REG_MISSING;
3675    
3676    if (left != NULL)    if (left != NULL)
3677      left->parent = tree;      left->parent = tree;
# Line 3842  create_token_tree (dfa, left, right, tok Line 3684  create_token_tree (dfa, left, right, tok
3684     To be called from preorder or postorder.  */     To be called from preorder or postorder.  */
3685    
3686  static reg_errcode_t  static reg_errcode_t
3687  mark_opt_subexp (extra, node)  mark_opt_subexp (void *extra, bin_tree_t *node)
      void *extra;  
      bin_tree_t *node;  
3688  {  {
3689    int idx = (int) (long) extra;    Idx idx = (Idx) (long) extra;
3690    if (node->token.type == SUBEXP && node->token.opr.idx == idx)    if (node->token.type == SUBEXP && node->token.opr.idx == idx)
3691      node->token.opt_subexp = 1;      node->token.opt_subexp = 1;
3692    
# Line 3884  free_tree (void *extra, bin_tree_t *node Line 3724  free_tree (void *extra, bin_tree_t *node
3724     it's easier to duplicate.  */     it's easier to duplicate.  */
3725    
3726  static bin_tree_t *  static bin_tree_t *
3727  duplicate_tree (root, dfa)  duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
      const bin_tree_t *root;  
      re_dfa_t *dfa;  
3728  {  {
3729    const bin_tree_t *node;    const bin_tree_t *node;
3730    bin_tree_t *dup_root;    bin_tree_t *dup_root;

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26