Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-tools / libgrep / regcomp.c
index f0b2e52..01b668b 100644 (file)
@@ -1,5 +1,5 @@
 /* Extended regular expression matching and search library.
-   Copyright (C) 2002-2013 Free Software Foundation, Inc.
+   Copyright (C) 2002-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifdef _LIBC
+# include <locale/weight.h>
+#endif
+
 static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
                                          size_t length, reg_syntax_t syntax);
 static void re_compile_fastmap_iter (regex_t *bufp,
@@ -335,7 +339,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
              memset (&state, '\0', sizeof (state));
              if (__mbrtowc (&wc, (const char *) buf, p - buf,
                             &state) == p - buf
-                 && (__wcrtomb ((char *) buf, towlower (wc), &state)
+                 && (__wcrtomb ((char *) buf, __towlower (wc), &state)
                      != (size_t) -1))
                re_set_fastmap (fastmap, false, buf[0]);
            }
@@ -411,7 +415,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
                    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
                  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
                    {
-                     if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+                     if (__wcrtomb (buf, __towlower (cset->mbchars[i]), &state)
                          != (size_t) -1)
                        re_set_fastmap (fastmap, false, *(unsigned char *) buf);
                    }
@@ -2187,6 +2191,7 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
 {
   re_dfa_t *dfa = preg->buffer;
   bin_tree_t *tree, *branch = NULL;
+  bitset_word_t initial_bkref_map = dfa->completed_bkref_map;
   tree = parse_branch (regexp, preg, token, syntax, nest, err);
   if (BE (*err != REG_NOERROR && tree == NULL, 0))
     return NULL;
@@ -2197,9 +2202,16 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
       if (token->type != OP_ALT && token->type != END_OF_RE
          && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
        {
+         bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map;
+         dfa->completed_bkref_map = initial_bkref_map;
          branch = parse_branch (regexp, preg, token, syntax, nest, err);
          if (BE (*err != REG_NOERROR && branch == NULL, 0))
-           return NULL;
+           {
+             if (tree != NULL)
+               postorder (tree, free_tree, NULL);
+             return NULL;
+           }
+         dfa->completed_bkref_map |= accumulated_bkref_map;
        }
       else
        branch = NULL;
@@ -2460,14 +2472,22 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
   while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
         || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
+      bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token,
+                                          syntax, err);
+      if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+       {
+         if (tree != NULL)
+           postorder (tree, free_tree, NULL);
+         return NULL;
+       }
+      tree = dup_tree;
       /* In BRE consecutive duplications are not allowed.  */
       if ((syntax & RE_CONTEXT_INVALID_DUP)
          && (token->type == OP_DUP_ASTERISK
              || token->type == OP_OPEN_DUP_NUM))
        {
+         if (tree != NULL)
+           postorder (tree, free_tree, NULL);
          *err = REG_BADRPT;
          return NULL;
        }
@@ -2623,6 +2643,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
 
       /* Duplicate ELEM before it is marked optional.  */
       elem = duplicate_tree (elem, dfa);
+      if (BE (elem == NULL, 0))
+        goto parse_dup_op_espace;
       old_tree = tree;
     }
   else
@@ -3161,6 +3183,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
       re_token_t token2;
 
       start_elem.opr.name = start_name_buf;
+      start_elem.type = COLL_SYM;
       ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
                                   syntax, first_round);
       if (BE (ret != REG_NOERROR, 0))
@@ -3204,6 +3227,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
       if (is_range_exp == true)
        {
          end_elem.opr.name = end_name_buf;
+         end_elem.type = COLL_SYM;
          ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
                                       dfa, syntax, true);
          if (BE (ret != REG_NOERROR, 0))
@@ -3478,8 +3502,6 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
       int32_t idx1, idx2;
       unsigned int ch;
       size_t len;
-      /* This #include defines a local function!  */
-# include <locale/weight.h>
       /* Calculate the index for equivalence class.  */
       cp = name;
       table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
@@ -3489,7 +3511,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
                                                   _NL_COLLATE_EXTRAMB);
       indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
                                                _NL_COLLATE_INDIRECTMB);
-      idx1 = findidx (&cp, -1);
+      idx1 = findidx (table, indirect, extra, &cp, -1);
       if (BE (idx1 == 0 || *cp != '\0', 0))
        /* This isn't a valid character.  */
        return REG_ECOLLATE;
@@ -3500,7 +3522,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
        {
          char_buf[0] = ch;
          cp = char_buf;
-         idx2 = findidx (&cp, 1);
+         idx2 = findidx (table, indirect, extra, &cp, 1);
 /*
          idx2 = table[ch];
 */