]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - posix/fnmatch_loop.c
Increase some test timeouts.
[thirdparty/glibc.git] / posix / fnmatch_loop.c
index 72bd3ee856670ec9a29d14e533e52ae5cf8bb023..e298cac5dcdc3209d2f4b6b741c99a251f1b8a1a 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991-1993,1996-2001,2003-2005,2007,2010,2011
-   Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
 
 struct STRUCT
 {
@@ -28,27 +28,18 @@ struct STRUCT
    it matches, nonzero if not.  */
 static int FCT (const CHAR *pattern, const CHAR *string,
                const CHAR *string_end, int no_leading_period, int flags,
-               struct STRUCT *ends, size_t alloca_used)
-     internal_function;
+               struct STRUCT *ends, size_t alloca_used);
 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
                const CHAR *string_end, int no_leading_period, int flags,
-               size_t alloca_used)
-     internal_function;
-static const CHAR *END (const CHAR *patternp) internal_function;
+               size_t alloca_used);
+static const CHAR *END (const CHAR *patternp);
 
 static int
-internal_function
-FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
-     const CHAR *pattern;
-     const CHAR *string;
-     const CHAR *string_end;
-     int no_leading_period;
-     int flags;
-     struct STRUCT *ends;
-     size_t alloca_used;
+FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
+     int no_leading_period, int flags, struct STRUCT *ends, size_t alloca_used)
 {
-  register const CHAR *p = pattern, *n = string;
-  register UCHAR c;
+  const CHAR *p = pattern, *n = string;
+  UCHAR c;
 #ifdef _LIBC
 # if WIDE_CHAR_VERSION
   const char *collseq = (const char *)
@@ -237,7 +228,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
            /* Nonzero if the sense of the character class is inverted.  */
            const CHAR *p_init = p;
            const CHAR *n_init = n;
-           register int not;
+           int not;
            CHAR cold;
            UCHAR fn;
 
@@ -343,7 +334,12 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 #ifdef _LIBC
                else if (c == L('[') && *p == L('='))
                  {
-                   UCHAR str[1];
+                   /* It's important that STR be a scalar variable rather
+                      than a one-element array, because GCC (at least 4.9.2
+                      -O2 on x86-64) can be confused by the array and
+                      diagnose a "used initialized" in a dead branch in the
+                      findidx function.  */
+                   UCHAR str;
                    uint32_t nrules =
                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
                    const CHAR *startp = p;
@@ -355,7 +351,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                        c = L('[');
                        goto normal_bracket;
                      }
-                   str[0] = c;
+                   str = c;
 
                    c = *++p;
                    if (c != L('=') || p[1] != L(']'))
@@ -368,7 +364,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
                    if (nrules == 0)
                      {
-                       if ((UCHAR) *n == str[0])
+                       if ((UCHAR) *n == str)
                          goto matched;
                      }
                    else
@@ -376,28 +372,21 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                        const int32_t *table;
 # if WIDE_CHAR_VERSION
                        const int32_t *weights;
-                       const int32_t *extra;
+                       const wint_t *extra;
 # else
                        const unsigned char *weights;
                        const unsigned char *extra;
 # endif
                        const int32_t *indirect;
                        int32_t idx;
-                       const UCHAR *cp = (const UCHAR *) str;
-
-                       /* This #include defines a local function!  */
-# if WIDE_CHAR_VERSION
-#  include <locale/weightwc.h>
-# else
-#  include <locale/weight.h>
-# endif
+                       const UCHAR *cp = (const UCHAR *) &str;
 
 # if WIDE_CHAR_VERSION
                        table = (const int32_t *)
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
                        weights = (const int32_t *)
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
-                       extra = (const int32_t *)
+                       extra = (const wint_t *)
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
                        indirect = (const int32_t *)
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
@@ -412,7 +401,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
 # endif
 
-                       idx = findidx (&cp, 1);
+                       idx = FINDIDX (table, indirect, extra, &cp, 1);
                        if (idx != 0)
                          {
                            /* We found a table entry.  Now see whether the
@@ -422,7 +411,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                            int32_t idx2;
                            const UCHAR *np = (const UCHAR *) n;
 
-                           idx2 = findidx (&np, string_end - n);
+                           idx2 = FINDIDX (table, indirect, extra,
+                                           &np, string_end - n);
                            if (idx2 != 0
                                && (idx >> 24) == (idx2 >> 24)
                                && len == weights[idx2 & 0xffffff])
@@ -504,7 +494,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                          {
                            int32_t table_size;
                            const int32_t *symb_table;
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                            char str[c1];
                            unsigned int strcnt;
 # else
@@ -516,7 +506,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                            int32_t second;
                            int32_t hash;
 
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                            /* We have to convert the name to a single-byte
                               string.  This is possible since the names
                               consist of ASCII characters and the internal
@@ -571,7 +561,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                              {
                                /* Compare the byte sequence but only if
                                   this is not part of a range.  */
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                int32_t *wextra;
 
                                idx += 1 + extra[idx];
@@ -583,7 +573,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
                                if (! is_range)
                                  {
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                    for (c1 = 0;
                                         (int32_t) c1 < wextra[idx];
                                         ++c1)
@@ -604,7 +594,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
                                /* Get the collation sequence value.  */
                                is_seqval = 1;
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                cold = wextra[1 + wextra[idx]];
 # else
                                /* Adjust for the alignment.  */
@@ -667,7 +657,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                        uint32_t lcollseq;
                        UCHAR cend = *p++;
 
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                        /* Search in the `names' array for the characters.  */
                        fcollseq = __collseq_table_lookup (collseq, fn);
                        if (fcollseq == ~((uint32_t) 0))
@@ -722,7 +712,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                              {
                                int32_t table_size;
                                const int32_t *symb_table;
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                char str[c1];
                                unsigned int strcnt;
 # else
@@ -734,7 +724,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                                int32_t second;
                                int32_t hash;
 
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                /* We have to convert the name to a single-byte
                                   string.  This is possible since the names
                                   consist of ASCII characters and the internal
@@ -789,7 +779,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                                  {
                                    /* Compare the byte sequence but only if
                                       this is not part of a range.  */
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                    int32_t *wextra;
 
                                    idx += 1 + extra[idx];
@@ -800,7 +790,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 # endif
                                    /* Get the collation sequence value.  */
                                    is_seqval = 1;
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                    cend = wextra[1 + wextra[idx]];
 # else
                                    /* Adjust for the alignment.  */
@@ -832,7 +822,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                           characters which are not mentioned in the
                           collation specification.  */
                        if (
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                            lcollseq == 0xffffffff ||
 # endif
                            lcollseq <= fcollseq)
@@ -844,7 +834,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                              hcollseq = cend;
                            else
                              {
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                                hcollseq =
                                  __collseq_table_lookup (collseq, cend);
                                if (hcollseq == ~((uint32_t) 0))
@@ -865,7 +855,7 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)
                              goto matched;
                          }
-# ifdef WIDE_CHAR_VERSION
+# if WIDE_CHAR_VERSION
                      range_not_matched:
 # endif
 #else
@@ -899,11 +889,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
          matched:
            /* Skip the rest of the [...] that already matched.  */
-           do
+           while ((c = *p++) != L (']'))
              {
-             ignore_next:
-               c = *p++;
-
                if (c == L('\0'))
                  /* [... (unterminated) loses.  */
                  return FNM_NOMATCH;
@@ -931,12 +918,11 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
                        if (c < L('a') || c >= L('z'))
                          {
-                           p = startp;
-                           goto ignore_next;
+                           p = startp - 2;
+                           break;
                          }
                      }
                    p += 2;
-                   c = *p++;
                  }
                else if (c == L('[') && *p == L('='))
                  {
@@ -947,25 +933,21 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
                    if (c != L('=') || p[1] != L(']'))
                      return FNM_NOMATCH;
                    p += 2;
-                   c = *p++;
                  }
                else if (c == L('[') && *p == L('.'))
                  {
-                   ++p;
                    while (1)
                      {
                        c = *++p;
-                       if (c == '\0')
+                       if (c == L('\0'))
                          return FNM_NOMATCH;
 
-                       if (*p == L('.') && p[1] == L(']'))
+                       if (c == L('.') && p[1] == L(']'))
                          break;
                      }
                    p += 2;
-                   c = *p++;
                  }
              }
-           while (c != L(']'));
            if (not)
              return FNM_NOMATCH;
          }
@@ -1015,7 +997,6 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
 
 
 static const CHAR *
-internal_function
 END (const CHAR *pattern)
 {
   const CHAR *p = pattern;
@@ -1045,7 +1026,12 @@ END (const CHAR *pattern)
       }
     else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
              || *p == L('!')) && p[1] == L('('))
-      p = END (p + 1);
+      {
+       p = END (p + 1);
+       if (*p == L('\0'))
+         /* This is an invalid pattern.  */
+         return pattern;
+      }
     else if (*p == L(')'))
       break;
 
@@ -1054,7 +1040,6 @@ END (const CHAR *pattern)
 
 
 static int
-internal_function
 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
      int no_leading_period, int flags, size_t alloca_used)
 {
@@ -1283,3 +1268,5 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
 #undef STRCAT
 #undef L
 #undef BTOWC
+#undef WIDE_CHAR_VERSION
+#undef FINDIDX