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

Diff of /ccvs/lib/regexec.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 match_ctx_init (re_match_context_t *cache, int eflags,  static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
21                                       int n) internal_function;                                       Idx n) internal_function;
22  static void match_ctx_clean (re_match_context_t *mctx) internal_function;  static void match_ctx_clean (re_match_context_t *mctx) internal_function;
23  static void match_ctx_free (re_match_context_t *cache) internal_function;  static void match_ctx_free (re_match_context_t *cache) internal_function;
24  static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node,  static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node,
25                                            int str_idx, int from, int to)                                            Idx str_idx, Idx from, Idx to)
26       internal_function;       internal_function;
27  static int search_cur_bkref_entry (re_match_context_t *mctx, int str_idx)  static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
28       internal_function;       internal_function;
29  static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node,  static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node,
30                                             int str_idx) internal_function;                                             Idx str_idx) internal_function;
31  static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,  static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
32                                                     int node, int str_idx)                                                      Idx node, Idx str_idx)
33       internal_function;       internal_function;
34  static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,  static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
35                             re_dfastate_t **limited_sts, int last_node,                             re_dfastate_t **limited_sts, Idx last_node,
36                             int last_str_idx)                             Idx last_str_idx)
37       internal_function;       internal_function;
38  static reg_errcode_t re_search_internal (const regex_t *preg,  static reg_errcode_t re_search_internal (const regex_t *preg,
39                                           const char *string, int length,                                           const char *string, Idx length,
40                                           int start, int range, int stop,                                           Idx start, Idx last_start, Idx stop,
41                                           size_t nmatch, regmatch_t pmatch[],                                           size_t nmatch, regmatch_t pmatch[],
42                                           int eflags) internal_function;                                           int eflags) internal_function;
43  static int re_search_2_stub (struct re_pattern_buffer *bufp,  static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp,
44                               const char *string1, int length1,                                    const char *string1, Idx length1,
45                               const char *string2, int length2,                                    const char *string2, Idx length2,
46                               int start, int range, struct re_registers *regs,                                    Idx start, regoff_t range,
47                               int stop, int ret_len) internal_function;                                    struct re_registers *regs,
48  static int re_search_stub (struct re_pattern_buffer *bufp,                                    Idx stop, bool ret_len) internal_function;
49                             const char *string, int length, int start,  static regoff_t re_search_stub (struct re_pattern_buffer *bufp,
50                             int range, int stop, struct re_registers *regs,                                  const char *string, Idx length, Idx start,
51                             int ret_len) internal_function;                                  regoff_t range, Idx stop,
52                                    struct re_registers *regs,
53                                    bool ret_len) internal_function;
54  static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,  static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
55                                int nregs, int regs_allocated) internal_function;                                Idx nregs, int regs_allocated) internal_function;
 static inline re_dfastate_t *acquire_init_state_context  
      (reg_errcode_t *err, const re_match_context_t *mctx, int idx)  
      __attribute ((always_inline)) internal_function;  
56  static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)  static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)
57       internal_function;       internal_function;
58  static int check_matching (re_match_context_t *mctx, int fl_longest_match,  static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match,
59                             int *p_match_first)                             Idx *p_match_first)
60       internal_function;       internal_function;
61  static int check_halt_node_context (const re_dfa_t *dfa, int node,  static Idx check_halt_state_context (const re_match_context_t *mctx,
62                                      unsigned int context) internal_function;                                       const re_dfastate_t *state, Idx idx)
 static int check_halt_state_context (const re_match_context_t *mctx,  
                                      const re_dfastate_t *state, int idx)  
63       internal_function;       internal_function;
64  static void update_regs (re_dfa_t *dfa, regmatch_t *pmatch,  static void update_regs (re_dfa_t *dfa, regmatch_t *pmatch,
65                           regmatch_t *prev_idx_match, int cur_node,                           regmatch_t *prev_idx_match, Idx cur_node,
66                           int cur_idx, int nmatch) internal_function;                           Idx cur_idx, Idx nmatch) internal_function;
 static int proceed_next_node (const re_match_context_t *mctx,  
                               int nregs, regmatch_t *regs,  
                               int *pidx, int node, re_node_set *eps_via_nodes,  
                               struct re_fail_stack_t *fs) internal_function;  
67  static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,  static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
68                                        int str_idx, int dest_node, int nregs,                                        Idx str_idx, Idx dest_node, Idx nregs,
69                                        regmatch_t *regs,                                        regmatch_t *regs,
70                                        re_node_set *eps_via_nodes) internal_function;                                        re_node_set *eps_via_nodes) internal_function;
 static int pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,  
                            regmatch_t *regs, re_node_set *eps_via_nodes) internal_function;  
71  static reg_errcode_t set_regs (const regex_t *preg,  static reg_errcode_t set_regs (const regex_t *preg,
72                                 const re_match_context_t *mctx,                                 const re_match_context_t *mctx,
73                                 size_t nmatch, regmatch_t *pmatch,                                 size_t nmatch, regmatch_t *pmatch,
74                                 int fl_backtrack) internal_function;                                 bool fl_backtrack) internal_function;
75  static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) internal_function;  static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) internal_function;
76    
77  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
78  static int sift_states_iter_mb (const re_match_context_t *mctx,  static int sift_states_iter_mb (const re_match_context_t *mctx,
79                                  re_sift_context_t *sctx,                                  re_sift_context_t *sctx,
80                                  int node_idx, int str_idx, int max_str_idx) internal_function;                                  Idx node_idx, Idx str_idx, Idx max_str_idx) internal_function;
81  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
82  static reg_errcode_t sift_states_backward (re_match_context_t *mctx,  static reg_errcode_t sift_states_backward (re_match_context_t *mctx,
83                                             re_sift_context_t *sctx) internal_function;                                             re_sift_context_t *sctx) internal_function;
84  static reg_errcode_t build_sifted_states (re_match_context_t *mctx,  static reg_errcode_t build_sifted_states (re_match_context_t *mctx,
85                                            re_sift_context_t *sctx, int str_idx,                                            re_sift_context_t *sctx, Idx str_idx,
86                                            re_node_set *cur_dest) internal_function;                                            re_node_set *cur_dest) internal_function;
87  static reg_errcode_t update_cur_sifted_state (re_match_context_t *mctx,  static reg_errcode_t update_cur_sifted_state (re_match_context_t *mctx,
88                                                re_sift_context_t *sctx,                                                re_sift_context_t *sctx,
89                                                int str_idx,                                                Idx str_idx,
90                                                re_node_set *dest_nodes) internal_function;                                                re_node_set *dest_nodes) internal_function;
91  static reg_errcode_t add_epsilon_src_nodes (re_dfa_t *dfa,  static reg_errcode_t add_epsilon_src_nodes (re_dfa_t *dfa,
92                                              re_node_set *dest_nodes,                                              re_node_set *dest_nodes,
93                                              const re_node_set *candidates) internal_function;                                              const re_node_set *candidates) internal_function;
94  static reg_errcode_t sub_epsilon_src_nodes (re_dfa_t *dfa, int node,  static bool check_dst_limits (const re_match_context_t *mctx,
95                                              re_node_set *dest_nodes,                                const re_node_set *limits,
96                                              const re_node_set *and_nodes) internal_function;                                Idx dst_node, Idx dst_idx, Idx src_node,
97  static int check_dst_limits (re_match_context_t *mctx, re_node_set *limits,                                Idx src_idx) internal_function;
98                               int dst_node, int dst_idx, int src_node,  static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
99                               int src_idx) internal_function;                                          int boundaries, Idx subexp_idx,
100  static int check_dst_limits_calc_pos_1 (re_match_context_t *mctx,                                          Idx from_node, Idx bkref_idx) internal_function;
101                                          int boundaries, int subexp_idx,  static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
102                                          int from_node, int bkref_idx) internal_function;                                        Idx limit, Idx subexp_idx,
103  static int check_dst_limits_calc_pos (re_match_context_t *mctx,                                        Idx node, Idx str_idx,
104                                        int limit, int subexp_idx,                                        Idx bkref_idx) internal_function;
                                       int node, int str_idx,  
                                       int bkref_idx) internal_function;  
105  static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,  static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
106                                            re_node_set *dest_nodes,                                            re_node_set *dest_nodes,
107                                            const re_node_set *candidates,                                            const re_node_set *candidates,
108                                            re_node_set *limits,                                            re_node_set *limits,
109                                            struct re_backref_cache_entry *bkref_ents,                                            struct re_backref_cache_entry *bkref_ents,
110                                            int str_idx) internal_function;                                            Idx str_idx) internal_function;
111  static reg_errcode_t sift_states_bkref (re_match_context_t *mctx,  static reg_errcode_t sift_states_bkref (re_match_context_t *mctx,
112                                          re_sift_context_t *sctx,                                          re_sift_context_t *sctx,
113                                          int str_idx, const re_node_set *candidates) internal_function;                                          Idx str_idx, const re_node_set *candidates) internal_function;
 static reg_errcode_t clean_state_log_if_needed (re_match_context_t *mctx,  
                                                 int next_state_log_idx) internal_function;  
114  static reg_errcode_t merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst,  static reg_errcode_t merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst,
115                                          re_dfastate_t **src, int num) internal_function;                                          re_dfastate_t **src, Idx num) internal_function;
116  static re_dfastate_t *find_recover_state (reg_errcode_t *err,  static re_dfastate_t *find_recover_state (reg_errcode_t *err,
117                                           re_match_context_t *mctx) internal_function;                                           re_match_context_t *mctx) internal_function;
118  static re_dfastate_t *transit_state (reg_errcode_t *err,  static re_dfastate_t *transit_state (reg_errcode_t *err,
# Line 136  static re_dfastate_t *merge_state_with_l Line 123  static re_dfastate_t *merge_state_with_l
123                                              re_dfastate_t *next_state) internal_function;                                              re_dfastate_t *next_state) internal_function;
124  static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,  static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
125                                                  re_node_set *cur_nodes,                                                  re_node_set *cur_nodes,
126                                                  int str_idx) internal_function;                                                  Idx str_idx) internal_function;
127  #if 0  #if 0
128  static re_dfastate_t *transit_state_sb (reg_errcode_t *err,  static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
129                                          re_match_context_t *mctx,                                          re_match_context_t *mctx,
# Line 149  static reg_errcode_t transit_state_mb (r Line 136  static reg_errcode_t transit_state_mb (r
136  static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,  static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
137                                            const re_node_set *nodes) internal_function;                                            const re_node_set *nodes) internal_function;
138  static reg_errcode_t get_subexp (re_match_context_t *mctx,  static reg_errcode_t get_subexp (re_match_context_t *mctx,
139                                   int bkref_node, int bkref_str_idx) internal_function;                                   Idx bkref_node, Idx bkref_str_idx) internal_function;
140  static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,  static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
141                                       const re_sub_match_top_t *sub_top,                                       const re_sub_match_top_t *sub_top,
142                                       re_sub_match_last_t *sub_last,                                       re_sub_match_last_t *sub_last,
143                                       int bkref_node, int bkref_str) internal_function;                                       Idx bkref_node, Idx bkref_str) internal_function;
144  static int find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,  static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
145                               int subexp_idx, int type) internal_function;                               Idx subexp_idx, int type) internal_function;
146  static reg_errcode_t check_arrival (re_match_context_t *mctx,  static reg_errcode_t check_arrival (re_match_context_t *mctx,
147                                      state_array_t *path, int top_node,                                      state_array_t *path, Idx top_node,
148                                      int top_str, int last_node, int last_str,                                      Idx top_str, Idx last_node, Idx last_str,
149                                      int type) internal_function;                                      int type) internal_function;
150  static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,  static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
151                                                     int str_idx,                                                     Idx str_idx,
152                                                     re_node_set *cur_nodes,                                                     re_node_set *cur_nodes,
153                                                     re_node_set *next_nodes) internal_function;                                                     re_node_set *next_nodes) internal_function;
154  static reg_errcode_t check_arrival_expand_ecl (re_dfa_t *dfa,  static reg_errcode_t check_arrival_expand_ecl (re_dfa_t *dfa,
155                                                 re_node_set *cur_nodes,                                                 re_node_set *cur_nodes,
156                                                 int ex_subexp, int type) internal_function;                                                 Idx ex_subexp, int type) internal_function;
157  static reg_errcode_t check_arrival_expand_ecl_sub (re_dfa_t *dfa,  static reg_errcode_t check_arrival_expand_ecl_sub (re_dfa_t *dfa,
158                                                     re_node_set *dst_nodes,                                                     re_node_set *dst_nodes,
159                                                     int target, int ex_subexp,                                                     Idx target, Idx ex_subexp,
160                                                     int type) internal_function;                                                     int type) internal_function;
161  static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,  static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
162                                           re_node_set *cur_nodes, int cur_str,                                           re_node_set *cur_nodes, Idx cur_str,
163                                           int subexp_num, int type) internal_function;                                           Idx subexp_num, int type) internal_function;
164  static int build_trtable (re_dfa_t *dfa,  static bool build_trtable (re_dfa_t *dfa,
165                            re_dfastate_t *state) internal_function;                             re_dfastate_t *state) internal_function;
166  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
167  static int check_node_accept_bytes (re_dfa_t *dfa, int node_idx,  static int check_node_accept_bytes (re_dfa_t *dfa, Idx node_idx,
168                                      const re_string_t *input, int idx) internal_function;                                      const re_string_t *input, Idx idx) internal_function;
169  # ifdef _LIBC  # ifdef _LIBC
170  static unsigned int find_collation_sequence_value (const unsigned char *mbs,  static unsigned int find_collation_sequence_value (const unsigned char *mbs,
171                                                     size_t name_len) internal_function;                                                     size_t name_len) internal_function;
172  # endif /* _LIBC */  # endif /* _LIBC */
173  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
174  static int group_nodes_into_DFAstates (re_dfa_t *dfa,  static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
175                                         const re_dfastate_t *state,                                         const re_dfastate_t *state,
176                                         re_node_set *states_node,                                         re_node_set *states_node,
177                                         bitset *states_ch) internal_function;                                         bitset *states_ch) internal_function;
178  static int check_node_accept (const re_match_context_t *mctx,  static bool check_node_accept (const re_match_context_t *mctx,
179                                const re_token_t *node, int idx) internal_function;                                 const re_token_t *node, Idx idx)
180         internal_function;
181  static reg_errcode_t extend_buffers (re_match_context_t *mctx) internal_function;  static reg_errcode_t extend_buffers (re_match_context_t *mctx) internal_function;
182    
183  /* Entry point for POSIX code.  */  /* Entry point for POSIX code.  */
# Line 209  static reg_errcode_t extend_buffers (re_ Line 197  static reg_errcode_t extend_buffers (re_
197     We return 0 if we find a match and REG_NOMATCH if not.  */     We return 0 if we find a match and REG_NOMATCH if not.  */
198    
199  int  int
200  regexec (preg, string, nmatch, pmatch, eflags)  regexec (const regex_t *__restrict preg, const char *__restrict string,
201      const regex_t *__restrict preg;           size_t nmatch, regmatch_t pmatch[], int eflags)
     const char *__restrict string;  
     size_t nmatch;  
     regmatch_t pmatch[];  
     int eflags;  
202  {  {
203    reg_errcode_t err;    reg_errcode_t err;
204    int start, length;    Idx start, length;
205    re_dfa_t *dfa = (re_dfa_t *)preg->buffer;  #ifdef _LIBC
206      re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
207    #endif
208    
209    if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))    if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
210      return REG_BADPAT;      return REG_BADPAT;
# Line 235  regexec (preg, string, nmatch, pmatch, e Line 221  regexec (preg, string, nmatch, pmatch, e
221      }      }
222    
223    __libc_lock_lock (dfa->lock);    __libc_lock_lock (dfa->lock);
224    if (preg->no_sub)    if (preg->re_no_sub)
225      err = re_search_internal (preg, string, length, start, length - start,      err = re_search_internal (preg, string, length, start, length,
226                                length, 0, NULL, eflags);                                length, 0, NULL, eflags);
227    else    else
228      err = re_search_internal (preg, string, length, start, length - start,      err = re_search_internal (preg, string, length, start, length,
229                                length, nmatch, pmatch, eflags);                                length, nmatch, pmatch, eflags);
230    __libc_lock_unlock (dfa->lock);    __libc_lock_unlock (dfa->lock);
231    return err != REG_NOERROR;    return err != REG_NOERROR;
# Line 285  compat_symbol (libc, __compat_regexec, r Line 271  compat_symbol (libc, __compat_regexec, r
271     the first STOP characters of the concatenation of the strings should be     the first STOP characters of the concatenation of the strings should be
272     concerned.     concerned.
273    
274     If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match     If REGS is not NULL, and BUFP->re_no_sub is not set, the offsets of the match
275     and all groups is stroed in REGS.  (For the "_2" variants, the offsets are     and all groups is stroed in REGS.  (For the "_2" variants, the offsets are
276     computed relative to the concatenation, not relative to the individual     computed relative to the concatenation, not relative to the individual
277     strings.)     strings.)
# Line 294  compat_symbol (libc, __compat_regexec, r Line 280  compat_symbol (libc, __compat_regexec, r
280     return the position of the start of the match.  Return value -1 means no     return the position of the start of the match.  Return value -1 means no
281     match was found and -2 indicates an internal error.  */     match was found and -2 indicates an internal error.  */
282    
283  int  regoff_t
284  re_match (bufp, string, length, start, regs)  re_match (struct re_pattern_buffer *bufp, const char *string,
285      struct re_pattern_buffer *bufp;            Idx length, Idx start, struct re_registers *regs)
     const char *string;  
     int length, start;  
     struct re_registers *regs;  
286  {  {
287    return re_search_stub (bufp, string, length, start, 0, length, regs, 1);    return re_search_stub (bufp, string, length, start, 0, length, regs, true);
288  }  }
289  #ifdef _LIBC  #ifdef _LIBC
290  weak_alias (__re_match, re_match)  weak_alias (__re_match, re_match)
291  #endif  #endif
292    
293  int  regoff_t
294  re_search (bufp, string, length, start, range, regs)  re_search (struct re_pattern_buffer *bufp, const char *string,
295      struct re_pattern_buffer *bufp;             Idx length, Idx start, regoff_t range, struct re_registers *regs)
     const char *string;  
     int length, start, range;  
     struct re_registers *regs;  
296  {  {
297    return re_search_stub (bufp, string, length, start, range, length, regs, 0);    return re_search_stub (bufp, string, length, start, range, length, regs,
298                             false);
299  }  }
300  #ifdef _LIBC  #ifdef _LIBC
301  weak_alias (__re_search, re_search)  weak_alias (__re_search, re_search)
302  #endif  #endif
303    
304  int  regoff_t
305  re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)  re_match_2 (struct re_pattern_buffer *bufp,
306      struct re_pattern_buffer *bufp;              const char *string1, Idx length1,
307      const char *string1, *string2;              const char *string2, Idx length2,
308      int length1, length2, start, stop;              Idx start, struct re_registers *regs, Idx stop)
     struct re_registers *regs;  
