(re_dfa_add_node): Remove the substitutions which became useless.
[kopensolaris-gnu/glibc.git] / posix / regex_internal.c
index 5327c26..69fb9a6 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <wchar.h>
-#include <wctype.h>
+
+#if defined HAVE_WCHAR_H || defined _LIBC
+# include <wchar.h>
+#endif /* HAVE_WCHAR_H || _LIBC */
+#if defined HAVE_WCTYPE_H || defined _LIBC
+# include <wctype.h>
+#endif /* HAVE_WCTYPE_H || _LIBC */
 
 #ifdef _LIBC
 # ifndef _RE_DEFINE_LOCALE_FUNCTIONS
@@ -57,8 +62,8 @@
 #include "regex.h"
 #include "regex_internal.h"
 
-static void re_string_construct_common (const unsigned char *str,
-                                        int len, re_string_t *pstr,
+static void re_string_construct_common (const char *str, int len,
+                                        re_string_t *pstr,
                                         RE_TRANSLATE_TYPE trans, int icase);
 #ifdef RE_ENABLE_I18N
 static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx);
@@ -86,20 +91,21 @@ static unsigned int inline calc_state_hash (const re_node_set *nodes,
 static reg_errcode_t
 re_string_allocate (pstr, str, len, init_len, trans, icase)
      re_string_t *pstr;
-     const unsigned char *str;
+     const char *str;
      int len, init_len, icase;
      RE_TRANSLATE_TYPE trans;
 {
   reg_errcode_t ret;
   int init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
   re_string_construct_common (str, len, pstr, trans, icase);
+  pstr->stop = pstr->len;
 
   ret = re_string_realloc_buffers (pstr, init_buf_len);
   if (BE (ret != REG_NOERROR, 0))
     return ret;
 
   pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
-                    : (unsigned char *)str);
+                    : (unsigned char *) str);
   pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
   pstr->valid_len = (MBS_CASE_ALLOCATED (pstr) || MBS_ALLOCATED (pstr)
                      || MB_CUR_MAX > 1) ? pstr->valid_len : len;
@@ -111,12 +117,13 @@ re_string_allocate (pstr, str, len, init_len, trans, icase)
 static reg_errcode_t
 re_string_construct (pstr, str, len, trans, icase)
      re_string_t *pstr;
-     const unsigned char *str;
+     const char *str;
      int len, icase;
      RE_TRANSLATE_TYPE trans;
 {
   reg_errcode_t ret;
   re_string_construct_common (str, len, pstr, trans, icase);
+  pstr->stop = pstr->len;
   /* Set 0 so that this function can initialize whole buffers.  */
   pstr->valid_len = 0;
 
@@ -127,7 +134,7 @@ re_string_construct (pstr, str, len, trans, icase)
         return ret;
     }
   pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
-                    : (unsigned char *)str);
+                    : (unsigned char *) str);
   pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
 
   if (icase)
@@ -169,7 +176,7 @@ re_string_realloc_buffers (pstr, new_buf_len)
 #ifdef RE_ENABLE_I18N
   if (MB_CUR_MAX > 1)
     {
-      pstr->wcs = re_realloc (pstr->wcs, wchar_t, new_buf_len);
+      pstr->wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
       if (BE (pstr->wcs == NULL, 0))
         return REG_ESPACE;
     }
@@ -195,14 +202,14 @@ re_string_realloc_buffers (pstr, new_buf_len)
 
 static void
 re_string_construct_common (str, len, pstr, trans, icase)
-     const unsigned char *str;
+     const char *str;
      int len;
      re_string_t *pstr;
      RE_TRANSLATE_TYPE trans;
      int icase;
 {
   memset (pstr, '\0', sizeof (re_string_t));
-  pstr->raw_mbs = str;
+  pstr->raw_mbs = (const unsigned char *) str;
   pstr->len = len;
   pstr->trans = trans;
   pstr->icase = icase ? 1 : 0;
@@ -235,8 +242,8 @@ build_wcs_buffer (pstr)
       wchar_t wc;
       remain_len = end_idx - byte_idx;
       prev_st = pstr->cur_state;
-      mbclen = mbrtowc (&wc, pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx,
-                        remain_len, &pstr->cur_state);
+      mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+                              + byte_idx), remain_len, &pstr->cur_state);
       if (BE (mbclen == (size_t) -2, 0))
         {
           /* The buffer doesn't have enough space, finish to build.  */
@@ -254,7 +261,7 @@ build_wcs_buffer (pstr)
       /* Apply the translateion if we need.  */
       if (pstr->trans != NULL && mbclen == 1)
         {
-          int ch =  pstr->trans[pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]];
+          int ch = pstr->trans[pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]];
           pstr->mbs_case[byte_idx] = ch;
         }
       /* Write wide character and padding.  */
