/[inetutils]/inetutils/lib/regex_internal.c
ViewVC logotype

Diff of /inetutils/lib/regex_internal.c

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

revision 1.1 by gray, Sun Jul 31 20:14:08 2005 UTC revision 1.2 by ams, Fri Dec 2 14:00:00 2005 UTC
# Line 17  Line 17 
17     with this program; if not, write to the Free Software Foundation,     with this program; if not, write to the Free Software Foundation,
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 void re_string_construct_common (const char *str, int len,  static void re_string_construct_common (const char *str, Idx len,
21                                          re_string_t *pstr,                                          re_string_t *pstr,
22                                          RE_TRANSLATE_TYPE trans, int icase,                                          REG_TRANSLATE_TYPE trans, bool icase,
23                                          const re_dfa_t *dfa) internal_function;                                          const re_dfa_t *dfa) internal_function;
24  #ifdef RE_ENABLE_I18N  static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
 static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx,  
                                  wint_t *last_wc) internal_function;  
 #endif /* RE_ENABLE_I18N */  
 static reg_errcode_t register_state (re_dfa_t *dfa, re_dfastate_t *newstate,  
                                      unsigned int hash) internal_function;  
 static re_dfastate_t *create_ci_newstate (re_dfa_t *dfa,  
25                                            const re_node_set *nodes,                                            const re_node_set *nodes,
26                                            unsigned int hash) internal_function;                                            re_hashval_t hash) internal_function;
27  static re_dfastate_t *create_cd_newstate (re_dfa_t *dfa,  static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
28                                            const re_node_set *nodes,                                            const re_node_set *nodes,
29                                            unsigned int context,                                            unsigned int context,
30                                            unsigned int hash) internal_function;                                            re_hashval_t hash) internal_function;
 static unsigned int inline calc_state_hash (const re_node_set *nodes,  
                                             unsigned int context) internal_function;  
31    
32  /* Functions for string operation.  */  /* Functions for string operation.  */
33    
# Line 43  static unsigned int inline calc_state_ha Line 35  static unsigned int inline calc_state_ha
35     re_string_reconstruct before using the object.  */     re_string_reconstruct before using the object.  */
36    
37  static reg_errcode_t  static reg_errcode_t
38  re_string_allocate (pstr, str, len, init_len, trans, icase, dfa)  internal_function
39       re_string_t *pstr;  re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
40       const char *str;                      REG_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
      int len, init_len, icase;  
      RE_TRANSLATE_TYPE trans;  
      const re_dfa_t *dfa;  