309  {  {
310    return re_search_2_stub (bufp, string1, length1, string2, length2,    return re_search_2_stub (bufp, string1, length1, string2, length2,
311                             start, 0, regs, stop, 1);                             start, 0, regs, stop, true);
312  }  }
313  #ifdef _LIBC  #ifdef _LIBC
314  weak_alias (__re_match_2, re_match_2)  weak_alias (__re_match_2, re_match_2)
315  #endif  #endif
316    
317  int  regoff_t
318  re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)  re_search_2 (struct re_pattern_buffer *bufp,
319      struct re_pattern_buffer *bufp;               const char *string1, Idx length1,
320      const char *string1, *string2;               const char *string2, Idx length2,
321      int length1, length2, start, range, stop;               Idx start, regoff_t range, struct re_registers *regs, Idx stop)
     struct re_registers *regs;  
322  {  {
323    return re_search_2_stub (bufp, string1, length1, string2, length2,    return re_search_2_stub (bufp, string1, length1, string2, length2,
324                             start, range, regs, stop, 0);                             start, range, regs, stop, false);
325  }  }
326  #ifdef _LIBC  #ifdef _LIBC
327  weak_alias (__re_search_2, re_search_2)  weak_alias (__re_search_2, re_search_2)
328  #endif  #endif
329    
330  static int  static regoff_t
331  re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,  internal_function
332                    stop, ret_len)  re_search_2_stub (struct re_pattern_buffer *bufp,
333      struct re_pattern_buffer *bufp;                    const char *string1, Idx length1,
334      const char *string1, *string2;                    const char *string2, Idx length2,
335      int length1, length2, start, range, stop, ret_len;                    Idx start, regoff_t range, struct re_registers *regs,
336      struct re_registers *regs;                    Idx stop, bool ret_len)
337  {  {
338    const char *str;    const char *str;
339    int rval;    regoff_t rval;
340    int len = length1 + length2;    Idx len = length1 + length2;
341    int free_str = 0;    char *s = NULL;
342    
343    if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))    if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
344      return -2;      return -2;
345    
346    /* Concatenate the strings.  */    /* Concatenate the strings.  */
347    if (length2 > 0)    if (length2 > 0)
348      if (length1 > 0)      if (length1 > 0)
349        {        {
350          char *s = re_malloc (char, len);          s = re_malloc (char, len);
351    
352          if (BE (s == NULL, 0))          if (BE (s == NULL, 0))
353            return -2;            return -2;
354          memcpy (s, string1, length1);          memcpy (s, string1, length1);
355          memcpy (s + length1, string2, length2);          memcpy (s + length1, string2, length2);
356          str = s;          str = s;
         free_str = 1;  
357        }        }
358      else      else
359        str = string2;        str = string2;
# Line 384  re_search_2_stub (bufp, string1, length1 Line 362  re_search_2_stub (bufp, string1, length1
362    
363    rval = re_search_stub (bufp, str, len, start, range, stop, regs,    rval = re_search_stub (bufp, str, len, start, range, stop, regs,
364                           ret_len);                           ret_len);
365    if (free_str)    re_free (s);
     re_free ((char *) str);  
366    return rval;    return rval;
367  }  }
368    
369  /* The parameters have the same meaning as those of re_search.  /* The parameters have the same meaning as those of re_search.
370     Additional parameters:     Additional parameters:
371     If RET_LEN is nonzero the length of the match is returned (re_match style);     If RET_LEN is true the length of the match is returned (re_match style);
372     otherwise the position of the match is returned.  */     otherwise the position of the match is returned.  */
373    
374  static int  static regoff_t
375  re_search_stub (bufp, string, length, start, range, stop, regs, ret_len)  internal_function
376      struct re_pattern_buffer *bufp;  re_search_stub (struct re_pattern_buffer *bufp,
377      const char *string;                  const char *string, Idx length,
378      int length, start, range, stop, ret_len;                  Idx start, regoff_t range, Idx stop, struct re_registers *regs,
379      struct re_registers *regs;                  bool ret_len)
380  {  {
381    reg_errcode_t result;    reg_errcode_t result;
382    regmatch_t *pmatch;    regmatch_t *pmatch;
383    int nregs, rval;    Idx nregs;
384      regoff_t rval;
385    int eflags = 0;    int eflags = 0;
386    re_dfa_t *dfa = (re_dfa_t *)bufp->buffer;  #ifdef _LIBC
387      re_dfa_t *dfa = (re_dfa_t *) bufp->re_buffer;
388    #endif
389      Idx last_start = start + range;
390    
391    /* Check for out-of-range.  */    /* Check for out-of-range.  */
392    if (BE (start < 0 || start > length, 0))    if (BE (start < 0 || start > length, 0))
393      return -1;      return -1;
394    if (BE (start + range > length, 0))    if (sizeof start < sizeof range)
395      range = length - start;      {
396    else if (BE (start + range < 0, 0))        regoff_t length_offset = length;
397      range = -start;        regoff_t start_offset = start;
398          if (BE (length_offset - start_offset < range, 0))
399            last_start = length;
400          else if (BE (range < - start_offset, 0))
401            last_start = 0;
402        }
403      else
404        {
405          if (BE ((last_start < start) != (range < 0), 0))
406            {
407              /* Overflow occurred when computing last_start; substitute
408                 the extreme value.  */
409              last_start = range < 0 ? 0 : length;
410            }
411          else
412            {
413              if (BE (length < last_start, 0))
414                last_start = length;
415              else if (BE (last_start < 0, 0))
416                last_start = 0;
417            }
418        }
419    
420    __libc_lock_lock (dfa->lock);    __libc_lock_lock (dfa->lock);
421    
422    eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;    eflags |= (bufp->re_not_bol) ? REG_NOTBOL : 0;
423    eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;    eflags |= (bufp->re_not_eol) ? REG_NOTEOL : 0;
424    
425    /* Compile fastmap if we haven't yet.  */    /* Compile fastmap if we haven't yet.  */
426    if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate)    if (start < last_start && bufp->re_fastmap != NULL
427          && !bufp->re_fastmap_accurate)
428      re_compile_fastmap (bufp);      re_compile_fastmap (bufp);
429    
430    if (BE (bufp->no_sub, 0))    if (BE (bufp->re_no_sub, 0))
431      regs = NULL;      regs = NULL;
432    
433    /* We need at least 1 register.  */    /* We need at least 1 register.  */
434    if (regs == NULL)    if (regs == NULL)
435      nregs = 1;      nregs = 1;
436    else if (BE (bufp->regs_allocated == REGS_FIXED &&    else if (BE (bufp->re_regs_allocated == REG_FIXED
437                 regs->num_regs < bufp->re_nsub + 1, 0))                 && regs->rm_num_regs <= bufp->re_nsub, 0))
438      {      {
439        nregs = regs->num_regs;        nregs = regs->rm_num_regs;
440        if (BE (nregs < 1, 0))        if (BE (nregs < 1, 0))
441          {          {
442            /* Nothing can be copied to regs.  */            /* Nothing can be copied to regs.  */
# Line 443  re_search_stub (bufp, string, length, st Line 446  re_search_stub (bufp, string, length, st
446      }      }
447    else    else
448      nregs = bufp->re_nsub + 1;      nregs = bufp->re_nsub + 1;
449    pmatch = re_malloc (regmatch_t, nregs);    pmatch = re_xmalloc (regmatch_t, nregs);
450    if (BE (pmatch == NULL, 0))    if (BE (pmatch == NULL, 0))
451      {      {
452        rval = -2;        rval = -2;
453        goto out;        goto out;
454      }      }
455    
456    result = re_search_internal (bufp, string, length, start, range, stop,    result = re_search_internal (bufp, string, length, start, last_start, stop,
457                                 nregs, pmatch, eflags);                                 nregs, pmatch, eflags);
458    
459    rval = 0;    rval = 0;
# Line 461  re_search_stub (bufp, string, length, st Line 464  re_search_stub (bufp, string, length, st
464    else if (regs != NULL)    else if (regs != NULL)
465      {      {
466        /* If caller wants register contents data back, copy them.  */        /* If caller wants register contents data back, copy them.  */
467        bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,        bufp->re_regs_allocated = re_copy_regs (regs, pmatch, nregs,
468                                             bufp->regs_allocated);                                                bufp->re_regs_allocated);
469        if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))        if (BE (bufp->re_regs_allocated == REG_UNALLOCATED, 0))
470          rval = -2;          rval = -2;
471      }      }
472    
# Line 484  re_search_stub (bufp, string, length, st Line 487  re_search_stub (bufp, string, length, st
487  }  }
488    
489  static unsigned  static unsigned
490  re_copy_regs (regs, pmatch, nregs, regs_allocated)  internal_function
491      struct re_registers *regs;  re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs,
492      regmatch_t *pmatch;                int regs_allocated)
493      int nregs, regs_allocated;  {
494  {    int rval = REG_REALLOCATE;
495    int rval = REGS_REALLOCATE;    Idx i;
496    int i;    Idx need_regs = nregs + 1;
497    int need_regs = nregs + 1;    /* We need one extra element beyond `rm_num_regs' for the `-1' marker GNU code
   /* We need one extra element beyond `num_regs' for the `-1' marker GNU code  
498       uses.  */       uses.  */
499    
500    /* Have the register data arrays been allocated?  */    /* Have the register data arrays been allocated?  */
501    if (regs_allocated == REGS_UNALLOCATED)    if (regs_allocated == REG_UNALLOCATED)
502      { /* No.  So allocate them with malloc.  */      { /* No.  So allocate them with malloc.  */
503        regs->start = re_malloc (regoff_t, need_regs);        regs->rm_start = re_xmalloc (regoff_t, need_regs);
504        regs->end = re_malloc (regoff_t, need_regs);        regs->rm_end = re_malloc (regoff_t, need_regs);
505        if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))        if (BE (regs->rm_start == NULL, 0) || BE (regs->rm_end == NULL, 0))
506          return REGS_UNALLOCATED;          return REG_UNALLOCATED;
507        regs->num_regs = need_regs;        regs->rm_num_regs = need_regs;
508      }      }
509    else if (regs_allocated == REGS_REALLOCATE)    else if (regs_allocated == REG_REALLOCATE)
510      { /* Yes.  If we need more elements than were already      { /* Yes.  If we need more elements than were already
511           allocated, reallocate them.  If we need fewer, just           allocated, reallocate them.  If we need fewer, just
512           leave it alone.  */           leave it alone.  */
513        if (BE (need_regs > regs->num_regs, 0))        if (BE (need_regs > regs->rm_num_regs, 0))
514          {          {
515            regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);            regoff_t *new_start =
516            regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);              re_xrealloc (regs->rm_start, regoff_t, need_regs);
517              regoff_t *new_end = re_realloc (regs->rm_end, regoff_t, need_regs);
518            if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))            if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
519              return REGS_UNALLOCATED;              return REG_UNALLOCATED;
520            regs->start = new_start;            regs->rm_start = new_start;
521            regs->end = new_end;            regs->rm_end = new_end;
522            regs->num_regs = need_regs;            regs->rm_num_regs = need_regs;
523          }          }
524      }      }
525    else    else
526      {      {
527        assert (regs_allocated == REGS_FIXED);        assert (regs_allocated == REG_FIXED);
528        /* This function may not be called with REGS_FIXED and nregs too big.  */        /* This function may not be called with REG_FIXED and nregs too big.  */
529        assert (regs->num_regs >= nregs);        assert (regs->rm_num_regs >= nregs);
530        rval = REGS_FIXED;        rval = REG_FIXED;
531      }      }
532    
533    /* Copy the regs.  */    /* Copy the regs.  */
534    for (i = 0; i < nregs; ++i)    for (i = 0; i < nregs; ++i)
535      {      {
536        regs->start[i] = pmatch[i].rm_so;        regs->rm_start[i] = pmatch[i].rm_so;
537        regs->end[i] = pmatch[i].rm_eo;        regs->rm_end[i] = pmatch[i].rm_eo;
538      }      }
539    for ( ; i < regs->num_regs; ++i)    for ( ; i < regs->rm_num_regs; ++i)
540      regs->start[i] = regs->end[i] = -1;      regs->rm_start[i] = regs->rm_end[i] = -1;
541    
542    return rval;    return rval;
543  }  }
# Line 553  re_copy_regs (regs, pmatch, nregs, regs_ Line 556  re_copy_regs (regs, pmatch, nregs, regs_
556     freeing the old data.  */     freeing the old data.  */
557    
558  void  void
559  re_set_registers (bufp, regs, num_regs, starts, ends)  re_set_registers (struct re_pattern_buffer *bufp, struct re_registers *regs,
560      struct re_pattern_buffer *bufp;                    __re_size_t num_regs, regoff_t *starts, regoff_t *ends)
     struct re_registers *regs;  
     unsigned num_regs;  
     regoff_t *starts, *ends;  
561  {  {
562    if (num_regs)    if (num_regs)
563      {      {
564        bufp->regs_allocated = REGS_REALLOCATE;        bufp->re_regs_allocated = REG_REALLOCATE;
565        regs->num_regs = num_regs;        regs->rm_num_regs = num_regs;
566        regs->start = starts;        regs->rm_start = starts;
567        regs->end = ends;        regs->rm_end = ends;
568      }      }
569    else    else
570      {      {
571        bufp->regs_allocated = REGS_UNALLOCATED;        bufp->re_regs_allocated = REG_UNALLOCATED;
572        regs->num_regs = 0;        regs->rm_num_regs = 0;
573        regs->start = regs->end = (regoff_t *) 0;        regs->rm_start = regs->rm_end = NULL;
574      }      }
575  }  }
576  #ifdef _LIBC  #ifdef _LIBC
# Line 585  int Line 585  int
585  # ifdef _LIBC  # ifdef _LIBC
586  weak_function  weak_function
587  # endif  # endif
588  re_exec (s)  re_exec (const char *s)
      const char *s;  
589  {  {
590    return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);    return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
591  }  }
# Line 596  re_exec (s) Line 595  re_exec (s)
595    
596  /* Searches for a compiled pattern PREG in the string STRING, whose  /* Searches for a compiled pattern PREG in the string STRING, whose
597     length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same     length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
598     mingings with regexec.  START, and RANGE have the same meanings     meaning as with regexec.  LAST_START is START + RANGE, where
599     with re_search.     START and RANGE have the same meaning as with re_search.
600     Return REG_NOERROR if we find a match, and REG_NOMATCH if not,     Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
601     otherwise return the error code.     otherwise return the error code.
602     Note: We assume front end functions already check ranges.     Note: We assume front end functions already check ranges.
603     (START + RANGE >= 0 && START + RANGE <= LENGTH)  */     (0 <= LAST_START && LAST_START <= LENGTH)  */
604    
605  static reg_errcode_t  static reg_errcode_t
606  re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,  internal_function
607                      eflags)  re_search_internal (const regex_t *preg,
608      const regex_t *preg;                      const char *string, Idx length,
609      const char *string;                      Idx start, Idx last_start, Idx stop,
610      int length, start, range, stop, eflags;                      size_t nmatch, regmatch_t pmatch[],
611      size_t nmatch;                      int eflags)
     regmatch_t pmatch[];  