@@ -283,8 +290,8 @@ build_wcs_upper_buffer (pstr)
       wchar_t wc;
       remain_len = end_idx - byte_idx;
       prev_st = pstr->cur_state;
-      mbclen = mbrtowc (&wc, pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx,
-                        remain_len, &pstr->cur_state);
+      mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+                              + byte_idx), remain_len, &pstr->cur_state);
       if (BE (mbclen == (size_t) -2, 0))
         {
           /* The buffer doesn't have enough space, finish to build.  */
@@ -309,7 +316,7 @@ build_wcs_upper_buffer (pstr)
       else /* mbclen > 1 */
         {
           if (iswlower (wc))
-            wcrtomb (pstr->mbs + byte_idx, towupper (wc), &prev_st);
+            wcrtomb ((char *) pstr->mbs + byte_idx, towupper (wc), &prev_st);
           else
             memcpy (pstr->mbs + byte_idx,
                     pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
@@ -339,7 +346,7 @@ re_string_skip_chars (pstr, new_raw_idx)
     {
       int remain_len = pstr->len - rawbuf_idx;
       prev_st = pstr->cur_state;
-      mbclen = mbrlen (pstr->raw_mbs + rawbuf_idx, remain_len,
+      mbclen = mbrlen ((const char *) pstr->raw_mbs + rawbuf_idx, remain_len,
                        &pstr->cur_state);
       if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
         {
@@ -415,13 +422,15 @@ re_string_reconstruct (pstr, idx, eflags, newline)
       if (MB_CUR_MAX > 1)
         memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
 #endif /* RE_ENABLE_I18N */
+      pstr->len += pstr->raw_mbs_idx;
+      pstr->stop += pstr->raw_mbs_idx;
       pstr->valid_len = pstr->raw_mbs_idx = 0;
       pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
                            : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
       if (!MBS_CASE_ALLOCATED (pstr))
-        pstr->mbs_case = (unsigned char *)pstr->raw_mbs;
+        pstr->mbs_case = (unsigned char *) pstr->raw_mbs;
       if (!MBS_ALLOCATED (pstr) && !MBS_CASE_ALLOCATED (pstr))
-        pstr->mbs = (unsigned char *)pstr->raw_mbs;
+        pstr->mbs = (unsigned char *) pstr->raw_mbs;
       offset = idx;
     }
 
@@ -436,7 +445,7 @@ re_string_reconstruct (pstr, idx, eflags, newline)
 #ifdef RE_ENABLE_I18N
           if (MB_CUR_MAX > 1)
             memmove (pstr->wcs, pstr->wcs + offset,
-                     (pstr->valid_len - offset) * sizeof (wchar_t));
+                     (pstr->valid_len - offset) * sizeof (wint_t));
 #endif /* RE_ENABLE_I18N */
           if (MBS_ALLOCATED (pstr))
             memmove (pstr->mbs, pstr->mbs + offset,
@@ -473,6 +482,7 @@ re_string_reconstruct (pstr, idx, eflags, newline)
     }
   pstr->raw_mbs_idx = idx;
   pstr->len -= offset;
+  pstr->stop -= offset;
 
   /* Then build the buffers.  */
 #ifdef RE_ENABLE_I18N
@@ -612,50 +622,6 @@ re_node_set_init_copy (dest, src)
   return REG_NOERROR;
 }
 
-/* Calculate the intersection of the sets SRC1 and SRC2. And store it in
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
-   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
-
-static reg_errcode_t
-re_node_set_intersect (dest, src1, src2)
-     re_node_set *dest;
-     const re_node_set *src1, *src2;
-{
-  int i1, i2, id;
-  if (src1->nelem > 0 && src2->nelem > 0)
-    {
-      if (src1->nelem + src2->nelem > dest->alloc)
-        {
-          dest->alloc = src1->nelem + src2->nelem;
-          dest->elems = re_realloc (dest->elems, int, dest->alloc);
-          if (BE (dest->elems == NULL, 0))
-            return REG_ESPACE;
-        }
-    }
-  else
-    {
-      /* The intersection of empty sets is also empty set.  */
-      dest->nelem = 0;
-      return REG_NOERROR;
-    }
-
-  for (i1 = i2 = id = 0; i1 < src1->nelem && i2 < src2->nelem; )
-    {
-      if (src1->elems[i1] > src2->elems[i2])
-        {
-          ++i2;
-          continue;
-        }
-      /* The intersection must have the elements which are in both of
-         SRC1 and SRC2.  */
-      if (src1->elems[i1] == src2->elems[i2])
-        dest->elems[id++] = src2->elems[i2++];
-      ++i1;
-    }
-  dest->nelem = id;
-  return REG_NOERROR;
-}
-
 /* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
    DEST. Return value indicate the error code or REG_NOERROR if succeeded.
    Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
@@ -904,7 +870,7 @@ re_node_set_compare (set1, set2)
   return 1;
 }
 
-/* Return 1 if SET contains the element ELEM, return 0 otherwise.  */
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
 
 static int
 re_node_set_contains (set, elem)
@@ -926,7 +892,7 @@ re_node_set_contains (set, elem)
       else
         right = mid;
     }