41  {  {
42    reg_errcode_t ret;    reg_errcode_t ret;
43    int init_buf_len;    Idx init_buf_len;
44    
45    /* Ensure at least one character fits into the buffers.  */    /* Ensure at least one character fits into the buffers.  */
46    if (init_len < dfa->mb_cur_max)    if (init_len < dfa->mb_cur_max)
# Line 74  re_string_allocate (pstr, str, len, init Line 63  re_string_allocate (pstr, str, len, init
63  /* This function allocate the buffers, and initialize them.  */  /* This function allocate the buffers, and initialize them.  */
64    
65  static reg_errcode_t  static reg_errcode_t
66  re_string_construct (pstr, str, len, trans, icase, dfa)  internal_function
67       re_string_t *pstr;  re_string_construct (re_string_t *pstr, const char *str, Idx len,
68       const char *str;                       REG_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
      int len, icase;  
      RE_TRANSLATE_TYPE trans;  
      const re_dfa_t *dfa;  
69  {  {
70    reg_errcode_t ret;    reg_errcode_t ret;
71    memset (pstr, '\0', sizeof (re_string_t));    memset (pstr, '\0', sizeof (re_string_t));
# Line 140  re_string_construct (pstr, str, len, tra Line 126  re_string_construct (pstr, str, len, tra
126  /* Helper functions for re_string_allocate, and re_string_construct.  */  /* Helper functions for re_string_allocate, and re_string_construct.  */
127    
128  static reg_errcode_t  static reg_errcode_t
129  re_string_realloc_buffers (pstr, new_buf_len)  internal_function
130       re_string_t *pstr;  re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
      int new_buf_len;  
131  {  {
132  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
133    if (pstr->mb_cur_max > 1)    if (pstr->mb_cur_max > 1)
134      {      {
135        wint_t *new_array = re_realloc (pstr->wcs, wint_t, new_buf_len);        wint_t *new_wcs = re_xrealloc (pstr->wcs, wint_t, new_buf_len);
136        if (BE (new_array == NULL, 0))        if (BE (new_wcs == NULL, 0))
137          return REG_ESPACE;          return REG_ESPACE;
138        pstr->wcs = new_array;        pstr->wcs = new_wcs;
139        if (pstr->offsets != NULL)        if (pstr->offsets != NULL)
140          {          {
141            int *new_array = re_realloc (pstr->offsets, int, new_buf_len);            Idx *new_offsets = re_xrealloc (pstr->offsets, Idx, new_buf_len);
142            if (BE (new_array == NULL, 0))            if (BE (new_offsets == NULL, 0))
143              return REG_ESPACE;              return REG_ESPACE;
144            pstr->offsets = new_array;            pstr->offsets = new_offsets;
145          }          }
146      }      }
147  #endif /* RE_ENABLE_I18N  */  #endif /* RE_ENABLE_I18N  */
148    if (pstr->mbs_allocated)    if (pstr->mbs_allocated)
149      {      {
150        unsigned char *new_array = re_realloc (pstr->mbs, unsigned char,        unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
151                                               new_buf_len);                                             new_buf_len);
152        if (BE (new_array == NULL, 0))        if (BE (new_mbs == NULL, 0))
153          return REG_ESPACE;          return REG_ESPACE;
154        pstr->mbs = new_array;        pstr->mbs = new_mbs;
155      }      }
156    pstr->bufs_len = new_buf_len;    pstr->bufs_len = new_buf_len;
157    return REG_NOERROR;    return REG_NOERROR;
# Line 174  re_string_realloc_buffers (pstr, new_buf Line 159  re_string_realloc_buffers (pstr, new_buf
159    
160    
161  static void  static void
162  re_string_construct_common (str, len, pstr, trans, icase, dfa)  internal_function
163       const char *str;  re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
164       int len;                              REG_TRANSLATE_TYPE trans, bool icase,
165       re_string_t *pstr;                              const re_dfa_t *dfa)
      RE_TRANSLATE_TYPE trans;  
      int icase;  
      const re_dfa_t *dfa;  
166  {  {
167    pstr->raw_mbs = (const unsigned char *) str;    pstr->raw_mbs = (const unsigned char *) str;
168    pstr->len = len;    pstr->len = len;
169    pstr->raw_len = len;    pstr->raw_len = len;
170    pstr->trans = (unsigned RE_TRANSLATE_TYPE) trans;    pstr->trans = (unsigned REG_TRANSLATE_TYPE) trans;
171    pstr->icase = icase ? 1 : 0;    pstr->icase = icase;
172    pstr->mbs_allocated = (trans != NULL || icase);    pstr->mbs_allocated = (trans != NULL || icase);
173    pstr->mb_cur_max = dfa->mb_cur_max;    pstr->mb_cur_max = dfa->mb_cur_max;
174    pstr->is_utf8 = dfa->is_utf8;    pstr->is_utf8 = dfa->is_utf8;
# Line 209  re_string_construct_common (str, len, ps Line 191  re_string_construct_common (str, len, ps
191     built and starts from PSTR->VALID_LEN.  */     built and starts from PSTR->VALID_LEN.  */
192    
193  static void  static void
194  build_wcs_buffer (pstr)  internal_function
195       re_string_t *pstr;  build_wcs_buffer (re_string_t *pstr)
196  {  {
197  #ifdef _LIBC  #ifdef _LIBC
198    unsigned char buf[MB_LEN_MAX];    unsigned char buf[MB_LEN_MAX];
# Line 219  build_wcs_buffer (pstr) Line 201  build_wcs_buffer (pstr)
201    unsigned char buf[64];    unsigned char buf[64];
202  #endif  #endif
203    mbstate_t prev_st;    mbstate_t prev_st;
204    int byte_idx, end_idx, remain_len;    Idx byte_idx, end_idx, remain_len;
205    size_t mbclen;    size_t mbclen;
206    
207    /* Build the buffers from pstr->valid_len to either pstr->len or    /* Build the buffers from pstr->valid_len to either pstr->len or
# Line 276  build_wcs_buffer (pstr) Line 258  build_wcs_buffer (pstr)
258  /* Build wide character buffer PSTR->WCS like build_wcs_buffer,  /* Build wide character buffer PSTR->WCS like build_wcs_buffer,
259     but for REG_ICASE.  */     but for REG_ICASE.  */
260    
261  static int  static reg_errcode_t
262  build_wcs_upper_buffer (pstr)  internal_function
263       re_string_t *pstr;  build_wcs_upper_buffer (re_string_t *pstr)
264  {  {
265    mbstate_t prev_st;    mbstate_t prev_st;
266    int src_idx, byte_idx, end_idx, remain_len;    Idx src_idx, byte_idx, end_idx, remain_len;
267    size_t mbclen;    size_t mbclen;
268  #ifdef _LIBC  #ifdef _LIBC
269    char buf[MB_LEN_MAX];    char buf[MB_LEN_MAX];
# Line 319  build_wcs_upper_buffer (pstr) Line 301  build_wcs_upper_buffer (pstr)
301            mbclen = mbrtowc (&wc,            mbclen = mbrtowc (&wc,
302                              ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx                              ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
303                               + byte_idx), remain_len, &pstr->cur_state);                               + byte_idx), remain_len, &pstr->cur_state);
304            if (BE (mbclen + 2 > 2, 1))            if (BE ((size_t) (mbclen + 2) > 2, 1))
305              {              {
306                wchar_t wcu = wc;                wchar_t wcu = wc;
307                if (iswlower (wc))                if (iswlower (wc))
# Line 387  build_wcs_upper_buffer (pstr) Line 369  build_wcs_upper_buffer (pstr)
369          else          else
370            p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;            p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
371          mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);          mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);
372          if (BE (mbclen + 2 > 2, 1))          if (BE ((size_t) (mbclen + 2) > 2, 1))
373            {            {
374              wchar_t wcu = wc;              wchar_t wcu = wc;
375              if (iswlower (wc))              if (iswlower (wc))
# Line 410  build_wcs_upper_buffer (pstr) Line 392  build_wcs_upper_buffer (pstr)
392    
393                      if (pstr->offsets == NULL)                      if (pstr->offsets == NULL)
394                        {                        {
395                          pstr->offsets = re_malloc (int, pstr->bufs_len);                          pstr->offsets = re_xmalloc (Idx, pstr->bufs_len);
396    
397                          if (pstr->offsets == NULL)                          if (pstr->offsets == NULL)
398                            return REG_ESPACE;                            return REG_ESPACE;
# Line 492  build_wcs_upper_buffer (pstr) Line 474  build_wcs_upper_buffer (pstr)
474  /* Skip characters until the index becomes greater than NEW_RAW_IDX.  /* Skip characters until the index becomes greater than NEW_RAW_IDX.
475     Return the index.  */     Return the index.  */
476    
477  static int  static Idx
478  re_string_skip_chars (pstr, new_raw_idx, last_wc)  internal_function
479       re_string_t *pstr;  re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
      int new_raw_idx;  
      wint_t *last_wc;  
480  {  {
481    mbstate_t prev_st;    mbstate_t prev_st;
482    int rawbuf_idx;    Idx rawbuf_idx;
483    size_t mbclen;    size_t mbclen;
484    wchar_t wc = 0;    wchar_t wc = 0;
485    
# Line 507  re_string_skip_chars (pstr, new_raw_idx, Line 487  re_string_skip_chars (pstr, new_raw_idx,
487    for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;    for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
488         rawbuf_idx < new_raw_idx;)         rawbuf_idx < new_raw_idx;)
489      {      {
490        int remain_len;        Idx remain_len;
491        remain_len = pstr->len - rawbuf_idx;        remain_len = pstr->len - rawbuf_idx;
492        prev_st = pstr->cur_state;        prev_st = pstr->cur_state;
493        mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,        mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
# Line 530  re_string_skip_chars (pstr, new_raw_idx, Line 510  re_string_skip_chars (pstr, new_raw_idx,
510     This function is used in case of REG_ICASE.  */     This function is used in case of REG_ICASE.  */
511    
512  static void  static void
513  build_upper_buffer (pstr)  internal_function
514       re_string_t *pstr;  build_upper_buffer (re_string_t *pstr)
515  {  {
516    int char_idx, end_idx;    Idx char_idx, end_idx;
517    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
518    
519    for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)    for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
# Line 553  build_upper_buffer (pstr) Line 533  build_upper_buffer (pstr)
533  /* Apply TRANS to the buffer in PSTR.  */  /* Apply TRANS to the buffer in PSTR.  */
534    
535  static void  static void
536  re_string_translate_buffer (pstr)  internal_function
537       re_string_t *pstr;  re_string_translate_buffer (re_string_t *pstr)
538  {  {
539    int buf_idx, end_idx;    Idx buf_idx, end_idx;
540    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
541    
542    for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)    for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
# Line 574  re_string_translate_buffer (pstr) Line 554  re_string_translate_buffer (pstr)
554     convert to upper case in case of REG_ICASE, apply translation.  */     convert to upper case in case of REG_ICASE, apply translation.  */
555    
556  static reg_errcode_t  static reg_errcode_t
557  re_string_reconstruct (pstr, idx, eflags)  internal_function
558       re_string_t *pstr;  re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
      int idx, eflags;  
559  {  {
560    int offset = idx - pstr->raw_mbs_idx;    Idx offset;
561    if (BE (offset < 0, 0))  
562      if (BE (pstr->raw_mbs_idx <= idx, 0))
563        offset = idx - pstr->raw_mbs_idx;
564      else
565      {      {
566        /* Reset buffer.  */        /* Reset buffer.  */
567  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
# Line 642  re_string_reconstruct (pstr, idx, eflags Line 624  re_string_reconstruct (pstr, idx, eflags
624  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
625            if (pstr->mb_cur_max > 1)            if (pstr->mb_cur_max > 1)
626              {              {
627                int wcs_idx;                Idx wcs_idx;
628                wint_t wc = WEOF;                wint_t wc = WEOF;
629    
630                if (pstr->is_utf8)                if (pstr->is_utf8)
# Line 658  re_string_reconstruct (pstr, idx, eflags Line 640  re_string_reconstruct (pstr, idx, eflags
640                        {                        {
641                          mbstate_t cur_state;                          mbstate_t cur_state;
642                          wchar_t wc2;                          wchar_t wc2;
643                          int mlen = raw + pstr->len - p;                          Idx mlen = raw + pstr->len - p;
644                          unsigned char buf[6];                          unsigned char buf[6];
645                            size_t mbclen;
646    
647                          q = p;                          q = p;
648                          if (BE (pstr->trans != NULL, 0))                          if (BE (pstr->trans != NULL, 0))
# Line 672  re_string_reconstruct (pstr, idx, eflags Line 655  re_string_reconstruct (pstr, idx, eflags
655                          /* XXX Don't use mbrtowc, we know which conversion                          /* XXX Don't use mbrtowc, we know which conversion
656                             to use (UTF-8 -> UCS4).  */                             to use (UTF-8 -> UCS4).  */
657                          memset (&cur_state, 0, sizeof (cur_state));                          memset (&cur_state, 0, sizeof (cur_state));
658                          mlen = (mbrtowc (&wc2, (const char *) p, mlen,                          mbclen = mbrtowc (&wc2, (const char *) p, mlen,
659                                           &cur_state)                                            &cur_state);
660                                  - (raw + offset - p));                          if (raw + offset - p <= mbclen && mbclen < (size_t) -2)
                         if (mlen >= 0)  
661                            {                            {
662                              memset (&pstr->cur_state, '\0',                              memset (&pstr->cur_state, '\0',
663                                      sizeof (mbstate_t));                                      sizeof (mbstate_t));
664                              pstr->valid_len = mlen;                              pstr->valid_len = mbclen - (raw + offset - p);
665                              wc = wc2;                              wc = wc2;
666                            }                            }
667                          break;                          break;
# Line 693  re_string_reconstruct (pstr, idx, eflags Line 675  re_string_reconstruct (pstr, idx, eflags
675                    for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)                    for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
676                      pstr->wcs[wcs_idx] = WEOF;                      pstr->wcs[wcs_idx] = WEOF;
677                    if (pstr->mbs_allocated)                    if (pstr->mbs_allocated)
678                      memset (pstr->mbs, 255, pstr->valid_len);                      memset (pstr->mbs, -1, pstr->valid_len);
679                  }                  }
680                pstr->valid_raw_len = pstr->valid_len;                pstr->valid_raw_len = pstr->valid_len;
681                pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)                pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
# Line 728  re_string_reconstruct (pstr, idx, eflags Line 710  re_string_reconstruct (pstr, idx, eflags
710      {      {
711        if (pstr->icase)        if (pstr->icase)
712          {          {
713            int ret = build_wcs_upper_buffer (pstr);            reg_errcode_t ret = build_wcs_upper_buffer (pstr);
714            if (BE (ret != REG_NOERROR, 0))            if (BE (ret != REG_NOERROR, 0))
715              return ret;              return ret;
716          }          }
# Line 752  re_string_reconstruct (pstr, idx, eflags Line 734  re_string_reconstruct (pstr, idx, eflags
734  }  }
735    
736  static unsigned char  static unsigned char
737  re_string_peek_byte_case (pstr, idx)  internal_function __attribute ((pure))
738       const re_string_t *pstr;  re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
      int idx;  
739  {  {
740    int ch, off;    int ch;
741      Idx off;
742    
743    /* Handle the common (easiest) cases first.  */    /* Handle the common (easiest) cases first.  */
744    if (BE (!pstr->mbs_allocated, 1))    if (BE (!pstr->mbs_allocated, 1))
# Line 789  re_string_peek_byte_case (pstr, idx) Line 771  re_string_peek_byte_case (pstr, idx)
771  }  }
772    
773  static unsigned char  static unsigned char
774  re_string_fetch_byte_case (pstr)  internal_function __attribute ((pure))
775       re_string_t *pstr;  re_string_fetch_byte_case (re_string_t *pstr)
776  {  {
777    if (BE (!pstr->mbs_allocated, 1))    if (BE (!pstr->mbs_allocated, 1))
778      return re_string_fetch_byte (pstr);      return re_string_fetch_byte (pstr);
# Line 798  re_string_fetch_byte_case (pstr) Line 780  re_string_fetch_byte_case (pstr)
780  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
781    if (pstr->offsets_needed)    if (pstr->offsets_needed)
782      {      {
783        int off, ch;        Idx off;
784          int ch;
785    
786        /* For tr_TR.UTF-8 [[:islower:]] there is        /* For tr_TR.UTF-8 [[:islower:]] there is
787           [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip           [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
# Line 826  re_string_fetch_byte_case (pstr) Line 809  re_string_fetch_byte_case (pstr)
809  }  }
810    
811  static void  static void
812  re_string_destruct (pstr)  internal_function
813       re_string_t *pstr;  re_string_destruct (re_string_t *pstr)
814  {  {
815  #ifdef RE_ENABLE_I18N  #ifdef RE_ENABLE_I18N
816    re_free (pstr->wcs);    re_free (pstr->wcs);
# Line 840  re_string_destruct (pstr) Line 823  re_string_destruct (pstr)
823  /* Return the context at IDX in INPUT.  */  /* Return the context at IDX in INPUT.  */
824    
825  static unsigned int  static unsigned int
826  re_string_context_at (input, idx, eflags)  internal_function
827       const re_string_t *input;  re_string_context_at (const re_string_t *input, Idx idx, int eflags)
      int idx, eflags;  
828  {  {
829    int c;    int c;
830    if (BE (idx < 0, 0))    if (BE (! REG_VALID_INDEX (idx), 0))
831      /* In this case, we use the value stored in input->tip_context,      /* In this case, we use the value stored in input->tip_context,
832         since we can't know the character in input->mbs[-1] here.  */         since we can't know the character in input->mbs[-1] here.  */
833      return input->tip_context;      return input->tip_context;
# Line 856  re_string_context_at (input, idx, eflags Line 838  re_string_context_at (input, idx, eflags
838    if (input->mb_cur_max > 1)    if (input->mb_cur_max > 1)
839      {      {
840        wint_t wc;        wint_t wc;
841        int wc_idx = idx;        Idx wc_idx = idx;
842        while(input->wcs[wc_idx] == WEOF)        while(input->wcs[wc_idx] == WEOF)
843          {          {
844  #ifdef DEBUG  #ifdef DEBUG
845            /* It must not happen.  */            /* It must not happen.  */
846            assert (wc_idx >= 0);            assert (REG_VALID_INDEX (wc_idx));
847  #endif  #endif
848            --wc_idx;            --wc_idx;
849            if (wc_idx < 0)            if (! REG_VALID_INDEX (wc_idx))
850              return input->tip_context;              return input->tip_context;
851          }          }
852        wc = input->wcs[wc_idx];        wc = input->wcs[wc_idx];
# Line 886  re_string_context_at (input, idx, eflags Line 868  re_string_context_at (input, idx, eflags
868  /* Functions for set operation.  */  /* Functions for set operation.  */
869    
870  static reg_errcode_t  static reg_errcode_t
871  re_node_set_alloc (set, size)  internal_function
872       re_node_set *set;  re_node_set_alloc (re_node_set *set, Idx size)
      int size;  
873  {  {
874    set->alloc = size;    set->alloc = size;
875    set->nelem = 0;    set->nelem = 0;
876    set->elems = re_malloc (int, size);    set->elems = re_xmalloc (Idx, size);
877    if (BE (set->elems == NULL, 0))    if (BE (set->elems == NULL, 0))
878      return REG_ESPACE;      return REG_ESPACE;
879    return REG_NOERROR;    return REG_NOERROR;
880  }  }
881    
882  static reg_errcode_t  static reg_errcode_t
883  re_node_set_init_1 (set, elem)  internal_function
884       re_node_set *set;  re_node_set_init_1 (re_node_set *set, Idx elem)
      int elem;  
885  {  {
886    set->alloc = 1;    set->alloc = 1;
887    set->nelem = 1;    set->nelem = 1;
888    set->elems = re_malloc (int, 1);    set->elems = re_malloc (Idx, 1);
889    if (BE (set->elems == NULL, 0))    if (BE (set->elems == NULL, 0))
890      {      {
891        set->alloc = set->nelem = 0;        set->alloc = set->nelem = 0;
# Line 916  re_node_set_init_1 (set, elem) Line 896  re_node_set_init_1 (set, elem)
896  }  }
897    
898  static reg_errcode_t  static reg_errcode_t
899  re_node_set_init_2 (set, elem1, elem2)  internal_function
900       re_node_set *set;  re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
      int elem1, elem2;  
901  {  {
902    set->alloc = 2;    set->alloc = 2;
903    set->elems = re_malloc (int, 2);    set->elems = re_malloc (Idx, 2);
904    if (BE (set->elems == NULL, 0))    if (BE (set->elems == NULL, 0))
905      return REG_ESPACE;      return REG_ESPACE;
906    if (elem1 == elem2)    if (elem1 == elem2)
# Line 947  re_node_set_init_2 (set, elem1, elem2) Line 926  re_node_set_init_2 (set, elem1, elem2)
926  }  }
927    
928  static reg_errcode_t  static reg_errcode_t
929  re_node_set_init_copy (dest, src)  internal_function
930       re_node_set *dest;  re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
      const re_node_set *src;  
931  {  {
932    dest->nelem = src->nelem;    dest->nelem = src->nelem;
933    if (src->nelem > 0)    if (src->nelem > 0)
934      {      {
935        dest->alloc = dest->nelem;        dest->alloc = dest->nelem;
936        dest->elems = re_malloc (int, dest->alloc);        dest->elems = re_malloc (Idx, dest->alloc);
937        if (BE (dest->elems == NULL, 0))        if (BE (dest->elems == NULL, 0))
938          {          {
939            dest->alloc = dest->nelem = 0;            dest->alloc = dest->nelem = 0;
940            return REG_ESPACE;            return REG_ESPACE;
941          }          }
942        memcpy (dest->elems, src->elems, src->nelem * sizeof (int));        memcpy (dest->elems, src->elems, src->nelem * sizeof dest->elems[0]);
943      }      }
944    else    else
945      re_node_set_init_empty (dest);      re_node_set_init_empty (dest);
# Line 973  re_node_set_init_copy (dest, src) Line 951  re_node_set_init_copy (dest, src)
951     Note: We assume dest->elems is NULL, when dest->alloc is 0.  */     Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
952    
953  static reg_errcode_t  static reg_errcode_t
954  re_node_set_add_intersect (dest, src1, src2)  internal_function
955       re_node_set *dest;  re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
956       const re_node_set *src1, *src2;                             const re_node_set *src2)
957  {  {
958    int i1, i2, is, id, delta, sbase;    Idx i1, i2, is, id, delta, sbase;
959    if (src1->nelem == 0 || src2->nelem == 0)    if (src1->nelem == 0 || src2->nelem == 0)
960      return REG_NOERROR;      return REG_NOERROR;
961    
# Line 985  re_node_set_add_intersect (dest, src1, s Line 963  re_node_set_add_intersect (dest, src1, s
963       conservative estimate.  */       conservative estimate.  */
964    if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)    if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
965      {      {
966        int new_alloc = src1->nelem + src2->nelem + dest->alloc;        Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
967        int *new_elems = re_realloc (dest->elems, int, new_alloc);        Idx *new_elems;
968          if (sizeof (Idx) < 3
969              && (new_alloc < dest->alloc
970                  || ((Idx) (src1->nelem + src2->nelem) < src1->nelem)))
971            return REG_ESPACE;
972          new_elems = re_xrealloc (dest->elems, Idx, new_alloc);
973        if (BE (new_elems == NULL, 0))        if (BE (new_elems == NULL, 0))
974          return REG_ESPACE;          return REG_ESPACE;
975        dest->elems = new_elems;        dest->elems = new_elems;
# Line 1004  re_node_set_add_intersect (dest, src1, s Line 987  re_node_set_add_intersect (dest, src1, s
987        if (src1->elems[i1] == src2->elems[i2])        if (src1->elems[i1] == src2->elems[i2])
988          {          {
989            /* Try to find the item in DEST.  Maybe we could binary search?  */            /* Try to find the item in DEST.  Maybe we could binary search?  */
990            while (id >= 0 && dest->elems[id] > src1->elems[i1])            while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1])
991              --id;              --id;
992    
993            if (id < 0 || dest->elems[id] != src1->elems[i1])            if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1])
994              dest->elems[--sbase] = src1->elems[i1];              dest->elems[--sbase] = src1->elems[i1];
995    
996            if (--i1 < 0 || --i2 < 0)            if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2))
997              break;              break;
998          }          }
999    
1000        /* Lower the highest of the two items.  */        /* Lower the highest of the two items.  */
1001        else if (src1->elems[i1] < src2->elems[i2])        else if (src1->elems[i1] < src2->elems[i2])
1002          {          {
1003            if (--i2 < 0)            if (! REG_VALID_INDEX (--i2))
1004              break;              break;
1005          }          }
1006        else        else
1007          {          {
1008            if (--i1 < 0)            if (! REG_VALID_INDEX (--i1))
1009              break;              break;
1010          }          }
1011      }      }
# Line 1035  re_node_set_add_intersect (dest, src1, s Line 1018  re_node_set_add_intersect (dest, src1, s
1018       DEST elements are already in place; this is more or       DEST elements are already in place; this is more or
1019       less the same loop that is in re_node_set_merge.  */       less the same loop that is in re_node_set_merge.  */
1020    dest->nelem += delta;    dest->nelem += delta;
1021    if (delta > 0 && id >= 0)    if (delta > 0 && REG_VALID_INDEX (id))
1022      for (;;)      for (;;)
1023        {        {
1024          if (dest->elems[is] > dest->elems[id])          if (dest->elems[is] > dest->elems[id])
# Line 1049  re_node_set_add_intersect (dest, src1, s Line 1032  re_node_set_add_intersect (dest, src1, s
1032            {            {
1033              /* Slide from the bottom.  */              /* Slide from the bottom.  */
1034              dest->elems[id + delta] = dest->elems[id];              dest->elems[id + delta] = dest->elems[id];
1035              if (--id < 0)              if (! REG_VALID_INDEX (--id))
1036                break;                break;
1037            }            }
1038        }        }
1039    
1040    /* Copy remaining SRC elements.  */    /* Copy remaining SRC elements.  */
1041    memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int));    memcpy (dest->elems, dest->elems + sbase, delta * sizeof dest->elems[0]);
1042    
1043    return REG_NOERROR;    return REG_NOERROR;
1044  }  }
# Line 1064  re_node_set_add_intersect (dest, src1, s Line 1047  re_node_set_add_intersect (dest, src1, s
1047     DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */     DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
1048    
1049  static reg_errcode_t  static reg_errcode_t
1050  re_node_set_init_union (dest, src1, src2)  internal_function
1051       re_node_set *dest;  re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
1052       const re_node_set *src1, *src2;                          const re_node_set *src2)
1053  {  {
1054    int i1, i2, id;    Idx i1, i2, id;
1055    if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)    if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
1056      {      {
1057        dest->alloc = src1->nelem + src2->nelem;        dest->alloc = src1->nelem + src2->nelem;
1058        dest->elems = re_malloc (int, dest->alloc);        if (sizeof (Idx) < 2 && dest->alloc < src1->nelem)
1059            return REG_ESPACE;
1060          dest->elems = re_xmalloc (Idx, dest->alloc);
1061        if (BE (dest->elems == NULL, 0))        if (BE (dest->elems == NULL, 0))
1062          return REG_ESPACE;          return REG_ESPACE;
1063      }      }
# Line 1100  re_node_set_init_union (dest, src1, src2 Line 1085  re_node_set_init_union (dest, src1, src2
1085    if (i1 < src1->nelem)    if (i1 < src1->nelem)
1086      {      {
1087        memcpy (dest->elems + id, src1->elems + i1,        memcpy (dest->elems + id, src1->elems + i1,
1088               (src1->nelem - i1) * sizeof (int));               (src1->nelem - i1) * sizeof dest->elems[0]);
1089        id += src1->nelem - i1;        id += src1->nelem - i1;
1090      }      }
1091    else if (i2 < src2->nelem)    else if (i2 < src2->nelem)
1092      {      {
1093        memcpy (dest->elems + id, src2->elems + i2,        memcpy (dest->elems + id, src2->elems + i2,
1094               (src2->nelem - i2) * sizeof (int));               (src2->nelem - i2) * sizeof dest->elems[0]);
1095        id += src2->nelem - i2;        id += src2->nelem - i2;
1096      }      }
1097    dest->nelem = id;    dest->nelem = id;
# Line 1117  re_node_set_init_union (dest, src1, src2 Line 1102  re_node_set_init_union (dest, src1, src2
1102     DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */     DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
1103    
1104  static reg_errcode_t  static reg_errcode_t
1105  re_node_set_merge (dest, src)  internal_function
1106       re_node_set *dest;  re_node_set_merge (re_node_set *dest, const re_node_set *src)
      const re_node_set *src;  
1107  {  {
1108    int is, id, sbase, delta;    Idx is, id, sbase, delta;
1109    if (src == NULL || src->nelem == 0)    if (src == NULL || src->nelem == 0)
1110      return REG_NOERROR;      return REG_NOERROR;
1111      if (sizeof (Idx) < 3
1112          && ((Idx) (2 * src->nelem) < src->nelem
1113              || (Idx) (2 * src->nelem + dest->nelem) < dest->nelem))
1114        return REG_ESPACE;
1115    if (dest->alloc < 2 * src->nelem + dest->nelem)    if (dest->alloc < 2 * src->nelem + dest->nelem)
1116      {      {
1117        int new_alloc = 2 * (src->nelem + dest->alloc);        Idx new_alloc = src->nelem + dest->alloc;
1118        int *new_buffer = re_realloc (dest->elems, int, new_alloc);        Idx *new_buffer;
1119          if (sizeof (Idx) < 4 && new_alloc < dest->alloc)
1120            return REG_ESPACE;
1121          new_buffer = re_x2realloc (dest->elems, Idx, &new_alloc);
1122        if (BE (new_buffer == NULL, 0))        if (BE (new_buffer == NULL, 0))
1123          return REG_ESPACE;          return REG_ESPACE;
1124        dest->elems = new_buffer;        dest->elems = new_buffer;
# Line 1137  re_node_set_merge (dest, src) Line 1128  re_node_set_merge (dest, src)
1128    if (BE (dest->nelem == 0, 0))    if (BE (dest->nelem == 0, 0))
1129      {      {
1130        dest->nelem = src->nelem;        dest->nelem = src->nelem;
1131        memcpy (dest->elems, src->elems, src->nelem * sizeof (int));        memcpy (dest->elems, src->elems, src->nelem * sizeof dest->elems[0]);
1132        return REG_NOERROR;        return REG_NOERROR;
1133      }      }
1134    
1135    /* Copy into the top of DEST the items of SRC that are not    /* Copy into the top of DEST the items of SRC that are not
1136       found in DEST.  Maybe we could binary search in DEST?  */       found in DEST.  Maybe we could binary search in DEST?  */
1137    for (sbase = dest->nelem + 2 * src->nelem,    for (sbase = dest->nelem + 2 * src->nelem,
1138         is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; )         is = src->nelem - 1, id = dest->nelem - 1;
1139           REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
1140      {      {
1141        if (dest->elems[id] == src->elems[is])        if (dest->elems[id] == src->elems[is])
1142          is--, id--;          is--, id--;
# Line 1154  re_node_set_merge (dest, src) Line 1146  re_node_set_merge (dest, src)
1146          --id;          --id;
1147      }      }
1148    
1149    if (is >= 0)    if (REG_VALID_INDEX (is))
1150      {      {
1151        /* If DEST is exhausted, the remaining items of SRC must be unique.  */        /* If DEST is exhausted, the remaining items of SRC must be unique.  */
1152        sbase -= is + 1;        sbase -= is + 1;
1153        memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int));        memcpy (dest->elems + sbase, src->elems,
1154                  (is + 1) * sizeof dest->elems[0]);
1155      }      }
1156    
1157    id = dest->nelem - 1;    id = dest->nelem - 1;
# Line 1183  re_node_set_merge (dest, src) Line 1176  re_node_set_merge (dest, src)
1176          {          {
1177            /* Slide from the bottom.  */            /* Slide from the bottom.  */
1178            dest->elems[id + delta] = dest->elems[id];            dest->elems[id + delta] = dest->elems[id];
1179            if (--id < 0)            if (! REG_VALID_INDEX (--id))
1180              {              {
1181                /* Copy remaining SRC elements.  */                /* Copy remaining SRC elements.  */
1182                memcpy (dest->elems, dest->elems + sbase,                memcpy (dest->elems, dest->elems + sbase,
1183                        delta * sizeof (int));                        delta * sizeof dest->elems[0]);
1184                break;                break;
1185              }              }
1186          }          }
# Line 1198  re_node_set_merge (dest, src) Line 1191  re_node_set_merge (dest, src)
1191    
1192  /* Insert the new element ELEM to the re_node_set* SET.  /* Insert the new element ELEM to the re_node_set* SET.
1193     SET should not already have ELEM.     SET should not already have ELEM.
1194     return -1 if an error is occured, return 1 otherwise.  */     Return true if successful.  */
1195    
1196  static int  static bool
1197  re_node_set_insert (set, elem)  internal_function
1198       re_node_set *set;  re_node_set_insert (re_node_set *set, Idx elem)
      int elem;  
1199  {  {
1200    int idx;    Idx idx;
1201    /* In case the set is empty.  */    /* In case the set is empty.  */
1202    if (set->alloc == 0)    if (set->alloc == 0)
1203      {      return re_node_set_init_1 (set, elem) == REG_NOERROR;
       if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))  
         return 1;  
       else  
         return -1;  
     }  
1204    
1205    if (BE (set->nelem, 0) == 0)    if (BE (set->nelem, 0) == 0)
1206      {      {
1207        /* We already guaranteed above that set->alloc != 0.  */        /* We already guaranteed above that set->alloc != 0.  */
1208        set->elems[0] = elem;        set->elems[0] = elem;
1209        ++set->nelem;        ++set->nelem;
1210        return 1;        return true;
1211      }      }
1212    
1213    /* Realloc if we need.  */    /* Realloc if we need.  */
1214    if (set->alloc == set->nelem)    if (set->alloc == set->nelem)
1215      {      {
1216        int *new_array;        Idx *new_elems = re_x2realloc (set->elems, Idx, &set->alloc);
1217        set->alloc = set->alloc * 2;        if (BE (new_elems == NULL, 0))
1218        new_array = re_realloc (set->elems, int, set->alloc);          return false;
1219        if (BE (new_array == NULL, 0))        set->elems = new_elems;
         return -1;  
       set->elems = new_array;  
1220      }      }
1221    
1222    /* Move the elements which follows the new element.  Test the    /* Move the elements which follows the new element.  Test the
# Line 1251  re_node_set_insert (set, elem) Line 1236  re_node_set_insert (set, elem)
1236    /* Insert the new element.  */    /* Insert the new element.  */
1237    set->elems[idx] = elem;    set->elems[idx] = elem;
1238    ++set->nelem;    ++set->nelem;
1239    return 1;    return true;
1240  }  }
1241    
1242  /* Insert the new element ELEM to the re_node_set* SET.  /* Insert the new element ELEM to the re_node_set* SET.
1243     SET should not already have any element greater than or equal to ELEM.     SET should not already have any element greater than or equal to ELEM.
1244     Return -1 if an error is occured, return 1 otherwise.  */     Return true if successful.  */
1245    
1246  static int  static bool
1247  re_node_set_insert_last (set, elem)  internal_function
1248       re_node_set *set;  re_node_set_insert_last (re_node_set *set, Idx elem)
      int elem;  
1249  {  {
1250    /* Realloc if we need.  */    /* Realloc if we need.  */
1251    if (set->alloc == set->nelem)    if (set->alloc == set->nelem)
1252      {      {
1253        int *new_array;        Idx *new_elems;
1254        set->alloc = (set->alloc + 1) * 2;        new_elems = re_x2realloc (set->elems, Idx, &set->alloc);
1255        new_array = re_realloc (set->elems, int, set->alloc);        if (BE (new_elems == NULL, 0))
1256        if (BE (new_array == NULL, 0))          return false;
1257          return -1;        set->elems = new_elems;
       set->elems = new_array;  
1258      }      }
1259    
1260    /* Insert the new element.  */    /* Insert the new element.  */
1261    set->elems[set->nelem++] = elem;    set->elems[set->nelem++] = elem;
1262    return 1;    return true;
1263  }  }
1264    
1265  /* Compare two node sets SET1 and SET2.  /* Compare two node sets SET1 and SET2.
1266     return 1 if SET1 and SET2 are equivalent, return 0 otherwise.  */     Return true if SET1 and SET2 are equivalent.  */
1267    
1268  static int  static bool
1269  re_node_set_compare (set1, set2)  internal_function __attribute ((pure))
1270       const re_node_set *set1, *set2;  re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
1271  {  {
1272    int i;    Idx i;
1273    if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)    if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
1274      return 0;      return false;
1275    for (i = set1->nelem ; --i >= 0 ; )    for (i = set1->nelem ; REG_VALID_INDEX (--i) ; )
1276      if (set1->elems[i] != set2->elems[i])      if (set1->elems[i] != set2->elems[i])
1277        return 0;        return false;
1278    return 1;    return true;
1279  }  }
1280    
1281  /* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */  /* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
1282    
1283  static int  static Idx
1284  re_node_set_contains (set, elem)  internal_function __attribute ((pure))
1285       const re_node_set *set;  re_node_set_contains (const re_node_set *set, Idx elem)
      int elem;  
1286  {  {
1287    unsigned int idx, right, mid;    __re_size_t idx, right, mid;
1288    if (set->nelem <= 0)    if (! REG_VALID_NONZERO_INDEX (set->nelem))
1289      return 0;      return 0;
1290    
1291    /* Binary search the element.  */    /* Binary search the element.  */
# Line 1321  re_node_set_contains (set, elem) Line 1303  re_node_set_contains (set, elem)
1303  }  }
1304    
1305  static void  static void
1306  re_node_set_remove_at (set, idx)  internal_function
1307       re_node_set *set;  re_node_set_remove_at (re_node_set *set, Idx idx)
      int idx;  
1308  {  {
1309    if (idx < 0 || idx >= set->nelem)    if (idx < 0 || idx >= set->nelem)
1310      return;      return;
# Line 1334  re_node_set_remove_at (set, idx) Line 1315  re_node_set_remove_at (set, idx)
1315    
1316    
1317  /* Add the token TOKEN to dfa->nodes, and return the index of the token.  /* Add the token TOKEN to dfa->nodes, and return the index of the token.
1318     Or return -1, if an error will be occured.  */     Or return REG_MISSING if an error occurred.  */
1319    
1320  static int  static Idx
1321  re_dfa_add_node (dfa, token)  internal_function
1322       re_dfa_t *dfa;  re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
      re_token_t token;  
1323  {  {
1324    int type = token.type;    int type = token.type;
1325    if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))    if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
1326      {      {
1327        int new_nodes_alloc = dfa->nodes_alloc * 2;        Idx new_nodes_alloc = dfa->nodes_alloc;
1328        int *new_nexts, *new_indices;        Idx *new_nexts, *new_indices;
1329        re_node_set *new_edests, *new_eclosures;        re_node_set *new_edests, *new_eclosures;
1330    
1331        re_token_t *new_array = re_realloc (dfa->nodes, re_token_t,        re_token_t *new_nodes = re_x2realloc (dfa->nodes, re_token_t,
1332                                            new_nodes_alloc);                                              &new_nodes_alloc);
1333        if (BE (new_array == NULL, 0))        if (BE (new_nodes == NULL, 0))
1334          return -1;          return REG_MISSING;
1335        dfa->nodes = new_array;        dfa->nodes = new_nodes;
1336        new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc);        new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
1337        new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc);        new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
1338        new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);        new_edests = re_xrealloc (dfa->edests, re_node_set, new_nodes_alloc);
1339        new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);        new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
1340        if (BE (new_nexts == NULL || new_indices == NULL        if (BE (new_nexts == NULL || new_indices == NULL
1341                || new_edests == NULL || new_eclosures == NULL, 0))                || new_edests == NULL || new_eclosures == NULL, 0))
1342          return -1;          return REG_MISSING;
1343        dfa->nexts = new_nexts;        dfa->nexts = new_nexts;
1344        dfa->org_indices = new_indices;        dfa->org_indices = new_indices;
1345        dfa->edests = new_edests;        dfa->edests = new_edests;
# Line 1372  re_dfa_add_node (dfa, token) Line 1352  re_dfa_add_node (dfa, token)
1352    dfa->nodes[dfa->nodes_len].accept_mb =    dfa->nodes[dfa->nodes_len].accept_mb =
1353      (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;      (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
1354  #endif  #endif
1355    dfa->nexts[dfa->nodes_len] = -1;    dfa->nexts[dfa->nodes_len] = REG_MISSING;
1356    re_node_set_init_empty (dfa->edests + dfa->nodes_len);    re_node_set_init_empty (dfa->edests + dfa->nodes_len);
1357    re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);    re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
1358    return dfa->nodes_len++;    return dfa->nodes_len++;
1359  }  }
1360    
1361  static unsigned int inline  static inline re_hashval_t
1362  calc_state_hash (nodes, context)  internal_function
1363       const re_node_set *nodes;  calc_state_hash (const re_node_set *nodes, unsigned int context)
      unsigned int context;  
1364  {  {
1365    unsigned int hash = nodes->nelem + context;    re_hashval_t hash = nodes->nelem + context;
1366    int i;    Idx i;
1367    for (i = 0 ; i < nodes->nelem ; i++)    for (i = 0 ; i < nodes->nelem ; i++)
1368      hash += nodes->elems[i];      hash += nodes->elems[i];
1369    return hash;    return hash;
# Line 1400  calc_state_hash (nodes, context) Line 1379  calc_state_hash (nodes, context)
1379             optimization.  */             optimization.  */
1380    
1381  static re_dfastate_t*  static re_dfastate_t*
1382  re_acquire_state (err, dfa, nodes)  internal_function
1383       reg_errcode_t *err;  re_acquire_state (reg_errcode_t *err, re_dfa_t *dfa, const re_node_set *nodes)
      re_dfa_t *dfa;  
      const re_node_set *nodes;  
1384  {  {
1385    unsigned int hash;    re_hashval_t hash;
1386    re_dfastate_t *new_state;    re_dfastate_t *new_state;
1387    struct re_state_table_entry *spot;    struct re_state_table_entry *spot;
1388    int i;    Idx i;
1389    #ifdef lint
1390      /* Suppress bogus uninitialized-variable warnings.  */
1391      *err = REG_NOERROR;
1392    #endif
1393    if (BE (nodes->nelem == 0, 0))    if (BE (nodes->nelem == 0, 0))
1394      {      {
1395        *err = REG_NOERROR;        *err = REG_NOERROR;
# Line 1448  re_acquire_state (err, dfa, nodes) Line 1429  re_acquire_state (err, dfa, nodes)
1429             optimization.  */             optimization.  */
1430    
1431  static re_dfastate_t*  static re_dfastate_t*
1432  re_acquire_state_context (err, dfa, nodes, context)  internal_function
1433       reg_errcode_t *err;  re_acquire_state_context (reg_errcode_t *err, re_dfa_t *dfa,
1434       re_dfa_t *dfa;                            const re_node_set *nodes, unsigned int context)
      const re_node_set *nodes;  
      unsigned int context;  
1435  {  {
1436    unsigned int hash;    re_hashval_t hash;
1437    re_dfastate_t *new_state;    re_dfastate_t *new_state;
1438    struct re_state_table_entry *spot;    struct re_state_table_entry *spot;
1439    int i;    Idx i;
1440    #ifdef lint
1441      /* Suppress bogus uninitialized-variable warnings.  */
1442      *err = REG_NOERROR;
1443    #endif
1444    if (nodes->nelem == 0)    if (nodes->nelem == 0)
1445      {      {
1446        *err = REG_NOERROR;        *err = REG_NOERROR;
# Line 1490  re_acquire_state_context (err, dfa, node Line 1473  re_acquire_state_context (err, dfa, node
1473     indicates the error code if failed.  */     indicates the error code if failed.  */
1474    
1475  static reg_errcode_t  static reg_errcode_t
1476  register_state (dfa, newstate, hash)  internal_function
1477       re_dfa_t *dfa;  register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, re_hashval_t hash)
      re_dfastate_t *newstate;  
      unsigned int hash;  
1478  {  {
1479    struct re_state_table_entry *spot;    struct re_state_table_entry *spot;
1480    reg_errcode_t err;    reg_errcode_t err;
1481    int i;    Idx i;
1482    
1483    newstate->hash = hash;    newstate->hash = hash;
1484    err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);    err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
# Line 1505  register_state (dfa, newstate, hash) Line 1486  register_state (dfa, newstate, hash)
1486      return REG_ESPACE;      return REG_ESPACE;
1487    for (i = 0; i < newstate->nodes.nelem; i++)    for (i = 0; i < newstate->nodes.nelem; i++)
1488      {      {
1489        int elem = newstate->nodes.elems[i];        Idx elem = newstate->nodes.elems[i];
1490        if (!IS_EPSILON_NODE (dfa->nodes[elem].type))        if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
1491          re_node_set_insert_last (&newstate->non_eps_nodes, elem);          {
1492              bool ok = re_node_set_insert_last (&newstate->non_eps_nodes, elem);
1493              if (BE (! ok, 0))
1494                return REG_ESPACE;
1495            }
1496      }      }
1497    
1498    spot = dfa->state_table + (hash & dfa->state_hash_mask);    spot = dfa->state_table + (hash & dfa->state_hash_mask);
1499    if (BE (spot->alloc <= spot->num, 0))    if (BE (spot->alloc <= spot->num, 0))
1500      {      {
1501        int new_alloc = 2 * spot->num + 2;        Idx new_alloc = spot->num;
1502        re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,        re_dfastate_t **new_array = re_x2realloc (spot->array, re_dfastate_t *,
1503                                                new_alloc);                                                  &new_alloc);
1504        if (BE (new_array == NULL, 0))        if (BE (new_array == NULL, 0))
1505          return REG_ESPACE;          return REG_ESPACE;
1506        spot->array = new_array;        spot->array = new_array;
# Line 1529  register_state (dfa, newstate, hash) Line 1514  register_state (dfa, newstate, hash)
1514     Return the new state if succeeded, otherwise return NULL.  */     Return the new state if succeeded, otherwise return NULL.  */
1515    
1516  static re_dfastate_t *  static re_dfastate_t *
1517  create_ci_newstate (dfa, nodes, hash)  internal_function
1518       re_dfa_t *dfa;  create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1519       const re_node_set *nodes;                      re_hashval_t hash)
      unsigned int hash;  
1520  {  {
1521    int i;    Idx i;
1522    reg_errcode_t err;    reg_errcode_t err;
1523    re_dfastate_t *newstate;    re_dfastate_t *newstate;
1524    
1525    newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);    newstate = re_calloc (re_dfastate_t, 1);
1526    if (BE (newstate == NULL, 0))    if (BE (newstate == NULL, 0))
1527      return NULL;      return NULL;
1528    err = re_node_set_init_copy (&newstate->nodes, nodes);    err = re_node_set_init_copy (&newstate->nodes, nodes);
# Line 1580  create_ci_newstate (dfa, nodes, hash) Line 1564  create_ci_newstate (dfa, nodes, hash)
1564     Return the new state if succeeded, otherwise return NULL.  */     Return the new state if succeeded, otherwise return NULL.  */
1565    
1566  static re_dfastate_t *  static re_dfastate_t *
1567  create_cd_newstate (dfa, nodes, context, hash)  internal_function
1568       re_dfa_t *dfa;  create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
1569       const re_node_set *nodes;                      unsigned int context, re_hashval_t hash)
      unsigned int context, hash;  
1570  {  {
1571    int i, nctx_nodes = 0;    Idx i, nctx_nodes = 0;
1572    reg_errcode_t err;    reg_errcode_t err;
1573    re_dfastate_t *newstate;    re_dfastate_t *newstate;
1574    
1575    newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);    newstate = re_calloc (re_dfastate_t, 1);
1576    if (BE (newstate == NULL, 0))    if (BE (newstate == NULL, 0))
1577      return NULL;      return NULL;
1578    err = re_node_set_init_copy (&newstate->nodes, nodes);    err = re_node_set_init_copy (&newstate->nodes, nodes);
# Line 1656  create_cd_newstate (dfa, nodes, context, Line 1639  create_cd_newstate (dfa, nodes, context,
1639  }  }
1640    
1641  static void  static void
1642  free_state (state)  internal_function
1643       re_dfastate_t *state;  free_state (re_dfastate_t *state)
1644  {  {
1645    re_node_set_free (&state->non_eps_nodes);    re_node_set_free (&state->non_eps_nodes);
1646    re_node_set_free (&state->inveclosure);    re_node_set_free (&state->inveclosure);

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