612  {  {
613    reg_errcode_t err;    reg_errcode_t err;
614    re_dfa_t *dfa = (re_dfa_t *)preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
615    int left_lim, right_lim, incr;    Idx left_lim, right_lim;
616    int fl_longest_match, match_first, match_kind, match_last = -1;    int incr;
617    int extra_nmatch;    bool fl_longest_match;
618    int sb, ch;    int match_kind;
619      Idx match_first, match_last = REG_MISSING;
620      Idx extra_nmatch;
621      bool sb;
622      int ch;
623  #if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)  #if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
624    re_match_context_t mctx = { .dfa = dfa };    re_match_context_t mctx = { .dfa = dfa };
625  #else  #else
626    re_match_context_t mctx;    re_match_context_t mctx;
627  #endif  #endif
628    char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate    char *fastmap = ((preg->re_fastmap != NULL && preg->re_fastmap_accurate
629                     && range && !preg->can_be_null) ? preg->fastmap : NULL;                      && start != last_start && !preg->re_can_be_null)
630    unsigned RE_TRANSLATE_TYPE t = (unsigned RE_TRANSLATE_TYPE) preg->translate;                     ? preg->re_fastmap : NULL);
631      unsigned REG_TRANSLATE_TYPE t =
632        (unsigned REG_TRANSLATE_TYPE) preg->re_translate;
633    
634  #if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))  #if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
635    memset (&mctx, '\0', sizeof (re_match_context_t));    memset (&mctx, '\0', sizeof (re_match_context_t));
# Line 636  re_search_internal (preg, string, length Line 640  re_search_internal (preg, string, length
640    nmatch -= extra_nmatch;    nmatch -= extra_nmatch;
641    
642    /* Check if the DFA haven't been compiled.  */    /* Check if the DFA haven't been compiled.  */
643    if (BE (preg->used == 0 || dfa->init_state == NULL    if (BE (preg->re_used == 0 || dfa->init_state == NULL
644            || dfa->init_state_word == NULL || dfa->init_state_nl == NULL            || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
645            || dfa->init_state_begbuf == NULL, 0))            || dfa->init_state_begbuf == NULL, 0))
646      return REG_NOMATCH;      return REG_NOMATCH;
647    
648  #ifdef DEBUG  #ifdef DEBUG
649    /* We assume front-end functions already check them.  */    /* We assume front-end functions already check them.  */
650    assert (start + range >= 0 && start + range <= length);    assert (0 <= last_start && last_start <= length);
651  #endif  #endif
652    
653    /* If initial states with non-begbuf contexts have no elements,    /* If initial states with non-begbuf contexts have no elements,
654       the regex must be anchored.  If preg->newline_anchor is set,       the regex must be anchored.  If preg->re_newline_anchor is set,
655       we'll never use init_state_nl, so do not check it.  */       we'll never use init_state_nl, so do not check it.  */
656    if (dfa->init_state->nodes.nelem == 0    if (dfa->init_state->nodes.nelem == 0
657        && dfa->init_state_word->nodes.nelem == 0        && dfa->init_state_word->nodes.nelem == 0
658        && (dfa->init_state_nl->nodes.nelem == 0        && (dfa->init_state_nl->nodes.nelem == 0
659            || !preg->newline_anchor))            || !preg->re_newline_anchor))
660      {      {
661        if (start != 0 && start + range != 0)        if (start != 0 && last_start != 0)
662          return REG_NOMATCH;          return REG_NOMATCH;
663        start = range = 0;        start = last_start = 0;
664      }      }
665    
666    /* We must check the longest matching, if nmatch > 0.  */    /* We must check the longest matching, if nmatch > 0.  */
667    fl_longest_match = (nmatch != 0 || dfa->nbackref);    fl_longest_match = (nmatch != 0 || dfa->nbackref);
668    
669    err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,    err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
670                              preg->translate, preg->syntax & RE_ICASE, dfa);                              preg->re_translate,
671                                preg->re_syntax & REG_IGNORE_CASE, dfa);
672    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
673      goto free_return;      goto free_return;
674    mctx.input.stop = stop;    mctx.input.stop = stop;
675    mctx.input.raw_stop = stop;    mctx.input.raw_stop = stop;
676    mctx.input.newline_anchor = preg->newline_anchor;    mctx.input.newline_anchor = preg->re_newline_anchor;
677    
678    err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);    err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
679    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
# Line 680  re_search_internal (preg, string, length Line 685  re_search_internal (preg, string, length
685       multi character collating element.  */       multi character collating element.  */
686    if (nmatch > 1 || dfa->has_mb_node)    if (nmatch > 1 || dfa->has_mb_node)
687      {      {
688        mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);        mctx.state_log = re_xmalloc (re_dfastate_t *, mctx.input.bufs_len + 1);
689        if (BE (mctx.state_log == NULL, 0))        if (BE (mctx.state_log == NULL, 0))
690          {          {
691            err = REG_ESPACE;            err = REG_ESPACE;
# Line 695  re_search_internal (preg, string, length Line 700  re_search_internal (preg, string, length
700                             : CONTEXT_NEWLINE | CONTEXT_BEGBUF;                             : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
701    
702    /* Check incrementally whether of not the input string match.  */    /* Check incrementally whether of not the input string match.  */
703    incr = (range < 0) ? -1 : 1;    incr = (last_start < start) ? -1 : 1;
704    left_lim = (range < 0) ? start + range : start;    left_lim = (last_start < start) ? last_start : start;
705    right_lim = (range < 0) ? start : start + range;    right_lim = (last_start < start) ? start : last_start;
706    sb = dfa->mb_cur_max == 1;    sb = dfa->mb_cur_max == 1;
707    match_kind =    match_kind =
708      (fastmap      (fastmap
709       ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)       ? ((sb || !(preg->re_syntax & REG_IGNORE_CASE || t) ? 4 : 0)
710          | (range >= 0 ? 2 : 0)          | (start <= last_start ? 2 : 0)
711          | (t != NULL ? 1 : 0))          | (t != NULL ? 1 : 0))
712       : 8);       : 8);
713    
# Line 769  re_search_internal (preg, string, length Line 774  re_search_internal (preg, string, length
774              {              {
775                /* If MATCH_FIRST is out of the valid range, reconstruct the                /* If MATCH_FIRST is out of the valid range, reconstruct the
776                   buffers.  */                   buffers.  */
777                unsigned int offset = match_first - mctx.input.raw_mbs_idx;                __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
778                if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0))                if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0))
779                  {                  {
780                    err = re_string_reconstruct (&mctx.input, match_first,                    err = re_string_reconstruct (&mctx.input, match_first,
781                                                 eflags);                                                 eflags);
# Line 812  re_search_internal (preg, string, length Line 817  re_search_internal (preg, string, length
817        /* We assume that the matching starts from 0.  */        /* We assume that the matching starts from 0.  */
818        mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;        mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
819        match_last = check_matching (&mctx, fl_longest_match,        match_last = check_matching (&mctx, fl_longest_match,
820                                     range >= 0 ? &match_first : NULL);                                     start <= last_start ? &match_first : NULL);
821        if (match_last != -1)        if (match_last != REG_MISSING)
822          {          {
823            if (BE (match_last == -2, 0))            if (BE (match_last == REG_ERROR, 0))
824              {              {
825                err = REG_ESPACE;                err = REG_ESPACE;
826                goto free_return;                goto free_return;
# Line 823  re_search_internal (preg, string, length Line 828  re_search_internal (preg, string, length
828            else            else
829              {              {
830                mctx.match_last = match_last;                mctx.match_last = match_last;
831                if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)                if ((!preg->re_no_sub && nmatch > 1) || dfa->nbackref)
832                  {                  {
833                    re_dfastate_t *pstate = mctx.state_log[match_last];                    re_dfastate_t *pstate = mctx.state_log[match_last];
834                    mctx.last_node = check_halt_state_context (&mctx, pstate,                    mctx.last_node = check_halt_state_context (&mctx, pstate,
835                                                               match_last);                                                               match_last);
836                  }                  }
837                if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)                if ((!preg->re_no_sub && nmatch > 1 && dfa->has_plural_match)
838                    || dfa->nbackref)                    || dfa->nbackref)
839                  {                  {
840                    err = prune_impossible_nodes (&mctx);                    err = prune_impossible_nodes (&mctx);
# Line 837  re_search_internal (preg, string, length Line 842  re_search_internal (preg, string, length
842                      break;                      break;
843                    if (BE (err != REG_NOMATCH, 0))                    if (BE (err != REG_NOMATCH, 0))
844                      goto free_return;                      goto free_return;
845                    match_last = -1;                    match_last = REG_MISSING;
846                  }                  }
847                else                else
848                  break; /* We found a match.  */                  break; /* We found a match.  */
# Line 848  re_search_internal (preg, string, length Line 853  re_search_internal (preg, string, length
853      }      }
854    
855  #ifdef DEBUG  #ifdef DEBUG
856    assert (match_last != -1);    assert (match_last != REG_MISSING);
857    assert (err == REG_NOERROR);    assert (err == REG_NOERROR);
858  #endif  #endif
859    
860    /* Set pmatch[] if we need.  */    /* Set pmatch[] if we need.  */
861    if (nmatch > 0)    if (nmatch > 0)
862      {      {
863        int reg_idx;        Idx reg_idx;
864    
865        /* Initialize registers.  */        /* Initialize registers.  */
866        for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)        for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
# Line 864  re_search_internal (preg, string, length Line 869  re_search_internal (preg, string, length
869        /* Set the points where matching start/end.  */        /* Set the points where matching start/end.  */
870        pmatch[0].rm_so = 0;        pmatch[0].rm_so = 0;
871        pmatch[0].rm_eo = mctx.match_last;        pmatch[0].rm_eo = mctx.match_last;
872          /* FIXME: This function should fail if mctx.match_last exceeds
873             the maximum possible regoff_t value.  We need a new error
874             code REG_OVERFLOW.  */
875    
876        if (!preg->no_sub && nmatch > 1)        if (!preg->re_no_sub && nmatch > 1)
877          {          {
878            err = set_regs (preg, &mctx, nmatch, pmatch,            err = set_regs (preg, &mctx, nmatch, pmatch,
879                            dfa->has_plural_match && dfa->nbackref > 0);                            dfa->has_plural_match && dfa->nbackref > 0);
# Line 882  re_search_internal (preg, string, length Line 890  re_search_internal (preg, string, length
890  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
891              if (BE (mctx.input.offsets_needed != 0, 0))              if (BE (mctx.input.offsets_needed != 0, 0))
892                {                {
893                  if (pmatch[reg_idx].rm_so == mctx.input.valid_len)                  pmatch[reg_idx].rm_so =
894                    pmatch[reg_idx].rm_so += mctx.input.valid_raw_len - mctx.input.valid_len;                    (pmatch[reg_idx].rm_so == mctx.input.valid_len
895                  else                     ? mctx.input.valid_raw_len
896                    pmatch[reg_idx].rm_so = mctx.input.offsets[pmatch[reg_idx].rm_so];                     : mctx.input.offsets[pmatch[reg_idx].rm_so]);
897                  if (pmatch[reg_idx].rm_eo == mctx.input.valid_len)                  pmatch[reg_idx].rm_eo =
898                    pmatch[reg_idx].rm_eo += mctx.input.valid_raw_len - mctx.input.valid_len;                    (pmatch[reg_idx].rm_eo == mctx.input.valid_len
899                  else                     ? mctx.input.valid_raw_len
900                    pmatch[reg_idx].rm_eo = mctx.input.offsets[pmatch[reg_idx].rm_eo];                     : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
901                }                }
902  #else  #else
903              assert (mctx.input.offsets_needed == 0);              assert (mctx.input.offsets_needed == 0);
# Line 923  re_search_internal (preg, string, length Line 931  re_search_internal (preg, string, length
931  }  }
932    
933  static reg_errcode_t  static reg_errcode_t
934  prune_impossible_nodes (mctx)  internal_function
935       re_match_context_t *mctx;  prune_impossible_nodes (re_match_context_t *mctx)
936  {  {
937    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
938    int halt_node, match_last;    Idx halt_node, match_last;
939    reg_errcode_t ret;    reg_errcode_t ret;
940    re_dfastate_t **sifted_states;    re_dfastate_t **sifted_states;
941    re_dfastate_t **lim_states = NULL;    re_dfastate_t **lim_states = NULL;
# Line 937  prune_impossible_nodes (mctx) Line 945  prune_impossible_nodes (mctx)
945  #endif  #endif
946    match_last = mctx->match_last;    match_last = mctx->match_last;
947    halt_node = mctx->last_node;    halt_node = mctx->last_node;
948    sifted_states = re_malloc (re_dfastate_t *, match_last + 1);    sifted_states = re_xmalloc (re_dfastate_t *, match_last + 1);
949    if (BE (sifted_states == NULL, 0))    if (BE (sifted_states == NULL, 0))
950      {      {
951        ret = REG_ESPACE;        ret = REG_ESPACE;
# Line 945  prune_impossible_nodes (mctx) Line 953  prune_impossible_nodes (mctx)
953      }      }
954    if (dfa->nbackref)    if (dfa->nbackref)
955      {      {
956        lim_states = re_malloc (re_dfastate_t *, match_last + 1);        lim_states = re_xmalloc (re_dfastate_t *, match_last + 1);
957        if (BE (lim_states == NULL, 0))        if (BE (lim_states == NULL, 0))
958          {          {
959            ret = REG_ESPACE;            ret = REG_ESPACE;
# Line 966  prune_impossible_nodes (mctx) Line 974  prune_impossible_nodes (mctx)
974            do            do
975              {              {
976                --match_last;                --match_last;
977                if (match_last < 0)                if (! REG_VALID_INDEX (match_last))
978                  {                  {
979                    ret = REG_NOMATCH;                    ret = REG_NOMATCH;
980                    goto free_return;                    goto free_return;
# Line 1009  prune_impossible_nodes (mctx) Line 1017  prune_impossible_nodes (mctx)
1017     since initial states may have constraints like "\<", "^", etc..  */     since initial states may have constraints like "\<", "^", etc..  */
1018    
1019  static inline re_dfastate_t *  static inline re_dfastate_t *
1020  acquire_init_state_context (err, mctx, idx)  __attribute ((always_inline)) internal_function
1021       reg_errcode_t *err;  acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
1022       const re_match_context_t *mctx;                              Idx idx)
      int idx;  
1023  {  {
1024    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1025    if (dfa->init_state->has_constraint)    if (dfa->init_state->has_constraint)
# Line 1043  acquire_init_state_context (err, mctx, i Line 1050  acquire_init_state_context (err, mctx, i
1050  }  }
1051    
1052  /* Check whether the regular expression match input string INPUT or not,  /* Check whether the regular expression match input string INPUT or not,
1053     and return the index where the matching end, return -1 if not match,     and return the index where the matching end.  Return REG_MISSING if
1054     or return -2 in case of an error.     there is no match, and return REG_ERROR in case of an error.
1055     FL_LONGEST_MATCH means we want the POSIX longest matching.     FL_LONGEST_MATCH means we want the POSIX longest matching.
1056     If P_MATCH_FIRST is not NULL, and the match fails, it is set to the     If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
1057     next place where we may want to try matching.     next place where we may want to try matching.
1058     Note that the matcher assume that the maching starts from the current     Note that the matcher assume that the maching starts from the current
1059     index of the buffer.  */     index of the buffer.  */
1060    
1061  static int  static Idx
1062  check_matching (mctx, fl_longest_match, p_match_first)  internal_function
1063      re_match_context_t *mctx;  check_matching (re_match_context_t *mctx, bool fl_longest_match,
1064      int fl_longest_match;                  Idx *p_match_first)
     int *p_match_first;  
1065  {  {
1066    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1067    reg_errcode_t err;    reg_errcode_t err;
1068    int match = 0;    Idx match = 0;
1069    int match_last = -1;    Idx match_last = REG_MISSING;
1070    int cur_str_idx = re_string_cur_idx (&mctx->input);    Idx cur_str_idx = re_string_cur_idx (&mctx->input);
1071    re_dfastate_t *cur_state;    re_dfastate_t *cur_state;
1072    int at_init_state = p_match_first != NULL;    bool at_init_state = p_match_first != NULL;
1073    int next_start_idx = cur_str_idx;    Idx next_start_idx = cur_str_idx;
1074    
1075    err = REG_NOERROR;    err = REG_NOERROR;
1076    cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);    cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
# Line 1072  check_matching (mctx, fl_longest_match, Line 1078  check_matching (mctx, fl_longest_match,
1078    if (BE (cur_state == NULL, 0))    if (BE (cur_state == NULL, 0))
1079      {      {
1080        assert (err == REG_ESPACE);        assert (err == REG_ESPACE);
1081        return -2;        return REG_ERROR;
1082      }      }
1083    
1084    if (mctx->state_log != NULL)    if (mctx->state_log != NULL)
# Line 1083  check_matching (mctx, fl_longest_match, Line 1089  check_matching (mctx, fl_longest_match,
1089           later.  E.g. Processing back references.  */           later.  E.g. Processing back references.  */
1090        if (BE (dfa->nbackref, 0))        if (BE (dfa->nbackref, 0))
1091          {          {
1092            at_init_state = 0;            at_init_state = false;
1093            err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);            err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
1094            if (BE (err != REG_NOERROR, 0))            if (BE (err != REG_NOERROR, 0))
1095              return err;              return err;
# Line 1116  check_matching (mctx, fl_longest_match, Line 1122  check_matching (mctx, fl_longest_match,
1122    while (!re_string_eoi (&mctx->input))    while (!re_string_eoi (&mctx->input))
1123      {      {
1124        re_dfastate_t *old_state = cur_state;        re_dfastate_t *old_state = cur_state;
1125        int next_char_idx = re_string_cur_idx (&mctx->input) + 1;        Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
1126    
1127        if (BE (next_char_idx >= mctx->input.bufs_len, 0)        if (BE (next_char_idx >= mctx->input.bufs_len, 0)
1128            || (BE (next_char_idx >= mctx->input.valid_len, 0)            || (BE (next_char_idx >= mctx->input.valid_len, 0)
# Line 1126  check_matching (mctx, fl_longest_match, Line 1132  check_matching (mctx, fl_longest_match,
1132            if (BE (err != REG_NOERROR, 0))            if (BE (err != REG_NOERROR, 0))
1133              {              {
1134                assert (err == REG_ESPACE);                assert (err == REG_ESPACE);
1135                return -2;                return REG_ERROR;
1136              }              }
1137          }          }
1138    
# Line 1140  check_matching (mctx, fl_longest_match, Line 1146  check_matching (mctx, fl_longest_match,
1146               state using the state log, if available and if we have not               state using the state log, if available and if we have not
1147               already found a valid (even if not the longest) match.  */               already found a valid (even if not the longest) match.  */
1148            if (BE (err != REG_NOERROR, 0))            if (BE (err != REG_NOERROR, 0))
1149              return -2;              return REG_ERROR;
1150    
1151            if (mctx->state_log == NULL            if (mctx->state_log == NULL
1152                || (match && !fl_longest_match)                || (match && !fl_longest_match)
# Line 1153  check_matching (mctx, fl_longest_match, Line 1159  check_matching (mctx, fl_longest_match,
1159            if (old_state == cur_state)            if (old_state == cur_state)
1160              next_start_idx = next_char_idx;              next_start_idx = next_char_idx;
1161            else            else
1162              at_init_state = 0;              at_init_state = false;
1163          }          }
1164    
1165        if (cur_state->halt)        if (cur_state->halt)
# Line 1184  check_matching (mctx, fl_longest_match, Line 1190  check_matching (mctx, fl_longest_match,
1190    
1191  /* Check NODE match the current context.  */  /* Check NODE match the current context.  */
1192    
1193  static int check_halt_node_context (dfa, node, context)  static bool
1194      const re_dfa_t *dfa;  internal_function
1195      int node;  check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context)
     unsigned int context;  
1196  {  {
1197    re_token_type_t type = dfa->nodes[node].type;    re_token_type_t type = dfa->nodes[node].type;
1198    unsigned int constraint = dfa->nodes[node].constraint;    unsigned int constraint = dfa->nodes[node].constraint;
1199    if (type != END_OF_RE)    if (type != END_OF_RE)
1200      return 0;      return false;
1201    if (!constraint)    if (!constraint)
1202      return 1;      return true;
1203    if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))    if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
1204      return 0;      return false;
1205    return 1;    return true;
1206  }  }
1207    
1208  /* Check the halt state STATE match the current context.  /* Check the halt state STATE match the current context.
1209     Return 0 if not match, if the node, STATE has, is a halt node and     Return 0 if not match, if the node, STATE has, is a halt node and
1210     match the context, return the node.  */     match the context, return the node.  */
1211    
1212  static int  static Idx
1213  check_halt_state_context (mctx, state, idx)  internal_function
1214      const re_match_context_t *mctx;  check_halt_state_context (const re_match_context_t *mctx,
1215      const re_dfastate_t *state;                            const re_dfastate_t *state, Idx idx)
     int idx;  
1216  {  {
1217    int i;    Idx i;
1218    unsigned int context;    unsigned int context;
1219  #ifdef DEBUG  #ifdef DEBUG
1220    assert (state->halt);    assert (state->halt);
# Line 1224  check_halt_state_context (mctx, state, i Line 1228  check_halt_state_context (mctx, state, i
1228    
1229  /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA  /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
1230     corresponding to the DFA).     corresponding to the DFA).
1231     Return the destination node, and update EPS_VIA_NODES, return -1 in case     Return the destination node, and update EPS_VIA_NODES;
1232     of errors.  */     return REG_MISSING in case of errors.  */
1233    
1234  static int  static Idx
1235  proceed_next_node (mctx, nregs, regs, pidx, node, eps_via_nodes, fs)  internal_function
1236      const re_match_context_t *mctx;  proceed_next_node (const re_match_context_t *mctx,
1237      regmatch_t *regs;                     Idx nregs, regmatch_t *regs, Idx *pidx, Idx node,
1238      int nregs, *pidx, node;                     re_node_set *eps_via_nodes, struct re_fail_stack_t *fs)
     re_node_set *eps_via_nodes;  
     struct re_fail_stack_t *fs;  
1239  {  {
1240    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1241    int i, err, dest_node;    Idx i;
1242    dest_node = -1;    bool ok;
1243    if (IS_EPSILON_NODE (dfa->nodes[node].type))    if (IS_EPSILON_NODE (dfa->nodes[node].type))
1244      {      {
1245        re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;        re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
1246        re_node_set *edests = &dfa->edests[node];        re_node_set *edests = &dfa->edests[node];
1247        int dest_node;        Idx dest_node;
1248        err = re_node_set_insert (eps_via_nodes, node);        ok = re_node_set_insert (eps_via_nodes, node);
1249        if (BE (err < 0, 0))        if (BE (! ok, 0))
1250          return -2;          return REG_ERROR;
1251        /* Pick up a valid destination, or return -1 if none is found.  */        /* Pick up a valid destination, or return REG_MISSING if none
1252        for (dest_node = -1, i = 0; i < edests->nelem; ++i)           is found.  */
1253          for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i)
1254          {          {
1255            int candidate = edests->elems[i];            Idx candidate = edests->elems[i];
1256            if (!re_node_set_contains (cur_nodes, candidate))            if (!re_node_set_contains (cur_nodes, candidate))
1257              continue;              continue;
1258            if (dest_node == -1)            if (dest_node == REG_MISSING)
1259              dest_node = candidate;              dest_node = candidate;
1260    
1261            else            else
# Line 1266  proceed_next_node (mctx, nregs, regs, pi Line 1269  proceed_next_node (mctx, nregs, regs, pi
1269                else if (fs != NULL                else if (fs != NULL
1270                         && push_fail_stack (fs, *pidx, candidate, nregs, regs,                         && push_fail_stack (fs, *pidx, candidate, nregs, regs,
1271                                             eps_via_nodes))                                             eps_via_nodes))
1272                  return -2;                  return REG_ERROR;
1273    
1274                /* We know we are going to exit.  */                /* We know we are going to exit.  */
1275                break;                break;
# Line 1276  proceed_next_node (mctx, nregs, regs, pi Line 1279  proceed_next_node (mctx, nregs, regs, pi
1279      }      }
1280    else    else
1281      {      {
1282        int naccepted = 0;        Idx naccepted = 0;
1283        re_token_type_t type = dfa->nodes[node].type;        re_token_type_t type = dfa->nodes[node].type;
1284    
1285  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
# Line 1286  proceed_next_node (mctx, nregs, regs, pi Line 1289  proceed_next_node (mctx, nregs, regs, pi
1289  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
1290        if (type == OP_BACK_REF)        if (type == OP_BACK_REF)
1291          {          {
1292            int subexp_idx = dfa->nodes[node].opr.idx + 1;            Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
1293            naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;            naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
1294            if (fs != NULL)            if (fs != NULL)
1295              {              {
1296                if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)                if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
1297                  return -1;                  return REG_MISSING;
1298                else if (naccepted)                else if (naccepted)
1299                  {                  {
1300                    char *buf = (char *) re_string_get_buffer (&mctx->input);                    char *buf = (char *) re_string_get_buffer (&mctx->input);
1301                    if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,                    if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
1302                                naccepted) != 0)                                naccepted) != 0)
1303                      return -1;                      return REG_MISSING;
1304                  }                  }
1305              }              }
1306    
1307            if (naccepted == 0)            if (naccepted == 0)
1308              {              {
1309                err = re_node_set_insert (eps_via_nodes, node);                Idx dest_node;
1310                if (BE (err < 0, 0))                ok = re_node_set_insert (eps_via_nodes, node);
1311                  return -2;                if (BE (! ok, 0))
1312                    return REG_ERROR;
1313                dest_node = dfa->edests[node].elems[0];                dest_node = dfa->edests[node].elems[0];
1314                if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,                if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
1315                                          dest_node))                                          dest_node))
# Line 1316  proceed_next_node (mctx, nregs, regs, pi Line 1320  proceed_next_node (mctx, nregs, regs, pi
1320        if (naccepted != 0        if (naccepted != 0
1321            || check_node_accept (mctx, dfa->nodes + node, *pidx))            || check_node_accept (mctx, dfa->nodes + node, *pidx))
1322          {          {
1323            dest_node = dfa->nexts[node];            Idx dest_node = dfa->nexts[node];
1324            *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;            *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
1325            if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL            if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
1326                       || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,                       || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
1327                                                 dest_node)))                                                 dest_node)))
1328              return -1;              return REG_MISSING;
1329            re_node_set_empty (eps_via_nodes);            re_node_set_empty (eps_via_nodes);
1330            return dest_node;            return dest_node;
1331          }          }
1332      }      }
1333    return -1;    return REG_MISSING;
1334  }  }
1335    
1336  static reg_errcode_t  static reg_errcode_t
1337  push_fail_stack (fs, str_idx, dest_node, nregs, regs, eps_via_nodes)  internal_function
1338       struct re_fail_stack_t *fs;  push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
1339       int str_idx, dest_node, nregs;                   Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
      regmatch_t *regs;  
      re_node_set *eps_via_nodes;  
1340  {  {
1341    reg_errcode_t err;    reg_errcode_t err;
1342    int num = fs->num++;    Idx num = fs->num++;
1343    if (fs->num == fs->alloc)    if (fs->num == fs->alloc)
1344      {      {
1345        struct re_fail_stack_ent_t *new_array;        struct re_fail_stack_ent_t *new_array =
1346        new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)          re_x2realloc (fs->stack, struct re_fail_stack_ent_t, &fs->alloc);
                                        * fs->alloc * 2));  
1347        if (new_array == NULL)        if (new_array == NULL)
1348          return REG_ESPACE;          return REG_ESPACE;
       fs->alloc *= 2;  
1349        fs->stack = new_array;        fs->stack = new_array;
1350      }      }
1351    fs->stack[num].idx = str_idx;    fs->stack[num].idx = str_idx;
1352    fs->stack[num].node = dest_node;    fs->stack[num].node = dest_node;
1353    fs->stack[num].regs = re_malloc (regmatch_t, nregs);    fs->stack[num].regs = re_xmalloc (regmatch_t, nregs);
1354    if (fs->stack[num].regs == NULL)    if (fs->stack[num].regs == NULL)
1355      return REG_ESPACE;      return REG_ESPACE;
1356    memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);    memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
# Line 1358  push_fail_stack (fs, str_idx, dest_node, Line 1358  push_fail_stack (fs, str_idx, dest_node,
1358    return err;    return err;
1359  }  }
1360    
1361  static int  static Idx
1362  pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)  internal_function
1363       struct re_fail_stack_t *fs;  pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx,
1364       int *pidx, nregs;                  Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
      regmatch_t *regs;  
      re_node_set *eps_via_nodes;  
1365  {  {
1366    int num = --fs->num;    Idx num = --fs->num;
1367    assert (num >= 0);    assert (REG_VALID_INDEX (num));
1368    *pidx = fs->stack[num].idx;    *pidx = fs->stack[num].idx;
1369    memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);    memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
1370    re_node_set_free (eps_via_nodes);    re_node_set_free (eps_via_nodes);
# Line 1381  pop_fail_stack (fs, pidx, nregs, regs, e Line 1379  pop_fail_stack (fs, pidx, nregs, regs, e
1379     pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */     pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
1380    
1381  static reg_errcode_t  static reg_errcode_t
1382  set_regs (preg, mctx, nmatch, pmatch, fl_backtrack)  internal_function
1383       const regex_t *preg;  set_regs (const regex_t *preg, const re_match_context_t *mctx,
1384       const re_match_context_t *mctx;            size_t nmatch, regmatch_t *pmatch, bool fl_backtrack)
      size_t nmatch;  
      regmatch_t *pmatch;  
      int fl_backtrack;  
1385  {  {
1386    re_dfa_t *dfa = (re_dfa_t *) preg->buffer;    re_dfa_t *dfa = (re_dfa_t *) preg->re_buffer;
1387    int idx, cur_node;    Idx idx, cur_node;
1388    re_node_set eps_via_nodes;    re_node_set eps_via_nodes;
1389    struct re_fail_stack_t *fs;    struct re_fail_stack_t *fs;
1390    struct re_fail_stack_t fs_body = { 0, 2, NULL };    struct re_fail_stack_t fs_body = { 0, 2, NULL };
1391    regmatch_t *prev_idx_match;    regmatch_t *prev_idx_match;
1392      bool prev_idx_match_malloced = false;
1393    
1394  #ifdef DEBUG  #ifdef DEBUG
1395    assert (nmatch > 1);    assert (nmatch > 1);
# Line 1402  set_regs (preg, mctx, nmatch, pmatch, fl Line 1398  set_regs (preg, mctx, nmatch, pmatch, fl
1398    if (fl_backtrack)    if (fl_backtrack)
1399      {      {
1400        fs = &fs_body;        fs = &fs_body;
1401        fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);        fs->stack = re_xmalloc (struct re_fail_stack_ent_t, fs->alloc);
1402        if (fs->stack == NULL)        if (fs->stack == NULL)
1403          return REG_ESPACE;          return REG_ESPACE;
1404      }      }
# Line 1412  set_regs (preg, mctx, nmatch, pmatch, fl Line 1408  set_regs (preg, mctx, nmatch, pmatch, fl
1408    cur_node = dfa->init_node;    cur_node = dfa->init_node;
1409    re_node_set_init_empty (&eps_via_nodes);    re_node_set_init_empty (&eps_via_nodes);
1410    
1411    prev_idx_match = (regmatch_t *) alloca (sizeof (regmatch_t) * nmatch);    if (re_alloc_oversized (nmatch, sizeof (regmatch_t)))
1412        {
1413          free_fail_stack_return (fs);
1414          return REG_ESPACE;
1415        }
1416      if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
1417        prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
1418      else
1419        {
1420          prev_idx_match = re_malloc (regmatch_t, nmatch);
1421          if (prev_idx_match == NULL)
1422            {
1423              free_fail_stack_return (fs);
1424              return REG_ESPACE;
1425            }
1426          prev_idx_match_malloced = true;
1427        }
1428    memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);    memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
1429    
1430    for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)    for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
# Line 1421  set_regs (preg, mctx, nmatch, pmatch, fl Line 1433  set_regs (preg, mctx, nmatch, pmatch, fl
1433    
1434        if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)        if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
1435          {          {
1436            int reg_idx;            Idx reg_idx;
1437            if (fs)            if (fs)
1438              {              {
1439                for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)                for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
# Line 1430  set_regs (preg, mctx, nmatch, pmatch, fl Line 1442  set_regs (preg, mctx, nmatch, pmatch, fl
1442                if (reg_idx == nmatch)                if (reg_idx == nmatch)
1443                  {                  {
1444                    re_node_set_free (&eps_via_nodes);                    re_node_set_free (&eps_via_nodes);
1445                      if (prev_idx_match_malloced)
1446                        re_free (prev_idx_match);
1447                    return free_fail_stack_return (fs);                    return free_fail_stack_return (fs);
1448                  }                  }
1449                cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,                cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
# Line 1438  set_regs (preg, mctx, nmatch, pmatch, fl Line 1452  set_regs (preg, mctx, nmatch, pmatch, fl
1452            else            else
1453              {              {
1454                re_node_set_free (&eps_via_nodes);                re_node_set_free (&eps_via_nodes);
1455                  if (prev_idx_match_malloced)
1456                    re_free (prev_idx_match);
1457                return REG_NOERROR;                return REG_NOERROR;
1458              }              }
1459          }          }
# Line 1446  set_regs (preg, mctx, nmatch, pmatch, fl Line 1462  set_regs (preg, mctx, nmatch, pmatch, fl
1462        cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,        cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
1463                                      &eps_via_nodes, fs);                                      &eps_via_nodes, fs);
1464    
1465        if (BE (cur_node < 0, 0))        if (BE (! REG_VALID_INDEX (cur_node), 0))
1466          {          {
1467            if (BE (cur_node == -2, 0))            if (BE (cur_node == REG_ERROR, 0))
1468              {              {
1469                re_node_set_free (&eps_via_nodes);                re_node_set_free (&eps_via_nodes);
1470                  if (prev_idx_match_malloced)
1471                    re_free (prev_idx_match);
1472                free_fail_stack_return (fs);                free_fail_stack_return (fs);
1473                return REG_ESPACE;                return REG_ESPACE;
1474              }              }
# Line 1460  set_regs (preg, mctx, nmatch, pmatch, fl Line 1478  set_regs (preg, mctx, nmatch, pmatch, fl
1478            else            else
1479              {              {
1480                re_node_set_free (&eps_via_nodes);                re_node_set_free (&eps_via_nodes);
1481                  if (prev_idx_match_malloced)
1482                    re_free (prev_idx_match);
1483                return REG_NOMATCH;                return REG_NOMATCH;
1484              }              }
1485          }          }
1486      }      }
1487    re_node_set_free (&eps_via_nodes);    re_node_set_free (&eps_via_nodes);
1488      if (prev_idx_match_malloced)
1489        re_free (prev_idx_match);
1490    return free_fail_stack_return (fs);    return free_fail_stack_return (fs);
1491  }  }
1492    
1493  static reg_errcode_t  static reg_errcode_t
1494  free_fail_stack_return (fs)  internal_function
1495       struct re_fail_stack_t *fs;  free_fail_stack_return (struct re_fail_stack_t *fs)
1496  {  {
1497    if (fs)    if (fs)
1498      {      {
1499        int fs_idx;        Idx fs_idx;
1500        for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)        for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
1501          {          {
1502            re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);            re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
# Line 1486  free_fail_stack_return (fs) Line 1508  free_fail_stack_return (fs)
1508  }  }
1509    
1510  static void  static void
1511  update_regs (dfa, pmatch, prev_idx_match, cur_node, cur_idx, nmatch)  internal_function
1512       re_dfa_t *dfa;  update_regs (re_dfa_t *dfa, regmatch_t *pmatch, regmatch_t *prev_idx_match,
1513       regmatch_t *pmatch, *prev_idx_match;               Idx cur_node, Idx cur_idx, Idx nmatch)
      int cur_node, cur_idx, nmatch;  
1514  {  {
1515    int type = dfa->nodes[cur_node].type;    int type = dfa->nodes[cur_node].type;
1516    if (type == OP_OPEN_SUBEXP)    if (type == OP_OPEN_SUBEXP)
1517      {      {
1518        int reg_num = dfa->nodes[cur_node].opr.idx + 1;        Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
1519    
1520        /* We are at the first node of this sub expression.  */        /* We are at the first node of this sub expression.  */
1521        if (reg_num < nmatch)        if (reg_num < nmatch)
# Line 1505  update_regs (dfa, pmatch, prev_idx_match Line 1526  update_regs (dfa, pmatch, prev_idx_match
1526      }      }
1527    else if (type == OP_CLOSE_SUBEXP)    else if (type == OP_CLOSE_SUBEXP)
1528      {      {
1529        int reg_num = dfa->nodes[cur_node].opr.idx + 1;        Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
1530        if (reg_num < nmatch)        if (reg_num < nmatch)
1531          {          {
1532            /* We are at the last node of this sub expression.  */            /* We are at the last node of this sub expression.  */
# Line 1559  update_regs (dfa, pmatch, prev_idx_match Line 1580  update_regs (dfa, pmatch, prev_idx_match
1580    ((state) != NULL && re_node_set_contains (&(state)->nodes, node))    ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
1581    
1582  static reg_errcode_t  static reg_errcode_t
1583  sift_states_backward (mctx, sctx)  internal_function
1584       re_match_context_t *mctx;  sift_states_backward (re_match_context_t *mctx, re_sift_context_t *sctx)
      re_sift_context_t *sctx;  
1585  {  {
1586    reg_errcode_t err;    reg_errcode_t err;
1587    int null_cnt = 0;    int null_cnt = 0;
1588    int str_idx = sctx->last_str_idx;    Idx str_idx = sctx->last_str_idx;
1589    re_node_set cur_dest;    re_node_set cur_dest;
1590    
1591  #ifdef DEBUG  #ifdef DEBUG
# Line 1618  sift_states_backward (mctx, sctx) Line 1638  sift_states_backward (mctx, sctx)
1638  }  }
1639    
1640  static reg_errcode_t  static reg_errcode_t
1641  build_sifted_states (mctx, sctx, str_idx, cur_dest)  internal_function
1642       re_match_context_t *mctx;  build_sifted_states (re_match_context_t *mctx, re_sift_context_t *sctx,
1643       re_sift_context_t *sctx;                       Idx str_idx, re_node_set *cur_dest)
      int str_idx;  
      re_node_set *cur_dest;  
1644  {  {
1645    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1646    re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;    re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
1647    int i;    Idx i;
1648    
1649    /* Then build the next sifted state.    /* Then build the next sifted state.
1650       We build the next sifted state on `cur_dest', and update       We build the next sifted state on `cur_dest', and update
# Line 1637  build_sifted_states (mctx, sctx, str_idx Line 1655  build_sifted_states (mctx, sctx, str_idx
1655       (with the epsilon nodes pre-filtered out).  */       (with the epsilon nodes pre-filtered out).  */
1656    for (i = 0; i < cur_src->nelem; i++)    for (i = 0; i < cur_src->nelem; i++)
1657      {      {
1658        int prev_node = cur_src->elems[i];        Idx prev_node = cur_src->elems[i];
1659        int naccepted = 0;        int naccepted = 0;
1660        int ret;        bool ok;
1661    
1662  #ifdef DEBUG  #ifdef DEBUG
1663        re_token_type_t type = dfa->nodes[prev_node].type;        re_token_type_t type = dfa->nodes[prev_node].type;
# Line 1665  build_sifted_states (mctx, sctx, str_idx Line 1683  build_sifted_states (mctx, sctx, str_idx
1683    
1684        if (sctx->limits.nelem)        if (sctx->limits.nelem)
1685          {          {
1686            int to_idx = str_idx + naccepted;            Idx to_idx = str_idx + naccepted;
1687            if (check_dst_limits (mctx, &sctx->limits,            if (check_dst_limits (mctx, &sctx->limits,
1688                                  dfa->nexts[prev_node], to_idx,                                  dfa->nexts[prev_node], to_idx,
1689                                  prev_node, str_idx))                                  prev_node, str_idx))
1690              continue;              continue;
1691          }          }
1692        ret = re_node_set_insert (cur_dest, prev_node);        ok = re_node_set_insert (cur_dest, prev_node);
1693        if (BE (ret == -1, 0))        if (BE (! ok, 0))
1694          return REG_ESPACE;          return REG_ESPACE;
1695      }      }
1696    
# Line 1682  build_sifted_states (mctx, sctx, str_idx Line 1700  build_sifted_states (mctx, sctx, str_idx
1700  /* Helper functions.  */  /* Helper functions.  */
1701    
1702  static reg_errcode_t  static reg_errcode_t
1703  clean_state_log_if_needed (mctx, next_state_log_idx)  internal_function
1704      re_match_context_t *mctx;  clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
     int next_state_log_idx;  
1705  {  {
1706    int top = mctx->state_log_top;    Idx top = mctx->state_log_top;
1707    
1708    if (next_state_log_idx >= mctx->input.bufs_len    if (next_state_log_idx >= mctx->input.bufs_len
1709        || (next_state_log_idx >= mctx->input.valid_len        || (next_state_log_idx >= mctx->input.valid_len
# Line 1708  clean_state_log_if_needed (mctx, next_st Line 1725  clean_state_log_if_needed (mctx, next_st
1725  }  }
1726    
1727  static reg_errcode_t  static reg_errcode_t
1728  merge_state_array (dfa, dst, src, num)  internal_function
1729       re_dfa_t *dfa;  merge_state_array (re_dfa_t *dfa, re_dfastate_t **dst, re_dfastate_t **src,
1730       re_dfastate_t **dst;                     Idx num)
      re_dfastate_t **src;  
      int num;  
1731  {  {
1732    int st_idx;    Idx st_idx;
1733    reg_errcode_t err;    reg_errcode_t err;
1734    for (st_idx = 0; st_idx < num; ++st_idx)    for (st_idx = 0; st_idx < num; ++st_idx)
1735      {      {
# Line 1737  merge_state_array (dfa, dst, src, num) Line 1752  merge_state_array (dfa, dst, src, num)
1752  }  }
1753    
1754  static reg_errcode_t  static reg_errcode_t
1755  update_cur_sifted_state (mctx, sctx, str_idx, dest_nodes)  internal_function
1756       re_match_context_t *mctx;  update_cur_sifted_state (re_match_context_t *mctx, re_sift_context_t *sctx,
1757       re_sift_context_t *sctx;                           Idx str_idx, re_node_set *dest_nodes)
      int str_idx;  
      re_node_set *dest_nodes;  
1758  {  {
1759    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1760    reg_errcode_t err;    reg_errcode_t err;
# Line 1786  update_cur_sifted_state (mctx, sctx, str Line 1799  update_cur_sifted_state (mctx, sctx, str
1799  }  }
1800    
1801  static reg_errcode_t  static reg_errcode_t
1802  add_epsilon_src_nodes (dfa, dest_nodes, candidates)  internal_function
1803       re_dfa_t *dfa;  add_epsilon_src_nodes (re_dfa_t *dfa, re_node_set *dest_nodes,
1804       re_node_set *dest_nodes;                         const re_node_set *candidates)
      const re_node_set *candidates;  
1805  {  {
1806    reg_errcode_t err = REG_NOERROR;    reg_errcode_t err = REG_NOERROR;
1807    int i;    Idx i;
1808    
1809    re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);    re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
1810    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
# Line 1812  add_epsilon_src_nodes (dfa, dest_nodes, Line 1824  add_epsilon_src_nodes (dfa, dest_nodes,
1824  }  }
1825    
1826  static reg_errcode_t  static reg_errcode_t
1827  sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates)  internal_function
1828       re_dfa_t *dfa;  sub_epsilon_src_nodes (re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,
1829       int node;                         const re_node_set *candidates)
      re_node_set *dest_nodes;  
      const re_node_set *candidates;  
1830  {  {
1831      int ecl_idx;      Idx ecl_idx;
1832      reg_errcode_t err;      reg_errcode_t err;
1833      re_node_set *inv_eclosure = dfa->inveclosures + node;      re_node_set *inv_eclosure = dfa->inveclosures + node;
1834      re_node_set except_nodes;      re_node_set except_nodes;
1835      re_node_set_init_empty (&except_nodes);      re_node_set_init_empty (&except_nodes);
1836      for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)      for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
1837        {        {
1838          int cur_node = inv_eclosure->elems[ecl_idx];          Idx cur_node = inv_eclosure->elems[ecl_idx];
1839          if (cur_node == node)          if (cur_node == node)
1840            continue;            continue;
1841          if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))          if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
1842            {            {
1843              int edst1 = dfa->edests[cur_node].elems[0];              Idx edst1 = dfa->edests[cur_node].elems[0];
1844              int edst2 = ((dfa->edests[cur_node].nelem > 1)              Idx edst2 = ((dfa->edests[cur_node].nelem > 1)
1845                           ? dfa->edests[cur_node].elems[1] : -1);                           ? dfa->edests[cur_node].elems[1] : REG_MISSING);
1846              if ((!re_node_set_contains (inv_eclosure, edst1)              if ((!re_node_set_contains (inv_eclosure, edst1)
1847                   && re_node_set_contains (dest_nodes, edst1))                   && re_node_set_contains (dest_nodes, edst1))
1848                  || (edst2 > 0                  || (REG_VALID_NONZERO_INDEX (edst2)
1849                      && !re_node_set_contains (inv_eclosure, edst2)                      && !re_node_set_contains (inv_eclosure, edst2)
1850                      && re_node_set_contains (dest_nodes, edst2)))                      && re_node_set_contains (dest_nodes, edst2)))
1851                {                {
# Line 1851  sub_epsilon_src_nodes (dfa, node, dest_n Line 1861  sub_epsilon_src_nodes (dfa, node, dest_n
1861        }        }
1862      for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)      for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
1863        {        {
1864          int cur_node = inv_eclosure->elems[ecl_idx];          Idx cur_node = inv_eclosure->elems[ecl_idx];
1865          if (!re_node_set_contains (&except_nodes, cur_node))          if (!re_node_set_contains (&except_nodes, cur_node))
1866            {            {
1867              int idx = re_node_set_contains (dest_nodes, cur_node) - 1;              Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;
1868              re_node_set_remove_at (dest_nodes, idx);              re_node_set_remove_at (dest_nodes, idx);
1869            }            }
1870        }        }
# Line 1862  sub_epsilon_src_nodes (dfa, node, dest_n Line 1872  sub_epsilon_src_nodes (dfa, node, dest_n
1872      return REG_NOERROR;      return REG_NOERROR;
1873  }  }
1874    
1875  static int  static bool
1876  check_dst_limits (mctx, limits, dst_node, dst_idx, src_node, src_idx)  internal_function
1877       re_match_context_t *mctx;  check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,
1878       re_node_set *limits;                    Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)
      int dst_node, dst_idx, src_node, src_idx;  
1879  {  {
1880    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1881    int lim_idx, src_pos, dst_pos;    Idx lim_idx, src_pos, dst_pos;
1882    
1883    int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);    Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
1884    int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);    Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
1885    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
1886      {      {
1887        int subexp_idx;        Idx subexp_idx;
1888        struct re_backref_cache_entry *ent;        struct re_backref_cache_entry *ent;
1889        ent = mctx->bkref_ents + limits->elems[lim_idx];        ent = mctx->bkref_ents + limits->elems[lim_idx];
1890        subexp_idx = dfa->nodes[ent->node].opr.idx;        subexp_idx = dfa->nodes[ent->node].opr.idx;
# Line 1894  check_dst_limits (mctx, limits, dst_node Line 1903  check_dst_limits (mctx, limits, dst_node
1903        if (src_pos == dst_pos)        if (src_pos == dst_pos)
1904          continue; /* This is unrelated limitation.  */          continue; /* This is unrelated limitation.  */
1905        else        else
1906          return 1;          return true;
1907      }      }
1908    return 0;    return false;
1909  }  }
1910    
1911  static int  static int
1912  check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, from_node, bkref_idx)  internal_function
1913       re_match_context_t *mctx;  check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
1914       int boundaries, subexp_idx, from_node, bkref_idx;                               Idx subexp_idx, Idx from_node, Idx bkref_idx)
1915  {  {
1916    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
1917    re_node_set *eclosures = dfa->eclosures + from_node;    re_node_set *eclosures = dfa->eclosures + from_node;
1918    int node_idx;    Idx node_idx;
1919    
1920    /* Else, we are on the boundary: examine the nodes on the epsilon    /* Else, we are on the boundary: examine the nodes on the epsilon
1921       closure.  */       closure.  */
1922    for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)    for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
1923      {      {
1924        int node = eclosures->elems[node_idx];        Idx node = eclosures->elems[node_idx];
1925        switch (dfa->nodes[node].type)        switch (dfa->nodes[node].type)
1926          {          {
1927          case OP_BACK_REF:          case OP_BACK_REF:
1928            if (bkref_idx != -1)            if (bkref_idx != REG_MISSING)
1929              {              {
1930                struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;                struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
1931                do                do
1932                  {                  {
1933                    int dst, cpos;                    Idx dst;
1934                      int cpos;
1935    
1936                    if (ent->node != node)                    if (ent->node != node)
1937                      continue;                      continue;
1938    
1939                    if (subexp_idx <= 8 * sizeof (ent->eps_reachable_subexps_map)                    if (subexp_idx
1940                        && !(ent->eps_reachable_subexps_map & (1 << subexp_idx)))                        < CHAR_BIT * sizeof ent->eps_reachable_subexps_map
1941                          && !(ent->eps_reachable_subexps_map & (1u << subexp_idx)))
1942                      continue;                      continue;
1943    
1944                    /* Recurse trying to reach the OP_OPEN_SUBEXP and                    /* Recurse trying to reach the OP_OPEN_SUBEXP and
# Line 1953  check_dst_limits_calc_pos_1 (mctx, bound Line 1964  check_dst_limits_calc_pos_1 (mctx, bound
1964                    if (cpos == 0 && (boundaries & 2))                    if (cpos == 0 && (boundaries & 2))
1965                      return 0;                      return 0;
1966    
1967                    ent->eps_reachable_subexps_map &= ~(1 << subexp_idx);                    if (subexp_idx
1968                          < CHAR_BIT * sizeof ent->eps_reachable_subexps_map)
1969                        ent->eps_reachable_subexps_map &= ~(1u << subexp_idx);
1970                  }                  }
1971                while (ent++->more);                while (ent++->more);
1972              }              }
# Line 1978  check_dst_limits_calc_pos_1 (mctx, bound Line 1991  check_dst_limits_calc_pos_1 (mctx, bound
1991  }  }
1992    
1993  static int  static int
1994  check_dst_limits_calc_pos (mctx, limit, subexp_idx, from_node, str_idx, bkref_idx)  internal_function
1995       re_match_context_t *mctx;  check_dst_limits_calc_pos (const re_match_context_t *mctx,
1996       int limit, subexp_idx, from_node, str_idx, bkref_idx;                             Idx limit, Idx subexp_idx,
1997                               Idx from_node, Idx str_idx, Idx bkref_idx)
1998  {  {
1999    struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;    struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
2000    int boundaries;    int boundaries;
# Line 2007  check_dst_limits_calc_pos (mctx, limit, Line 2021  check_dst_limits_calc_pos (mctx, limit,
2021     which are against limitations from DEST_NODES. */     which are against limitations from DEST_NODES. */
2022    
2023  static reg_errcode_t  static reg_errcode_t
2024  check_subexp_limits (dfa, dest_nodes, candidates, limits, bkref_ents, str_idx)  internal_function
2025       re_dfa_t *dfa;  check_subexp_limits (re_dfa_t *dfa, re_node_set *dest_nodes,
2026       re_node_set *dest_nodes;                       const re_node_set *candidates, re_node_set *limits,
2027       const re_node_set *candidates;                       struct re_backref_cache_entry *bkref_ents, Idx str_idx)
      re_node_set *limits;  
      struct re_backref_cache_entry *bkref_ents;  
      int str_idx;  
2028  {  {
2029    reg_errcode_t err;    reg_errcode_t err;
2030    int node_idx, lim_idx;    Idx node_idx, lim_idx;
2031    
2032    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
2033      {      {
2034        int subexp_idx;        Idx subexp_idx;
2035        struct re_backref_cache_entry *ent;        struct re_backref_cache_entry *ent;
2036        ent = bkref_ents + limits->elems[lim_idx];        ent = bkref_ents + limits->elems[lim_idx];
2037    
# Line 2030  check_subexp_limits (dfa, dest_nodes, ca Line 2041  check_subexp_limits (dfa, dest_nodes, ca
2041        subexp_idx = dfa->nodes[ent->node].opr.idx;        subexp_idx = dfa->nodes[ent->node].opr.idx;
2042        if (ent->subexp_to == str_idx)        if (ent->subexp_to == str_idx)
2043          {          {
2044            int ops_node = -1;            Idx ops_node = REG_MISSING;
2045            int cls_node = -1;            Idx cls_node = REG_MISSING;
2046            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2047              {              {
2048                int node = dest_nodes->elems[node_idx];                Idx node = dest_nodes->elems[node_idx];
2049                re_token_type_t type = dfa->nodes[node].type;                re_token_type_t type = dfa->nodes[node].type;
2050                if (type == OP_OPEN_SUBEXP                if (type == OP_OPEN_SUBEXP
2051                    && subexp_idx == dfa->nodes[node].opr.idx)                    && subexp_idx == dfa->nodes[node].opr.idx)
# Line 2046  check_subexp_limits (dfa, dest_nodes, ca Line 2057  check_subexp_limits (dfa, dest_nodes, ca
2057    
2058            /* Check the limitation of the open subexpression.  */            /* Check the limitation of the open subexpression.  */
2059            /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */            /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
2060            if (ops_node >= 0)            if (REG_VALID_INDEX (ops_node))
2061              {              {
2062                err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,                err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
2063                                             candidates);                                             candidates);
# Line 2055  check_subexp_limits (dfa, dest_nodes, ca Line 2066  check_subexp_limits (dfa, dest_nodes, ca
2066              }              }
2067    
2068            /* Check the limitation of the close subexpression.  */            /* Check the limitation of the close subexpression.  */
2069            if (cls_node >= 0)            if (REG_VALID_INDEX (cls_node))
2070              for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)              for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2071                {                {
2072                  int node = dest_nodes->elems[node_idx];                  Idx node = dest_nodes->elems[node_idx];
2073                  if (!re_node_set_contains (dfa->inveclosures + node,                  if (!re_node_set_contains (dfa->inveclosures + node,
2074                                             cls_node)                                             cls_node)
2075                      && !re_node_set_contains (dfa->eclosures + node,                      && !re_node_set_contains (dfa->eclosures + node,
# Line 2078  check_subexp_limits (dfa, dest_nodes, ca Line 2089  check_subexp_limits (dfa, dest_nodes, ca
2089          {          {
2090            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
2091              {              {
2092                int node = dest_nodes->elems[node_idx];                Idx node = dest_nodes->elems[node_idx];
2093                re_token_type_t type = dfa->nodes[node].type;                re_token_type_t type = dfa->nodes[node].type;
2094                if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)                if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
2095                  {                  {
# Line 2098  check_subexp_limits (dfa, dest_nodes, ca Line 2109  check_subexp_limits (dfa, dest_nodes, ca
2109  }  }
2110    
2111  static reg_errcode_t  static reg_errcode_t
2112  sift_states_bkref (mctx, sctx, str_idx, candidates)  internal_function
2113       re_match_context_t *mctx;  sift_states_bkref (re_match_context_t *mctx, re_sift_context_t *sctx,
2114       re_sift_context_t *sctx;                     Idx str_idx, const re_node_set *candidates)
      int str_idx;  
      const re_node_set *candidates;  
2115  {  {
2116    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2117    reg_errcode_t err;    reg_errcode_t err;
2118    int node_idx, node;    Idx node_idx, node;
2119    re_sift_context_t local_sctx;    re_sift_context_t local_sctx;
2120    int first_idx = search_cur_bkref_entry (mctx, str_idx);    Idx first_idx = search_cur_bkref_entry (mctx, str_idx);
2121    
2122    if (first_idx == -1)    if (first_idx == REG_MISSING)
2123      return REG_NOERROR;      return REG_NOERROR;
2124    
2125    local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */    local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
2126    
2127    for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)    for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
2128      {      {
2129        int enabled_idx;        Idx enabled_idx;
2130        re_token_type_t type;        re_token_type_t type;
2131        struct re_backref_cache_entry *entry;        struct re_backref_cache_entry *entry;
2132        node = candidates->elems[node_idx];        node = candidates->elems[node_idx];
# Line 2132  sift_states_bkref (mctx, sctx, str_idx, Line 2141  sift_states_bkref (mctx, sctx, str_idx,
2141        enabled_idx = first_idx;        enabled_idx = first_idx;
2142        do        do
2143          {          {
2144            int subexp_len, to_idx, dst_node;            bool ok;
2145              Idx subexp_len, to_idx, dst_node;
2146            re_dfastate_t *cur_state;            re_dfastate_t *cur_state;
2147    
2148            if (entry->node != node)            if (entry->node != node)
# Line 2158  sift_states_bkref (mctx, sctx, str_idx, Line 2168  sift_states_bkref (mctx, sctx, str_idx,
2168              }              }
2169            local_sctx.last_node = node;            local_sctx.last_node = node;
2170            local_sctx.last_str_idx = str_idx;            local_sctx.last_str_idx = str_idx;
2171            err = re_node_set_insert (&local_sctx.limits, enabled_idx);            ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
2172            if (BE (err < 0, 0))            if (BE (! ok, 0))
2173              {              {
2174                err = REG_ESPACE;                err = REG_ESPACE;
2175                goto free_return;                goto free_return;
# Line 2197  sift_states_bkref (mctx, sctx, str_idx, Line 2207  sift_states_bkref (mctx, sctx, str_idx,
2207    
2208  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2209  static int  static int
2210  sift_states_iter_mb (mctx, sctx, node_idx, str_idx, max_str_idx)  internal_function
2211      const re_match_context_t *mctx;  sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
2212      re_sift_context_t *sctx;                       Idx node_idx, Idx str_idx, Idx max_str_idx)
     int node_idx, str_idx, max_str_idx;  
2213  {  {
2214    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2215    int naccepted;    int naccepted;
# Line 2228  sift_states_iter_mb (mctx, sctx, node_id Line 2237  sift_states_iter_mb (mctx, sctx, node_id
2237     update the destination of STATE_LOG.  */     update the destination of STATE_LOG.  */
2238    
2239  static re_dfastate_t *  static re_dfastate_t *
2240  transit_state (err, mctx, state)  internal_function
2241       reg_errcode_t *err;  transit_state (reg_errcode_t *err, re_match_context_t *mctx,
2242       re_match_context_t *mctx;                 re_dfastate_t *state)
      re_dfastate_t *state;  
2243  {  {
2244    re_dfastate_t **trtable;    re_dfastate_t **trtable;
2245    unsigned char ch;    unsigned char ch;
# Line 2287  transit_state (err, mctx, state) Line 2295  transit_state (err, mctx, state)
2295    
2296  /* Update the state_log if we need */  /* Update the state_log if we need */
2297  re_dfastate_t *  re_dfastate_t *
2298  merge_state_with_log (err, mctx, next_state)  internal_function
2299       reg_errcode_t *err;  merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
2300       re_match_context_t *mctx;                        re_dfastate_t *next_state)
      re_dfastate_t *next_state;  
2301  {  {
2302    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2303    int cur_idx = re_string_cur_idx (&mctx->input);    Idx cur_idx = re_string_cur_idx (&mctx->input);
2304    
2305    if (cur_idx > mctx->state_log_top)    if (cur_idx > mctx->state_log_top)
2306      {      {
# Line 2366  merge_state_with_log (err, mctx, next_st Line 2373  merge_state_with_log (err, mctx, next_st
2373  /* Skip bytes in the input that correspond to part of a  /* Skip bytes in the input that correspond to part of a
2374     multi-byte match, then look in the log for a state     multi-byte match, then look in the log for a state
2375     from which to restart matching.  */     from which to restart matching.  */
2376  re_dfastate_t *  static re_dfastate_t *
2377  find_recover_state (err, mctx)  internal_function
2378       reg_errcode_t *err;  find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
      re_match_context_t *mctx;  
2379  {  {
2380    re_dfastate_t *cur_state = NULL;    re_dfastate_t *cur_state = NULL;
2381    do    do
2382      {      {
2383        int max = mctx->state_log_top;        Idx max = mctx->state_log_top;
2384        int cur_str_idx = re_string_cur_idx (&mctx->input);        Idx cur_str_idx = re_string_cur_idx (&mctx->input);
2385    
2386        do        do
2387          {          {
# Line 2387  find_recover_state (err, mctx) Line 2393  find_recover_state (err, mctx)
2393    
2394        cur_state = merge_state_with_log (err, mctx, NULL);        cur_state = merge_state_with_log (err, mctx, NULL);
2395      }      }
2396    while (err == REG_NOERROR && cur_state == NULL);    while (*err == REG_NOERROR && cur_state == NULL);
2397    return cur_state;    return cur_state;
2398  }  }
2399    
# Line 2399  find_recover_state (err, mctx) Line 2405  find_recover_state (err, mctx)
2405     correspoding back references.  */     correspoding back references.  */
2406    
2407  static reg_errcode_t  static reg_errcode_t
2408  check_subexp_matching_top (mctx, cur_nodes, str_idx)  internal_function
2409       re_match_context_t *mctx;  check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
2410       re_node_set *cur_nodes;                             Idx str_idx)
      int str_idx;  
2411  {  {
2412    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2413    int node_idx;    Idx node_idx;
2414    reg_errcode_t err;    reg_errcode_t err;
2415    
2416    /* TODO: This isn't efficient.    /* TODO: This isn't efficient.
# Line 2415  check_subexp_matching_top (mctx, cur_nod Line 2420  check_subexp_matching_top (mctx, cur_nod
2420             E.g. RE: (a){2}  */             E.g. RE: (a){2}  */
2421    for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)    for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
2422      {      {
2423        int node = cur_nodes->elems[node_idx];        Idx node = cur_nodes->elems[node_idx];
2424        if (dfa->nodes[node].type == OP_OPEN_SUBEXP        if (dfa->nodes[node].type == OP_OPEN_SUBEXP
2425            && dfa->nodes[node].opr.idx < (8 * sizeof (dfa->used_bkref_map))            && dfa->nodes[node].opr.idx < CHAR_BIT * sizeof dfa->used_bkref_map
2426            && dfa->used_bkref_map & (1 << dfa->nodes[node].opr.idx))            && dfa->used_bkref_map & (1u << dfa->nodes[node].opr.idx))
2427          {          {
2428            err = match_ctx_add_subtop (mctx, node, str_idx);            err = match_ctx_add_subtop (mctx, node, str_idx);
2429            if (BE (err != REG_NOERROR, 0))            if (BE (err != REG_NOERROR, 0))
# Line 2433  check_subexp_matching_top (mctx, cur_nod Line 2438  check_subexp_matching_top (mctx, cur_nod
2438     accepting the current input byte.  */     accepting the current input byte.  */
2439    
2440  static re_dfastate_t *  static re_dfastate_t *
2441  transit_state_sb (err, mctx, state)  transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
2442       reg_errcode_t *err;                    re_dfastate_t *state)
      re_match_context_t *mctx;  
      re_dfastate_t *state;  
2443  {  {
2444    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2445    re_node_set next_nodes;    re_node_set next_nodes;
2446    re_dfastate_t *next_state;    re_dfastate_t *next_state;
2447    int node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);    Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
2448    unsigned int context;    unsigned int context;
2449    
2450    *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);    *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
# Line 2449  transit_state_sb (err, mctx, state) Line 2452  transit_state_sb (err, mctx, state)
2452      return NULL;      return NULL;
2453    for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)    for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
2454      {      {
2455        int cur_node = state->nodes.elems[node_cnt];        Idx cur_node = state->nodes.elems[node_cnt];
2456        if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))        if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
2457          {          {
2458            *err = re_node_set_merge (&next_nodes,            *err = re_node_set_merge (&next_nodes,
# Line 2474  transit_state_sb (err, mctx, state) Line 2477  transit_state_sb (err, mctx, state)
2477    
2478  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
2479  static reg_errcode_t  static reg_errcode_t
2480  transit_state_mb (mctx, pstate)  internal_function
2481      re_match_context_t *mctx;  transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
     re_dfastate_t *pstate;  
2482  {  {
2483    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2484    reg_errcode_t err;    reg_errcode_t err;
2485    int i;    Idx i;
2486    
2487    for (i = 0; i < pstate->nodes.nelem; ++i)    for (i = 0; i < pstate->nodes.nelem; ++i)
2488      {      {
2489        re_node_set dest_nodes, *new_nodes;        re_node_set dest_nodes, *new_nodes;
2490        int cur_node_idx = pstate->nodes.elems[i];        Idx cur_node_idx = pstate->nodes.elems[i];
2491        int naccepted, dest_idx;        int naccepted;
2492          Idx dest_idx;
2493        unsigned int context;        unsigned int context;
2494        re_dfastate_t *dest_state;        re_dfastate_t *dest_state;
2495    
# Line 2517  transit_state_mb (mctx, pstate) Line 2520  transit_state_mb (mctx, pstate)
2520        if (BE (err != REG_NOERROR, 0))        if (BE (err != REG_NOERROR, 0))
2521          return err;          return err;
2522  #ifdef DEBUG  #ifdef DEBUG
2523        assert (dfa->nexts[cur_node_idx] != -1);        assert (dfa->nexts[cur_node_idx] != REG_MISSING);
2524  #endif  #endif
2525        new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];        new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
2526    
# Line 2544  transit_state_mb (mctx, pstate) Line 2547  transit_state_mb (mctx, pstate)
2547  #endif /* RE_ENABLE_I18N */  #endif /* RE_ENABLE_I18N */
2548    
2549  static reg_errcode_t  static reg_errcode_t
2550  transit_state_bkref (mctx, nodes)  internal_function
2551      re_match_context_t *mctx;  transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
     const re_node_set *nodes;  
2552  {  {
2553    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2554    reg_errcode_t err;    reg_errcode_t err;
2555    int i;    Idx i;
2556    int cur_str_idx = re_string_cur_idx (&mctx->input);    Idx cur_str_idx = re_string_cur_idx (&mctx->input);
2557    
2558    for (i = 0; i < nodes->nelem; ++i)    for (i = 0; i < nodes->nelem; ++i)
2559      {      {
2560        int dest_str_idx, prev_nelem, bkc_idx;        Idx dest_str_idx, prev_nelem, bkc_idx;
2561        int node_idx = nodes->elems[i];        Idx node_idx = nodes->elems[i];
2562        unsigned int context;        unsigned int context;
2563        const re_token_t *node = dfa->nodes + node_idx;        const re_token_t *node = dfa->nodes + node_idx;
2564        re_node_set *new_dest_nodes;        re_node_set *new_dest_nodes;
# Line 2583  transit_state_bkref (mctx, nodes) Line 2585  transit_state_bkref (mctx, nodes)
2585        /* And add the epsilon closures (which is `new_dest_nodes') of        /* And add the epsilon closures (which is `new_dest_nodes') of
2586           the backreference to appropriate state_log.  */           the backreference to appropriate state_log.  */
2587  #ifdef DEBUG  #ifdef DEBUG
2588        assert (dfa->nexts[node_idx] != -1);        assert (dfa->nexts[node_idx] != REG_MISSING);
2589  #endif  #endif
2590        for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)        for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
2591          {          {
2592            int subexp_len;            Idx subexp_len;
2593            re_dfastate_t *dest_state;            re_dfastate_t *dest_state;
2594            struct re_backref_cache_entry *bkref_ent;            struct re_backref_cache_entry *bkref_ent;
2595            bkref_ent = mctx->bkref_ents + bkc_idx;            bkref_ent = mctx->bkref_ents + bkc_idx;
# Line 2659  transit_state_bkref (mctx, nodes) Line 2661  transit_state_bkref (mctx, nodes)
2661     delay these checking for prune_impossible_nodes().  */     delay these checking for prune_impossible_nodes().  */
2662    
2663  static reg_errcode_t  static reg_errcode_t
2664  get_subexp (mctx, bkref_node, bkref_str_idx)  internal_function
2665       re_match_context_t *mctx;  get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
      int bkref_node, bkref_str_idx;  
2666  {  {
2667    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2668    int subexp_num, sub_top_idx;    Idx subexp_num, sub_top_idx;
2669    const char *buf = (const char *) re_string_get_buffer (&mctx->input);    const char *buf = (const char *) re_string_get_buffer (&mctx->input);
2670    /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */    /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
2671    int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);    Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
2672    if (cache_idx != -1)    if (cache_idx != REG_MISSING)
2673      {      {
2674        const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx;        const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx;
2675        do        do
# Line 2685  get_subexp (mctx, bkref_node, bkref_str_ Line 2686  get_subexp (mctx, bkref_node, bkref_str_
2686        reg_errcode_t err;        reg_errcode_t err;
2687        re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];        re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
2688        re_sub_match_last_t *sub_last;        re_sub_match_last_t *sub_last;
2689        int sub_last_idx, sl_str, bkref_str_off;        Idx sub_last_idx, sl_str, bkref_str_off;
2690    
2691        if (dfa->nodes[sub_top->node].opr.idx != subexp_num)        if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
2692          continue; /* It isn't related.  */          continue; /* It isn't related.  */
# Line 2696  get_subexp (mctx, bkref_node, bkref_str_ Line 2697  get_subexp (mctx, bkref_node, bkref_str_
2697           evaluated.  */           evaluated.  */
2698        for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)        for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
2699          {          {
2700            int sl_str_diff;            regoff_t sl_str_diff;
2701            sub_last = sub_top->lasts[sub_last_idx];            sub_last = sub_top->lasts[sub_last_idx];
2702            sl_str_diff = sub_last->str_idx - sl_str;            sl_str_diff = sub_last->str_idx - sl_str;
2703            /* The matched string by the sub expression match with the substring            /* The matched string by the sub expression match with the substring
# Line 2741  get_subexp (mctx, bkref_node, bkref_str_ Line 2742  get_subexp (mctx, bkref_node, bkref_str_
2742        /* Then, search for the other last nodes of the sub expression.  */        /* Then, search for the other last nodes of the sub expression.  */
2743        for (; sl_str <= bkref_str_idx; ++sl_str)        for (; sl_str <= bkref_str_idx; ++sl_str)
2744          {          {
2745            int cls_node, sl_str_off;            Idx cls_node;
2746              regoff_t sl_str_off;
2747            const re_node_set *nodes;            const re_node_set *nodes;
2748            sl_str_off = sl_str - sub_top->str_idx;            sl_str_off = sl_str - sub_top->str_idx;
2749            /* The matched string by the sub expression match with the substring            /* The matched string by the sub expression match with the substring
# Line 2769  get_subexp (mctx, bkref_node, bkref_str_ Line 2771  get_subexp (mctx, bkref_node, bkref_str_
2771            /* Does this state have a ')' of the sub expression?  */            /* Does this state have a ')' of the sub expression?  */
2772            nodes = &mctx->state_log[sl_str]->nodes;            nodes = &mctx->state_log[sl_str]->nodes;
2773            cls_node = find_subexp_node (dfa, nodes, subexp_num, OP_CLOSE_SUBEXP);            cls_node = find_subexp_node (dfa, nodes, subexp_num, OP_CLOSE_SUBEXP);
2774            if (cls_node == -1)            if (cls_node == REG_MISSING)
2775              continue; /* No.  */              continue; /* No.  */
2776            if (sub_top->path == NULL)            if (sub_top->path == NULL)
2777              {              {
2778                sub_top->path = calloc (sizeof (state_array_t),                sub_top->path = re_calloc (state_array_t,
2779                                        sl_str - sub_top->str_idx + 1);                                           sl_str - sub_top->str_idx + 1);
2780                if (sub_top->path == NULL)                if (sub_top->path == NULL)
2781                  return REG_ESPACE;                  return REG_ESPACE;
2782              }              }
# Line 2805  get_subexp (mctx, bkref_node, bkref_str_ Line 2807  get_subexp (mctx, bkref_node, bkref_str_
2807     and SUB_LAST.  */     and SUB_LAST.  */
2808    
2809  static reg_errcode_t  static reg_errcode_t
2810  get_subexp_sub (mctx, sub_top, sub_last, bkref_node, bkref_str)  internal_function
2811       re_match_context_t *mctx;  get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
2812       const re_sub_match_top_t *sub_top;                  re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str)
      re_sub_match_last_t *sub_last;  
      int bkref_node, bkref_str;  
2813  {  {
2814    reg_errcode_t err;    reg_errcode_t err;
2815    int to_idx;    Idx to_idx;
2816    /* Can the subexpression arrive the back reference?  */    /* Can the subexpression arrive the back reference?  */
2817    err = check_arrival (mctx, &sub_last->path, sub_last->node,    err = check_arrival (mctx, &sub_last->path, sub_last->node,
2818                         sub_last->str_idx, bkref_node, bkref_str, OP_OPEN_SUBEXP);                         sub_last->str_idx, bkref_node, bkref_str, OP_OPEN_SUBEXP);
# Line 2834  get_subexp_sub (mctx, sub_top, sub_last, Line 2834  get_subexp_sub (mctx, sub_top, sub_last,
2834           nodes.           nodes.
2835           E.g. RE: (a){2}  */           E.g. RE: (a){2}  */
2836    
2837  static int  static Idx
2838  find_subexp_node (dfa, nodes, subexp_idx, type)  internal_function
2839       const re_dfa_t *dfa;  find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
2840       const re_node_set *nodes;                    Idx subexp_idx, int type)
      int subexp_idx, type;  
2841  {  {
2842    int cls_idx;    Idx cls_idx;
2843    for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)    for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
2844      {      {
2845        int cls_node = nodes->elems[cls_idx];        Idx cls_node = nodes->elems[cls_idx];
2846        const re_token_t *node = dfa->nodes + cls_node;        const re_token_t *node = dfa->nodes + cls_node;
2847        if (node->type == type        if (node->type == type
2848            && node->opr.idx == subexp_idx)            && node->opr.idx == subexp_idx)
2849          return cls_node;          return cls_node;
2850      }      }
2851    return -1;    return REG_MISSING;
2852  }  }
2853    
2854  /* Check whether the node TOP_NODE at TOP_STR can arrive to the node  /* Check whether the node TOP_NODE at TOP_STR can arrive to the node
# Line 2858  find_subexp_node (dfa, nodes, subexp_idx Line 2857  find_subexp_node (dfa, nodes, subexp_idx
2857     Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */     Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
2858    
2859  static reg_errcode_t  static reg_errcode_t
2860  check_arrival (mctx, path, top_node, top_str, last_node, last_str,  internal_function
2861                 type)  check_arrival (re_match_context_t *mctx, state_array_t *path,
2862       re_match_context_t *mctx;                 Idx top_node, Idx top_str, Idx last_node, Idx last_str,
2863       state_array_t *path;                 int type)
      int top_node, top_str, last_node, last_str, type;  
2864  {  {
2865    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
2866    reg_errcode_t err;    reg_errcode_t err;
2867    int subexp_num, backup_cur_idx, str_idx, null_cnt;    Idx subexp_num, backup_cur_idx, str_idx, null_cnt;
2868    re_dfastate_t *cur_state = NULL;    re_dfastate_t *cur_state = NULL;
2869    re_node_set *cur_nodes, next_nodes;    re_node_set *cur_nodes, next_nodes;
2870    re_dfastate_t **backup_state_log;    re_dfastate_t **backup_state_log;
# Line 2877  check_arrival (mctx, path, top_node, top Line 2875  check_arrival (mctx, path, top_node, top
2875    if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))    if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
2876      {      {
2877        re_dfastate_t **new_array;        re_dfastate_t **new_array;
2878        int old_alloc = path->alloc;        Idx old_alloc = path->alloc;
2879        path->alloc += last_str + mctx->max_mb_elem_len + 1;        Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1;
2880        new_array = re_realloc (path->array, re_dfastate_t *, path->alloc);        if (BE (new_alloc < old_alloc, 0))
2881        if (new_array == NULL)          return REG_ESPACE;
2882          {        new_array = re_xrealloc (path->array, re_dfastate_t *, new_alloc);
2883            path->alloc = old_alloc;        if (BE (new_array == NULL, 0))
2884            return REG_ESPACE;          return REG_ESPACE;
         }  
2885        path->array = new_array;        path->array = new_array;
2886          path->alloc = new_alloc;
2887        memset (new_array + old_alloc, '\0',        memset (new_array + old_alloc, '\0',
2888                sizeof (re_dfastate_t *) * (path->alloc - old_alloc));                sizeof (re_dfastate_t *) * (new_alloc - old_alloc));
2889      }      }
2890    
2891    str_idx = path->next_idx == 0 ? top_str : path->next_idx;    str_idx = path->next_idx == 0 ? top_str : path->next_idx;
# Line 3020  check_arrival (mctx, path, top_node, top Line 3018  check_arrival (mctx, path, top_node, top
3018           Can't we unify them?  */           Can't we unify them?  */
3019    
3020  static reg_errcode_t  static reg_errcode_t
3021  check_arrival_add_next_nodes (mctx, str_idx, cur_nodes, next_nodes)  internal_function
3022       re_match_context_t *mctx;  check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
3023       int str_idx;                                re_node_set *cur_nodes,
3024       re_node_set *cur_nodes, *next_nodes;                                re_node_set *next_nodes)
3025  {  {
3026    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
3027    int result;    bool ok;
3028    int cur_idx;    Idx cur_idx;
3029    reg_errcode_t err;    reg_errcode_t err;
3030    re_node_set union_set;    re_node_set union_set;
3031    re_node_set_init_empty (&union_set);    re_node_set_init_empty (&union_set);
3032    for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)    for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
3033      {      {
3034        int naccepted = 0;        int naccepted = 0;
3035        int cur_node = cur_nodes->elems[cur_idx];        Idx cur_node = cur_nodes->elems[cur_idx];
3036  #ifdef DEBUG  #ifdef DEBUG
3037        re_token_type_t type = dfa->nodes[cur_node].type;        re_token_type_t type = dfa->nodes[cur_node].type;
3038        assert (!IS_EPSILON_NODE (type));        assert (!IS_EPSILON_NODE (type));
# Line 3048  check_arrival_add_next_nodes (mctx, str_ Line 3046  check_arrival_add_next_nodes (mctx, str_
3046            if (naccepted > 1)            if (naccepted > 1)
3047              {              {
3048                re_dfastate_t *dest_state;                re_dfastate_t *dest_state;
3049                int next_node = dfa->nexts[cur_node];                Idx next_node = dfa->nexts[cur_node];
3050                int next_idx = str_idx + naccepted;                Idx next_idx = str_idx + naccepted;
3051                dest_state = mctx->state_log[next_idx];                dest_state = mctx->state_log[next_idx];
3052                re_node_set_empty (&union_set);                re_node_set_empty (&union_set);
3053                if (dest_state)                if (dest_state)
# Line 3061  check_arrival_add_next_nodes (mctx, str_ Line 3059  check_arrival_add_next_nodes (mctx, str_
3059                        return err;                        return err;
3060                      }                      }
3061                  }                  }
3062                result = re_node_set_insert (&union_set, next_node);                ok = re_node_set_insert (&union_set, next_node);
3063                if (BE (result < 0, 0))                if (BE (! ok, 0))
3064                  {                  {
3065                    re_node_set_free (&union_set);                    re_node_set_free (&union_set);
3066                    return REG_ESPACE;                    return REG_ESPACE;
# Line 3081  check_arrival_add_next_nodes (mctx, str_ Line 3079  check_arrival_add_next_nodes (mctx, str_
3079        if (naccepted        if (naccepted
3080            || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))            || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
3081          {          {
3082            result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);            ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
3083            if (BE (result < 0, 0))            if (BE (! ok, 0))
3084              {              {
3085                re_node_set_free (&union_set);                re_node_set_free (&union_set);
3086                return REG_ESPACE;                return REG_ESPACE;
# Line 3100  check_arrival_add_next_nodes (mctx, str_ Line 3098  check_arrival_add_next_nodes (mctx, str_
3098  */  */
3099    
3100  static reg_errcode_t  static reg_errcode_t
3101  check_arrival_expand_ecl (dfa, cur_nodes, ex_subexp, type)  internal_function
3102       re_dfa_t *dfa;  check_arrival_expand_ecl (re_dfa_t *dfa, re_node_set *cur_nodes,
3103       re_node_set *cur_nodes;                            Idx ex_subexp, int type)
      int ex_subexp, type;  
3104  {  {
3105    reg_errcode_t err;    reg_errcode_t err;
3106    int idx, outside_node;    Idx idx, outside_node;
3107    re_node_set new_nodes;    re_node_set new_nodes;
3108  #ifdef DEBUG  #ifdef DEBUG
3109    assert (cur_nodes->nelem);    assert (cur_nodes->nelem);
# Line 3119  check_arrival_expand_ecl (dfa, cur_nodes Line 3116  check_arrival_expand_ecl (dfa, cur_nodes
3116    
3117    for (idx = 0; idx < cur_nodes->nelem; ++idx)    for (idx = 0; idx < cur_nodes->nelem; ++idx)
3118      {      {
3119        int cur_node = cur_nodes->elems[idx];        Idx cur_node = cur_nodes->elems[idx];
3120        re_node_set *eclosure = dfa->eclosures + cur_node;        re_node_set *eclosure = dfa->eclosures + cur_node;
3121        outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);        outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
3122        if (outside_node == -1)        if (outside_node == REG_MISSING)
3123          {          {
3124            /* There are no problematic nodes, just merge them.  */            /* There are no problematic nodes, just merge them.  */
3125            err = re_node_set_merge (&new_nodes, eclosure);            err = re_node_set_merge (&new_nodes, eclosure);
# Line 3154  check_arrival_expand_ecl (dfa, cur_nodes Line 3151  check_arrival_expand_ecl (dfa, cur_nodes
3151     problematic append it to DST_NODES.  */     problematic append it to DST_NODES.  */
3152    
3153  static reg_errcode_t  static reg_errcode_t
3154  check_arrival_expand_ecl_sub (dfa, dst_nodes, target, ex_subexp, type)  internal_function
3155       re_dfa_t *dfa;  check_arrival_expand_ecl_sub (re_dfa_t *dfa, re_node_set *dst_nodes,
3156       int target, ex_subexp, type;                                Idx target, Idx ex_subexp, int type)
      re_node_set *dst_nodes;  
3157  {  {
3158    int cur_node;    Idx cur_node;
3159    for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)    for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
3160      {      {
3161        int err;        bool ok;
3162    
3163        if (dfa->nodes[cur_node].type == type        if (dfa->nodes[cur_node].type == type
3164            && dfa->nodes[cur_node].opr.idx == ex_subexp)            && dfa->nodes[cur_node].opr.idx == ex_subexp)
3165          {          {
3166            if (type == OP_CLOSE_SUBEXP)            if (type == OP_CLOSE_SUBEXP)
3167              {              {
3168                err = re_node_set_insert (dst_nodes, cur_node);                ok = re_node_set_insert (dst_nodes, cur_node);
3169                if (BE (err == -1, 0))                if (BE (! ok, 0))
3170                  return REG_ESPACE;                  return REG_ESPACE;
3171              }              }
3172            break;            break;
3173          }          }
3174        err = re_node_set_insert (dst_nodes, cur_node);        ok = re_node_set_insert (dst_nodes, cur_node);
3175        if (BE (err == -1, 0))        if (BE (! ok, 0))
3176          return REG_ESPACE;          return REG_ESPACE;
3177        if (dfa->edests[cur_node].nelem == 0)        if (dfa->edests[cur_node].nelem == 0)
3178          break;          break;
3179        if (dfa->edests[cur_node].nelem == 2)        if (dfa->edests[cur_node].nelem == 2)
3180          {          {
3181            err = check_arrival_expand_ecl_sub (dfa, dst_nodes,            reg_errcode_t ret =
3182                                                dfa->edests[cur_node].elems[1],              check_arrival_expand_ecl_sub (dfa, dst_nodes,
3183                                                ex_subexp, type);                                            dfa->edests[cur_node].elems[1],
3184            if (BE (err != REG_NOERROR, 0))                                            ex_subexp, type);
3185              return err;            if (BE (ret != REG_NOERROR, 0))
3186                return ret;
3187          }          }
3188        cur_node = dfa->edests[cur_node].elems[0];        cur_node = dfa->edests[cur_node].elems[0];
3189      }      }
# Line 3199  check_arrival_expand_ecl_sub (dfa, dst_n Line 3196  check_arrival_expand_ecl_sub (dfa, dst_n
3196     in MCTX->BKREF_ENTS.  */     in MCTX->BKREF_ENTS.  */
3197    
3198  static reg_errcode_t  static reg_errcode_t
3199  expand_bkref_cache (mctx, cur_nodes, cur_str, subexp_num,  internal_function
3200                      type)  expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
3201       re_match_context_t *mctx;                      Idx cur_str, Idx subexp_num, int type)
      int cur_str, subexp_num, type;  
      re_node_set *cur_nodes;  
3202  {  {
3203    re_dfa_t *const dfa = mctx->dfa;    re_dfa_t *const dfa = mctx->dfa;
3204    reg_errcode_t err;    reg_errcode_t err;
3205    int cache_idx_start = search_cur_bkref_entry (mctx, cur_str);    Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
3206    struct re_backref_cache_entry *ent;    struct re_backref_cache_entry *ent;
3207    
3208    if (cache_idx_start == -1)    if (cache_idx_start == REG_MISSING)
3209      return REG_NOERROR;      return REG_NOERROR;
3210    
3211   restart:   restart:
3212    ent = mctx->bkref_ents + cache_idx_start;    ent = mctx->bkref_ents + cache_idx_start;
3213    do    do
3214      {      {
3215        int to_idx, next_node;        Idx to_idx, next_node;
3216    
3217        /* Is this entry ENT is appropriate?  */        /* Is this entry ENT is appropriate?  */
3218        if (!re_node_set_contains (cur_nodes, ent->node))        if (!re_node_set_contains (cur_nodes, ent->node))
# Line 3255  expand_bkref_cache (mctx, cur_nodes, cur Line 3250  expand_bkref_cache (mctx, cur_nodes, cur
3250            next_node = dfa->nexts[ent->node];            next_node = dfa->nexts[ent->node];
3251            if (mctx->state_log[to_idx])            if (mctx->state_log[to_idx])
3252              {              {
3253                int ret;                bool ok;
3254                if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,                if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
3255                                          next_node))                                          next_node))
3256                  continue;                  continue;
3257                err = re_node_set_init_copy (&union_set,                err = re_node_set_init_copy (&union_set,
3258                                             &mctx->state_log[to_idx]->nodes);                                             &mctx->state_log[to_idx]->nodes);
3259                ret = re_node_set_insert (&union_set, next_node);                ok = re_node_set_insert (&union_set, next_node);
3260                if (BE (err != REG_NOERROR || ret < 0, 0))                if (BE (err != REG_NOERROR || ! ok, 0))
3261                  {                  {
3262                    re_node_set_free (&union_set);                    re_node_set_free (&union_set);
3263                    err = err != REG_NOERROR ? err : REG_ESPACE;                    err = err != REG_NOERROR ? err : REG_ESPACE;
# Line 3287  expand_bkref_cache (mctx, cur_nodes, cur Line 3282  expand_bkref_cache (mctx, cur_nodes, cur
3282  }  }
3283    
3284  /* Build transition table for the state.  /* Build transition table for the state.
3285     Return 1 if succeeded, otherwise return NULL.  */     Return true if successful.  */
3286    
3287  static int  static bool
3288  build_trtable (dfa, state)  internal_function
3289      re_dfa_t *dfa;  build_trtable (re_dfa_t *dfa, re_dfastate_t *state)
     re_dfastate_t *state;  
3290  {  {
3291    reg_errcode_t err;    reg_errcode_t err;
3292    int i, j, ch, need_word_trtable = 0;    Idx i, j;
3293      int ch;
3294      bool need_word_trtable = false;
3295    unsigned int elem, mask;    unsigned int elem, mask;
3296    int dests_node_malloced = 0, dest_states_malloced = 0;    bool dests_node_malloced = false, dest_states_malloced = false;
3297    int ndests; /* Number of the destination states from `state'.  */    Idx ndests; /* Number of the destination states from `state'.  */
3298    re_dfastate_t **trtable;    re_dfastate_t **trtable;
3299    re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;    re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
3300    re_node_set follows, *dests_node;    re_node_set follows, *dests_node;
# Line 3309  build_trtable (dfa, state) Line 3305  build_trtable (dfa, state)
3305       from `state'.  `dests_node[i]' represents the nodes which i-th       from `state'.  `dests_node[i]' represents the nodes which i-th
3306       destination state contains, and `dests_ch[i]' represents the       destination state contains, and `dests_ch[i]' represents the
3307       characters which i-th destination state accepts.  */       characters which i-th destination state accepts.  */
 #ifdef _LIBC  
3308    if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))    if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))
3309      dests_node = (re_node_set *)      dests_node = (re_node_set *)
3310        alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);        alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
3311    else    else
 #endif  
3312      {      {
3313        dests_node = (re_node_set *)        dests_node = (re_node_set *)
3314          malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);          malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
3315        if (BE (dests_node == NULL, 0))        if (BE (dests_node == NULL, 0))
3316          return 0;          return false;
3317        dests_node_malloced = 1;        dests_node_malloced = true;
3318      }      }
3319    dests_ch = (bitset *) (dests_node + SBC_MAX);    dests_ch = (bitset *) (dests_node + SBC_MAX);
3320    
# Line 3330  build_trtable (dfa, state) Line 3324  build_trtable (dfa, state)
3324    /* At first, group all nodes belonging to `state' into several    /* At first, group all nodes belonging to `state' into several
3325       destinations.  */       destinations.  */
3326    ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);    ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
3327    if (BE (ndests <= 0, 0))    if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0))
3328      {      {
3329        if (dests_node_malloced)        if (dests_node_malloced)
3330          free (dests_node);          free (dests_node);
       /* Return 0 in case of an error, 1 otherwise.  */  
3331        if (ndests == 0)        if (ndests == 0)
3332          {          {
3333            state->trtable = (re_dfastate_t **)            state->trtable = re_calloc (re_dfastate_t *, SBC_MAX);
3334              calloc (sizeof (re_dfastate_t *), SBC_MAX);            return true;
           return 1;  
3335          }          }
3336        return 0;        return false;
3337      }      }
3338    
3339    err = re_node_set_alloc (&follows, ndests + 1);    err = re_node_set_alloc (&follows, ndests + 1);
3340    if (BE (err != REG_NOERROR, 0))    if (BE (err != REG_NOERROR, 0))
3341      goto out_free;      goto out_free;
3342    
3343  #ifdef _LIBC    /* Avoid arithmetic overflow in size calculation.  */
3344      if (BE (((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX)
3345               / (3 * sizeof (re_dfastate_t *)))
3346              < ndests, 0))
3347        goto out_free;
3348    
3349    if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX    if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
3350                           + ndests * 3 * sizeof (re_dfastate_t *)))                           + ndests * 3 * sizeof (re_dfastate_t *)))
3351      dest_states = (re_dfastate_t **)      dest_states = (re_dfastate_t **)
3352        alloca (ndests * 3 * sizeof (re_dfastate_t *));        alloca (ndests * 3 * sizeof (re_dfastate_t *));
3353    else    else
 #endif  
3354      {      {
3355        dest_states = (re_dfastate_t **)        dest_states = (re_dfastate_t **)
3356          malloc (ndests * 3 * sizeof (re_dfastate_t *));          malloc (ndests * 3 * sizeof (re_dfastate_t *));
# Line 3368  out_free: Line 3364  out_free:
3364              re_node_set_free (dests_node + i);              re_node_set_free (dests_node + i);
3365            if (dests_node_malloced)            if (dests_node_malloced)
3366              free (dests_node);              free (dests_node);
3367            return 0;            return false;
3368          }          }
3369        dest_states_malloced = 1;        dest_states_malloced = true;
3370      }      }
3371    dest_states_word = dest_states + ndests;    dest_states_word = dest_states + ndests;
3372    dest_states_nl = dest_states_word + ndests;    dest_states_nl = dest_states_word + ndests;
# Line 3379  out_free: Line 3375  out_free:
3375    /* Then build the states for all destinations.  */    /* Then build the states for all destinations.  */
3376    for (i = 0; i < ndests; ++i)    for (i = 0; i < ndests; ++i)
3377      {      {
3378        int next_node;        Idx next_node;
3379        re_node_set_empty (&follows);        re_node_set_empty (&follows);
3380        /* Merge the follows of this destination states.  */        /* Merge the follows of this destination states.  */
3381        for (j = 0; j < dests_node[i].nelem; ++j)        for (j = 0; j < dests_node[i].nelem; ++j)
3382          {          {
3383            next_node = dfa->nexts[dests_node[i].elems[j]];            next_node = dfa->nexts[dests_node[i].elems[j]];
3384            if (next_node != -1)            if (next_node != REG_MISSING)
3385              {              {
3386                err = re_node_set_merge (&follows, dfa->eclosures + next_node);                err = re_node_set_merge (&follows, dfa->eclosures + next_node);
3387                if (BE (err != REG_NOERROR, 0))                if (BE (err != REG_NOERROR, 0))
# Line 3405  out_free: Line 3401  out_free:
3401              goto out_free;              goto out_free;
3402    
3403            if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)            if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
3404              need_word_trtable = 1;              need_word_trtable = true;
3405    
3406            dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,            dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
3407                                                          CONTEXT_NEWLINE);                                                          CONTEXT_NEWLINE);
# Line 3426  out_free: Line 3422  out_free:
3422           character, or we are in a single-byte character set so we can           character, or we are in a single-byte character set so we can
3423           discern by looking at the character code: allocate a           discern by looking at the character code: allocate a
3424           256-entry transition table.  */           256-entry transition table.  */
3425        trtable = state->trtable =        trtable = state->trtable = re_calloc (re_dfastate_t *, SBC_MAX);
         (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);  
3426        if (BE (trtable == NULL, 0))        if (BE (trtable == NULL, 0))
3427          goto out_free;          goto out_free;
3428    
# Line 3457  out_free: Line 3452  out_free:
3452           by looking at the character code: build two 256-entry           by looking at the character code: build two 256-entry
3453           transition tables, one starting at trtable[0] and one           transition tables, one starting at trtable[0] and one
3454           starting at trtable[SBC_MAX].  */           starting at trtable[SBC_MAX].  */
3455        trtable = state->word_trtable =        trtable = state->word_trtable = re_calloc (re_dfastate_t *, 2 * SBC_MAX);
         (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);  
3456        if (BE (trtable == NULL, 0))        if (BE (trtable == NULL, 0))
3457          goto out_free;          goto out_free;
3458    
# Line 3507  out_free: Line 3501  out_free:
3501    if (dests_node_malloced)    if (dests_node_malloced)
3502      free (dests_node);      free (dests_node);
3503    
3504    return 1;    return true;
3505  }  }
3506    
3507  /* Group all nodes belonging to STATE into several destinations.  /* Group all nodes belonging to STATE into several destinations.
# Line 3515  out_free: Line 3509  out_free:
3509     to DESTS_NODE[i] and set the characters accepted by the destination     to DESTS_NODE[i] and set the characters accepted by the destination
3510     to DEST_CH[i].  This function return the number of destinations.  */     to DEST_CH[i].  This function return the number of destinations.  */
3511    
3512  static int  static Idx
3513  group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch)  internal_function
3514      re_dfa_t *dfa;  group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
3515      const re_dfastate_t *state;                              re_node_set *dests_node, bitset *dests_ch)
     re_node_set *dests_node;  
     bitset *dests_ch;  
3516  {  {
3517    reg_errcode_t err;    reg_errcode_t err;
3518    int result;    bool ok;
3519    int i, j, k;    Idx i, j, k;
3520    int ndests; /* Number of the destinations from `state'.  */    Idx ndests; /* Number of the destinations from `state'.  */
3521    bitset accepts; /* Characters a node can accept.  */    bitset accepts; /* Characters a node can accept.  */
3522    const re_node_set *cur_nodes = &state->nodes;    const re_node_set *cur_nodes = &state->nodes;
3523    bitset_empty (accepts);    bitset_empty (accepts);
# Line 3553  group_nodes_into_DFAstates (dfa, state, Line 3545  group_nodes_into_DFAstates (dfa, state,
3545            else            else
3546  #endif  #endif
3547              bitset_set_all (accepts);              bitset_set_all (accepts);
3548            if (!(dfa->syntax & RE_DOT_NEWLINE))            if (!(dfa->syntax & REG_DOT_NEWLINE))
3549              bitset_clear (accepts, '\n');              bitset_clear (accepts, '\n');
3550            if (dfa->syntax & RE_DOT_NOT_NULL)            if (dfa->syntax & REG_DOT_NOT_NULL)
3551              bitset_clear (accepts, '\0');              bitset_clear (accepts, '\0');
3552          }          }
3553  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
3554        else if (type == OP_UTF8_PERIOD)        else if (type == OP_UTF8_PERIOD)
3555          {          {
3556            memset (accepts, 255, sizeof (unsigned int) * BITSET_UINTS / 2);            memset (accepts, 255, sizeof (unsigned int) * BITSET_UINTS / 2);
3557            if (!(dfa->syntax & RE_DOT_NEWLINE))            if (!(dfa->syntax & REG_DOT_NEWLINE))
3558              bitset_clear (accepts, '\n');              bitset_clear (accepts, '\n');
3559            if (dfa->syntax & RE_DOT_NOT_NULL)            if (dfa->syntax & REG_DOT_NOT_NULL)
3560              bitset_clear (accepts, '\0');              bitset_clear (accepts, '\0');
3561          }          }
3562  #endif  #endif
# Line 3577  group_nodes_into_DFAstates (dfa, state, Line 3569  group_nodes_into_DFAstates (dfa, state,
3569          {          {
3570            if (constraint & NEXT_NEWLINE_CONSTRAINT)            if (constraint & NEXT_NEWLINE_CONSTRAINT)
3571              {              {
3572                int accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);                unsigned int accepts_newline =
3573                    bitset_contain (accepts, NEWLINE_CHAR);
3574                bitset_empty (accepts);                bitset_empty (accepts);
3575                if (accepts_newline)                if (accepts_newline)
3576                  bitset_set (accepts, NEWLINE_CHAR);                  bitset_set (accepts, NEWLINE_CHAR);
# Line 3637  group_nodes_into_DFAstates (dfa, state, Line 3630  group_nodes_into_DFAstates (dfa, state,
3630            bitset intersec; /* Intersection sets, see below.  */            bitset intersec; /* Intersection sets, see below.  */
3631            bitset remains;            bitset remains;
3632            /* Flags, see below.  */            /* Flags, see below.  */
3633            int has_intersec, not_subset, not_consumed;            unsigned int has_intersec, not_subset, not_consumed;
3634    
3635            /* Optimization, skip if this state doesn't accept the character.  */            /* Optimization, skip if this state doesn't accept the character.  */
3636            if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))            if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
# Line 3672  group_nodes_into_DFAstates (dfa, state, Line 3665  group_nodes_into_DFAstates (dfa, state,
3665              }              }
3666    
3667            /* Put the position in the current group. */            /* Put the position in the current group. */
3668            result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);            ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
3669            if (BE (result < 0, 0))            if (BE (! ok, 0))
3670              goto error_return;              goto error_return;
3671    
3672            /* If all characters are consumed, go to next node. */            /* If all characters are consumed, go to next node. */
# Line 3695  group_nodes_into_DFAstates (dfa, state, Line 3688  group_nodes_into_DFAstates (dfa, state,
3688   error_return:   error_return:
3689    for (j = 0; j < ndests; ++j)    for (j = 0; j < ndests; ++j)
3690      re_node_set_free (dests_node + j);      re_node_set_free (dests_node + j);
3691    return -1;    return REG_MISSING;
3692  }  }
3693    
3694  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
# Line 3708  group_nodes_into_DFAstates (dfa, state, Line 3701  group_nodes_into_DFAstates (dfa, state,
3701     can only accept one byte.  */     can only accept one byte.  */
3702    
3703  static int  static int
3704  check_node_accept_bytes (dfa, node_idx, input, str_idx)  internal_function
3705      re_dfa_t *dfa;  check_node_accept_bytes (re_dfa_t *dfa, Idx node_idx,
3706      int node_idx, str_idx;                           const re_string_t *input, Idx str_idx)
     const re_string_t *input;  
3707  {  {
3708    const re_token_t *node = dfa->nodes + node_idx;    const re_token_t *node = dfa->nodes + node_idx;
3709    int char_len, elem_len;    int char_len, elem_len;
3710    int i;    Idx i;
3711    
3712    if (BE (node->type == OP_UTF8_PERIOD, 0))    if (BE (node->type == OP_UTF8_PERIOD, 0))
3713      {      {
# Line 3776  check_node_accept_bytes (dfa, node_idx, Line 3768  check_node_accept_bytes (dfa, node_idx,
3768        /* FIXME: I don't think this if is needed, as both '\n'        /* FIXME: I don't think this if is needed, as both '\n'
3769           and '\0' are char_len == 1.  */           and '\0' are char_len == 1.  */
3770        /* '.' accepts any one character except the following two cases.  */        /* '.' accepts any one character except the following two cases.  */
3771        if ((!(dfa->syntax & RE_DOT_NEWLINE) &&        if ((!(dfa->syntax & REG_DOT_NEWLINE) &&
3772             re_string_byte_at (input, str_idx) == '\n') ||             re_string_byte_at (input, str_idx) == '\n') ||
3773            ((dfa->syntax & RE_DOT_NOT_NULL) &&            ((dfa->syntax & REG_DOT_NOT_NULL) &&
3774             re_string_byte_at (input, str_idx) == '\0'))             re_string_byte_at (input, str_idx) == '\0'))
3775          return 0;          return 0;
3776        return char_len;        return char_len;
# Line 3794  check_node_accept_bytes (dfa, node_idx, Line 3786  check_node_accept_bytes (dfa, node_idx,
3786  # ifdef _LIBC  # ifdef _LIBC
3787        const unsigned char *pin        const unsigned char *pin
3788          = ((const unsigned char *) re_string_get_buffer (input) + str_idx);          = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
3789        int j;        Idx j;
3790        uint32_t nrules;        uint32_t nrules;
3791  # endif /* _LIBC */  # endif /* _LIBC */
3792        int match_len = 0;        int match_len = 0;
# Line 3893  check_node_accept_bytes (dfa, node_idx, Line 3885  check_node_accept_bytes (dfa, node_idx,
3885                      size_t weight_len = weights[idx];                      size_t weight_len = weights[idx];
3886                      if (weight_len == weights[equiv_class_idx])                      if (weight_len == weights[equiv_class_idx])
3887                        {                        {
3888                          int cnt = 0;                          Idx cnt = 0;
3889                          while (cnt <= weight_len                          while (cnt <= weight_len
3890                                 && (weights[equiv_class_idx + 1 + cnt]                                 && (weights[equiv_class_idx + 1 + cnt]
3891                                     == weights[idx + 1 + cnt]))                                     == weights[idx + 1 + cnt]))
# Line 3945  check_node_accept_bytes (dfa, node_idx, Line 3937  check_node_accept_bytes (dfa, node_idx,
3937    
3938  # ifdef _LIBC  # ifdef _LIBC
3939  static unsigned int  static unsigned int
3940  find_collation_sequence_value (mbs, mbs_len)  find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
     const unsigned char *mbs;  
     size_t mbs_len;  
3941  {  {
3942    uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);    uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
3943    if (nrules == 0)    if (nrules == 0)
# Line 3971  find_collation_sequence_value (mbs, mbs_ Line 3961  find_collation_sequence_value (mbs, mbs_
3961    
3962        for (idx = 0; idx < extrasize;)        for (idx = 0; idx < extrasize;)
3963          {          {
3964            int mbs_cnt, found = 0;            int mbs_cnt;
3965              bool found = false;
3966            int32_t elem_mbs_len;            int32_t elem_mbs_len;
3967            /* Skip the name of collating element name.  */            /* Skip the name of collating element name.  */
3968            idx = idx + extra[idx] + 1;            idx = idx + extra[idx] + 1;
# Line 3983  find_collation_sequence_value (mbs, mbs_ Line 3974  find_collation_sequence_value (mbs, mbs_
3974                    break;                    break;
3975                if (mbs_cnt == elem_mbs_len)                if (mbs_cnt == elem_mbs_len)
3976                  /* Found the entry.  */                  /* Found the entry.  */
3977                  found = 1;                  found = true;
3978              }              }
3979            /* Skip the byte sequence of the collating element.  */            /* Skip the byte sequence of the collating element.  */
3980            idx += elem_mbs_len;            idx += elem_mbs_len;
# Line 4008  find_collation_sequence_value (mbs, mbs_ Line 3999  find_collation_sequence_value (mbs, mbs_
3999  /* Check whether the node accepts the byte which is IDX-th  /* Check whether the node accepts the byte which is IDX-th
4000     byte of the INPUT.  */     byte of the INPUT.  */
4001    
4002  static int  static bool
4003  check_node_accept (mctx, node, idx)  internal_function
4004      const re_match_context_t *mctx;  check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
4005      const re_token_t *node;                     Idx idx)
     int idx;  
4006  {  {
4007    unsigned char ch;    unsigned char ch;
4008    ch = re_string_byte_at (&mctx->input, idx);    ch = re_string_byte_at (&mctx->input, idx);
# Line 4020  check_node_accept (mctx, node, idx) Line 4010  check_node_accept (mctx, node, idx)
4010      {      {
4011      case CHARACTER:      case CHARACTER:
4012        if (node->opr.c != ch)        if (node->opr.c != ch)
4013          return 0;          return false;
4014        break;        break;
4015    
4016      case SIMPLE_BRACKET:      case SIMPLE_BRACKET:
4017        if (!bitset_contain (node->opr.sbcset, ch))        if (!bitset_contain (node->opr.sbcset, ch))
4018          return 0;          return false;
4019        break;        break;
4020    
4021  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
4022      case OP_UTF8_PERIOD:      case OP_UTF8_PERIOD:
4023        if (ch >= 0x80)        if (ch >= 0x80)
4024          return 0;          return false;
4025        /* FALLTHROUGH */        /* FALLTHROUGH */
4026  #endif  #endif
4027      case OP_PERIOD:      case OP_PERIOD:
4028        if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))        if ((ch == '\n' && !(mctx->dfa->syntax & REG_DOT_NEWLINE))
4029            || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))            || (ch == '\0' && (mctx->dfa->syntax & REG_DOT_NOT_NULL)))
4030          return 0;          return false;
4031        break;        break;
4032    
4033      default:      default:
4034        return 0;        return false;
4035      }      }
4036    
4037    if (node->constraint)    if (node->constraint)
# Line 4051  check_node_accept (mctx, node, idx) Line 4041  check_node_accept (mctx, node, idx)
4041        unsigned int context = re_string_context_at (&mctx->input, idx,        unsigned int context = re_string_context_at (&mctx->input, idx,
4042                                                     mctx->eflags);                                                     mctx->eflags);
4043        if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))        if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
4044          return 0;          return false;
4045      }      }
4046    
4047    return 1;    return true;
4048  }  }
4049    
4050  /* Extend the buffers, if the buffers have run out.  */  /* Extend the buffers, if the buffers have run out.  */
4051    
4052  static reg_errcode_t  static reg_errcode_t
4053  extend_buffers (mctx)  internal_function
4054       re_match_context_t *mctx;  extend_buffers (re_match_context_t *mctx)
4055  {  {
4056    reg_errcode_t ret;    reg_errcode_t ret;
4057    re_string_t *pstr = &mctx->input;    re_string_t *pstr = &mctx->input;
# Line 4077  extend_buffers (mctx) Line 4067  extend_buffers (mctx)
4067        /* XXX We have no indication of the size of this buffer.  If this        /* XXX We have no indication of the size of this buffer.  If this
4068           allocation fail we have no indication that the state_log array           allocation fail we have no indication that the state_log array
4069           does not have the right size.  */           does not have the right size.  */
4070        re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,        re_dfastate_t **new_array = re_xrealloc (mctx->state_log, re_dfastate_t *,
4071                                                pstr->bufs_len + 1);                                                 pstr->bufs_len + 1);
4072        if (BE (new_array == NULL, 0))        if (BE (new_array == NULL, 0))
4073          return REG_ESPACE;          return REG_ESPACE;
4074        mctx->state_log = new_array;        mctx->state_log = new_array;
# Line 4119  extend_buffers (mctx) Line 4109  extend_buffers (mctx)
4109  /* Initialize MCTX.  */  /* Initialize MCTX.  */
4110    
4111  static reg_errcode_t  static reg_errcode_t
4112  match_ctx_init (mctx, eflags, n)  internal_function
4113      re_match_context_t *mctx;  match_ctx_init (re_match_context_t *mctx, int eflags, Idx n)
     int eflags, n;  
4114  {  {
4115    mctx->eflags = eflags;    mctx->eflags = eflags;
4116    mctx->match_last = -1;    mctx->match_last = REG_MISSING;
4117    if (n > 0)    if (n > 0)
4118      {      {
4119        mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);        mctx->bkref_ents = re_xmalloc (struct re_backref_cache_entry, n);
4120        mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);        mctx->sub_tops = re_xmalloc (re_sub_match_top_t *, n);
4121        if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))        if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
4122          return REG_ESPACE;          return REG_ESPACE;
4123      }      }
# Line 4148  match_ctx_init (mctx, eflags, n) Line 4137  match_ctx_init (mctx, eflags, n)
4137     of the input, or changes the input string.  */     of the input, or changes the input string.  */
4138    
4139  static void  static void
4140  match_ctx_clean (mctx)  internal_function
4141      re_match_context_t *mctx;  match_ctx_clean (re_match_context_t *mctx)
4142  {  {
4143    int st_idx;    Idx st_idx;
4144    for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)    for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
4145      {      {
4146        int sl_idx;        Idx sl_idx;
4147        re_sub_match_top_t *top = mctx->sub_tops[st_idx];        re_sub_match_top_t *top = mctx->sub_tops[st_idx];
4148        for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)        for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
4149          {          {
# Line 4178  match_ctx_clean (mctx) Line 4167  match_ctx_clean (mctx)
4167  /* Free all the memory associated with MCTX.  */  /* Free all the memory associated with MCTX.  */
4168    
4169  static void  static void
4170  match_ctx_free (mctx)  internal_function
4171      re_match_context_t *mctx;  match_ctx_free (re_match_context_t *mctx)
4172  {  {
4173    /* First, free all the memory associated with MCTX->SUB_TOPS.  */    /* First, free all the memory associated with MCTX->SUB_TOPS.  */
4174    match_ctx_clean (mctx);    match_ctx_clean (mctx);
# Line 4193  match_ctx_free (mctx) Line 4182  match_ctx_free (mctx)
4182  */  */
4183    
4184  static reg_errcode_t  static reg_errcode_t
4185  match_ctx_add_entry (mctx, node, str_idx, from, to)  internal_function
4186       re_match_context_t *mctx;  match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx,
4187       int node, str_idx, from, to;                       Idx from, Idx to)
4188  {  {
4189    if (mctx->nbkref_ents >= mctx->abkref_ents)    if (mctx->nbkref_ents >= mctx->abkref_ents)
4190      {      {
4191        struct re_backref_cache_entry* new_entry;        struct re_backref_cache_entry* new_entry;
4192        new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,        new_entry = re_x2realloc (mctx->bkref_ents, struct re_backref_cache_entry,
4193                                mctx->abkref_ents * 2);                                  &mctx->abkref_ents);
4194        if (BE (new_entry == NULL, 0))        if (BE (new_entry == NULL, 0))
4195          {          {
4196            re_free (mctx->bkref_ents);            re_free (mctx->bkref_ents);
# Line 4209  match_ctx_add_entry (mctx, node, str_idx Line 4198  match_ctx_add_entry (mctx, node, str_idx
4198          }          }
4199        mctx->bkref_ents = new_entry;        mctx->bkref_ents = new_entry;
4200        memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',        memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
4201                sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);                (sizeof (struct re_backref_cache_entry)
4202        mctx->abkref_ents *= 2;                 * (mctx->abkref_ents - mctx->nbkref_ents)));
4203      }      }
4204    if (mctx->nbkref_ents > 0    if (mctx->nbkref_ents > 0
4205        && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)        && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
# Line 4230  match_ctx_add_entry (mctx, node, str_idx Line 4219  match_ctx_add_entry (mctx, node, str_idx
4219       A backreference does not epsilon-transition unless it is empty, so set       A backreference does not epsilon-transition unless it is empty, so set
4220       to all zeros if FROM != TO.  */       to all zeros if FROM != TO.  */
4221    mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map    mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
4222      = (from == to ? ~0 : 0);      = (from == to ? -1 : 0);
4223    
4224    mctx->bkref_ents[mctx->nbkref_ents++].more = 0;    mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
4225    if (mctx->max_mb_elem_len < to - from)    if (mctx->max_mb_elem_len < to - from)
# Line 4238  match_ctx_add_entry (mctx, node, str_idx Line 4227  match_ctx_add_entry (mctx, node, str_idx
4227    return REG_NOERROR;    return REG_NOERROR;
4228  }  }
4229    
4230  /* Search for the first entry which has the same str_idx, or -1 if none is  /* Return the first entry with the same str_idx, or REG_MISSING if none is
4231     found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */     found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
4232    
4233  static int  static Idx
4234  search_cur_bkref_entry (mctx, str_idx)  internal_function
4235       re_match_context_t *mctx;  search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
      int str_idx;  
4236  {  {
4237    int left, right, mid, last;    Idx left, right, mid, last;
4238    last = right = mctx->nbkref_ents;    last = right = mctx->nbkref_ents;
4239    for (left = 0; left < right;)    for (left = 0; left < right;)
4240      {      {
# Line 4259  search_cur_bkref_entry (mctx, str_idx) Line 4247  search_cur_bkref_entry (mctx, str_idx)
4247    if (left < last && mctx->bkref_ents[left].str_idx == str_idx)    if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
4248      return left;      return left;
4249    else    else
4250      return -1;      return REG_MISSING;
4251  }  }
4252    
4253  /* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches  /* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
4254     at STR_IDX.  */     at STR_IDX.  */
4255    
4256  static reg_errcode_t  static reg_errcode_t
4257  match_ctx_add_subtop (mctx, node, str_idx)  internal_function
4258       re_match_context_t *mctx;  match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
      int node, str_idx;  
4259  {  {
4260  #ifdef DEBUG  #ifdef DEBUG
4261    assert (mctx->sub_tops != NULL);    assert (mctx->sub_tops != NULL);
# Line 4276  match_ctx_add_subtop (mctx, node, str_id Line 4263  match_ctx_add_subtop (mctx, node, str_id
4263  #endif  #endif
4264    if (BE (mctx->nsub_tops == mctx->asub_tops, 0))    if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
4265      {      {
4266        int new_asub_tops = mctx->asub_tops * 2;        Idx new_asub_tops = mctx->asub_tops;
4267        re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,        re_sub_match_top_t **new_array = re_x2realloc (mctx->sub_tops,
4268                                                     re_sub_match_top_t *,                                                       re_sub_match_top_t *,
4269                                                     new_asub_tops);                                                       &new_asub_tops);
4270        if (BE (new_array == NULL, 0))        if (BE (new_array == NULL, 0))
4271          return REG_ESPACE;          return REG_ESPACE;
4272        mctx->sub_tops = new_array;        mctx->sub_tops = new_array;
4273        mctx->asub_tops = new_asub_tops;        mctx->asub_tops = new_asub_tops;
4274      }      }
4275    mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));    mctx->sub_tops[mctx->nsub_tops] = re_calloc (re_sub_match_top_t, 1);
4276    if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))    if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
4277      return REG_ESPACE;      return REG_ESPACE;
4278    mctx->sub_tops[mctx->nsub_tops]->node = node;    mctx->sub_tops[mctx->nsub_tops]->node = node;
# Line 4297  match_ctx_add_subtop (mctx, node, str_id Line 4284  match_ctx_add_subtop (mctx, node, str_id
4284     at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */     at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
4285    
4286  static re_sub_match_last_t *  static re_sub_match_last_t *
4287  match_ctx_add_sublast (subtop, node, str_idx)  internal_function
4288       re_sub_match_top_t *subtop;  match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
      int node, str_idx;  
4289  {  {
4290    re_sub_match_last_t *new_entry;    re_sub_match_last_t *new_entry;
4291    if (BE (subtop->nlasts == subtop->alasts, 0))    if (BE (subtop->nlasts == subtop->alasts, 0))
4292      {      {
4293        int new_alasts = 2 * subtop->alasts + 1;        Idx new_alasts = subtop->alasts;
4294        re_sub_match_last_t **new_array = re_realloc (subtop->lasts,        re_sub_match_last_t **new_array = re_x2realloc (subtop->lasts,
4295                                                      re_sub_match_last_t *,                                                        re_sub_match_last_t *,
4296                                                      new_alasts);                                                        &new_alasts);
4297        if (BE (new_array == NULL, 0))        if (BE (new_array == NULL, 0))
4298          return NULL;          return NULL;
4299        subtop->lasts = new_array;        subtop->lasts = new_array;
4300        subtop->alasts = new_alasts;        subtop->alasts = new_alasts;
4301      }      }
4302    new_entry = calloc (1, sizeof (re_sub_match_last_t));    new_entry = re_calloc (re_sub_match_last_t, 1);
4303    if (BE (new_entry != NULL, 1))    if (BE (new_entry != NULL, 1))
4304      {      {
4305        subtop->lasts[subtop->nlasts] = new_entry;        subtop->lasts[subtop->nlasts] = new_entry;
# Line 4325  match_ctx_add_sublast (subtop, node, str Line 4311  match_ctx_add_sublast (subtop, node, str
4311  }  }
4312    
4313  static void  static void
4314  sift_ctx_init (sctx, sifted_sts, limited_sts, last_node, last_str_idx)  internal_function
4315      re_sift_context_t *sctx;  sift_ctx_init (re_sift_context_t *sctx,
4316      re_dfastate_t **sifted_sts, **limited_sts;                 re_dfastate_t **sifted_sts,
4317      int last_node, last_str_idx;                 re_dfastate_t **limited_sts,
4318                   Idx last_node, Idx last_str_idx)
4319  {  {
4320    sctx->sifted_states = sifted_sts;    sctx->sifted_states = sifted_sts;
4321    sctx->limited_states = limited_sts;    sctx->limited_states = limited_sts;

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