-  return set->elems[idx] == elem;
+  return set->elems[idx] == elem ? idx + 1 : 0;
 }
 
 static void
@@ -963,20 +929,18 @@ re_dfa_add_node (dfa, token, mode)
         dfa->nodes = new_array;
       if (mode)
         {
-          int *new_firsts, *new_nexts;
+          int *new_nexts;
           re_node_set *new_edests, *new_eclosures, *new_inveclosures;
 
-          new_firsts = re_realloc (dfa->firsts, int, dfa->nodes_alloc);
           new_nexts = re_realloc (dfa->nexts, int, dfa->nodes_alloc);
           new_edests = re_realloc (dfa->edests, re_node_set, dfa->nodes_alloc);
           new_eclosures = re_realloc (dfa->eclosures, re_node_set,
                                       dfa->nodes_alloc);
           new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
                                          dfa->nodes_alloc);
-          if (BE (new_firsts == NULL || new_nexts == NULL || new_edests == NULL
+          if (BE (new_nexts == NULL || new_edests == NULL
                   || new_eclosures == NULL || new_inveclosures == NULL, 0))
             return -1;
-          dfa->firsts = new_firsts;
           dfa->nexts = new_nexts;
           dfa->edests = new_edests;
           dfa->eclosures = new_eclosures;
@@ -985,6 +949,7 @@ re_dfa_add_node (dfa, token, mode)
     }
   dfa->nodes[dfa->nodes_len] = token;
   dfa->nodes[dfa->nodes_len].duplicated = 0;
+  dfa->nodes[dfa->nodes_len].constraint = 0;
   return dfa->nodes_len++;
 }
 
@@ -1160,24 +1125,21 @@ create_ci_newstate (dfa, nodes, hash)
     {
       re_token_t *node = dfa->nodes + nodes->elems[i];
       re_token_type_t type = node->type;
-      if (type == CHARACTER)
+      if (type == CHARACTER && !node->constraint)
         continue;
 
       /* If the state has the halt node, the state is a halt state.  */
       else if (type == END_OF_RE)
         newstate->halt = 1;
+#ifdef RE_ENABLE_I18N
       else if (type == COMPLEX_BRACKET
                || (type == OP_PERIOD && MB_CUR_MAX > 1))
         newstate->accept_mb = 1;
+#endif /* RE_ENABLE_I18N */
       else if (type == OP_BACK_REF)
         newstate->has_backref = 1;
-      else if (type == ANCHOR || OP_CONTEXT_NODE)
-        {
-          newstate->has_constraint = 1;
-          if (type == OP_CONTEXT_NODE
-              && dfa->nodes[node->opr.ctx_info->entity].type == END_OF_RE)
-            newstate->halt = 1;
-        }
+      else if (type == ANCHOR || node->constraint)
+        newstate->has_constraint = 1;
     }
   err = register_state (dfa, newstate, hash);
   return (err != REG_NOERROR) ? NULL : newstate;
@@ -1207,31 +1169,23 @@ create_cd_newstate (dfa, nodes, context, hash)
       unsigned int constraint = 0;
       re_token_t *node = dfa->nodes + nodes->elems[i];
       re_token_type_t type = node->type;
-      if (type == CHARACTER)
-        continue;
+      if (node->constraint)
+        constraint = node->constraint;
 
+      if (type == CHARACTER && !constraint)
+        continue;
       /* If the state has the halt node, the state is a halt state.  */
       else if (type == END_OF_RE)
         newstate->halt = 1;
+#ifdef RE_ENABLE_I18N
       else if (type == COMPLEX_BRACKET
                || (type == OP_PERIOD && MB_CUR_MAX > 1))
         newstate->accept_mb = 1;
+#endif /* RE_ENABLE_I18N */
       else if (type == OP_BACK_REF)
         newstate->has_backref = 1;
       else if (type == ANCHOR)
         constraint = node->opr.ctx_type;
-      else if (type == OP_CONTEXT_NODE)
-        {
-          re_token_type_t ctype = dfa->nodes[node->opr.ctx_info->entity].type;
-          constraint = node->constraint;
-          if (ctype == END_OF_RE)
-            newstate->halt = 1;
-          else if (ctype == OP_BACK_REF)
-            newstate->has_backref = 1;
-          else if (ctype == COMPLEX_BRACKET
-                   || (type == OP_PERIOD && MB_CUR_MAX > 1))
-            newstate->accept_mb = 1;
-        }
 
       if (constraint)
         {