Add .cantunwind to _dl_start_user
[platform/upstream/glibc.git] / posix / fnmatch.c
index 3fa7c32..a707847 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003
-       Free Software Foundation, Inc.
+/* Copyright (C) 1991-2015 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
@@ -13,9 +12,8 @@
    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/>.  */
 
 #if HAVE_CONFIG_H
 # include <config.h>
 #include <errno.h>
 #include <fnmatch.h>
 #include <ctype.h>
-
-#if HAVE_STRING_H || defined _LIBC
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
 
 #if defined STDC_HEADERS || defined _LIBC
 # include <stdlib.h>
 #endif
 
+#ifdef _LIBC
+# include <alloca.h>
+#else
+# define alloca_account(size., var) alloca (size)
+#endif
+
 /* For platform which support the ISO C amendement 1 functionality we
    support user defined character classes.  */
 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
@@ -209,6 +208,7 @@ __wcschrnul (s, c)
 # define FCT   internal_fnmatch
 # define EXT   ext_match
 # define END   end_pattern
+# define STRUCT        fnmatch_struct
 # define L(CS) CS
 # ifdef _LIBC
 #  define BTOWC(C)     __btowc (C)
@@ -220,6 +220,9 @@ __wcschrnul (s, c)
 # define MEMPCPY(D, S, N) __mempcpy (D, S, N)
 # define MEMCHR(S, C, N) memchr (S, C, N)
 # define STRCOLL(S1, S2) strcoll (S1, S2)
+# define WIDE_CHAR_VERSION 0
+# include <locale/weight.h>
+# define FINDIDX findidx
 # include "fnmatch_loop.c"
 
 
@@ -235,7 +238,8 @@ __wcschrnul (s, c)
 #  define INT  wint_t
 #  define FCT  internal_fnwmatch
 #  define EXT  ext_wmatch
-# define END   end_wpattern
+#  define END  end_wpattern
+#  define STRUCT fnwmatch_struct
 #  define L(CS)        L##CS
 #  define BTOWC(C)     (C)
 #  define STRLEN(S) __wcslen (S)
@@ -244,6 +248,12 @@ __wcschrnul (s, c)
 #  define MEMCHR(S, C, N) wmemchr (S, C, N)
 #  define STRCOLL(S1, S2) wcscoll (S1, S2)
 #  define WIDE_CHAR_VERSION 1
+/* Change the name the header defines so it doesn't conflict with
+   the <locale/weight.h> version included above.  */
+#  define findidx findidxwc
+#  include <locale/weightwc.h>
+#  undef findidx
+#  define FINDIDX findidxwc
 
 #  undef IS_CHAR_CLASS
 /* We have to convert the wide character string in a multibyte string.  But
@@ -328,8 +338,11 @@ fnmatch (pattern, string, flags)
       mbstate_t ps;
       size_t n;
       const char *p;
+      wchar_t *wpattern_malloc = NULL;
       wchar_t *wpattern;
+      wchar_t *wstring_malloc = NULL;
       wchar_t *wstring;
+      size_t alloca_used = 0;
 
       /* Convert the strings into wide characters.  */
       memset (&ps, '\0', sizeof (ps));
@@ -339,28 +352,41 @@ fnmatch (pattern, string, flags)
 #else
       n = strlen (pattern);
 #endif
-      if (__builtin_expect (n < 1024, 1))
+      if (__glibc_likely (n < 1024))
        {
-         wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+         wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
+                                                alloca_used);
          n = mbsrtowcs (wpattern, &p, n + 1, &ps);
-         if (__builtin_expect (n == (size_t) -1, 0))
+         if (__glibc_unlikely (n == (size_t) -1))
            /* Something wrong.
               XXX Do we have to set `errno' to something which mbsrtows hasn't
               already done?  */
            return -1;
          if (p)
-           memset (&ps, '\0', sizeof (ps));
+           {
+             memset (&ps, '\0', sizeof (ps));
+             goto prepare_wpattern;
+           }
        }
-      if (__builtin_expect (p != NULL, 0))
+      else
        {
+       prepare_wpattern:
          n = mbsrtowcs (NULL, &pattern, 0, &ps);
-         if (__builtin_expect (n == (size_t) -1, 0))
+         if (__glibc_unlikely (n == (size_t) -1))
            /* Something wrong.
               XXX Do we have to set `errno' to something which mbsrtows hasn't
               already done?  */
            return -1;
-         wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+         if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
+           {
+             __set_errno (ENOMEM);
+             return -2;
+           }
+         wpattern_malloc = wpattern
+           = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
          assert (mbsinit (&ps));
+         if (wpattern == NULL)
+           return -2;
          (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
        }
 
@@ -371,38 +397,66 @@ fnmatch (pattern, string, flags)
       n = strlen (string);
 #endif
       p = string;
-      if (__builtin_expect (n < 1024, 1))
+      if (__glibc_likely (n < 1024))
        {
-         wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+         wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
+                                               alloca_used);
          n = mbsrtowcs (wstring, &p, n + 1, &ps);
-         if (__builtin_expect (n == (size_t) -1, 0))
-           /* Something wrong.
-              XXX Do we have to set `errno' to something which mbsrtows hasn't
-              already done?  */
-           return -1;
+         if (__glibc_unlikely (n == (size_t) -1))
+           {
+             /* Something wrong.
+                XXX Do we have to set `errno' to something which
+                mbsrtows hasn't already done?  */
+           free_return:
+             free (wpattern_malloc);
+             return -1;
+           }
          if (p)
-           memset (&ps, '\0', sizeof (ps));
+           {
+             memset (&ps, '\0', sizeof (ps));
+             goto prepare_wstring;
+           }
        }
-      if (__builtin_expect (p != NULL, 0))
+      else
        {
+       prepare_wstring:
          n = mbsrtowcs (NULL, &string, 0, &ps);
-         if (__builtin_expect (n == (size_t) -1, 0))
+         if (__glibc_unlikely (n == (size_t) -1))
            /* Something wrong.
               XXX Do we have to set `errno' to something which mbsrtows hasn't
               already done?  */
-           return -1;
-         wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
+           goto free_return;
+         if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
+           {
+             free (wpattern_malloc);
+             __set_errno (ENOMEM);
+             return -2;
+           }
+
+         wstring_malloc = wstring
+           = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
+         if (wstring == NULL)
+           {
+             free (wpattern_malloc);
+             return -2;
+           }
          assert (mbsinit (&ps));
          (void) mbsrtowcs (wstring, &string, n + 1, &ps);
        }
 
-      return internal_fnwmatch (wpattern, wstring, wstring + n,
-                               flags & FNM_PERIOD, flags);
+      int res = internal_fnwmatch (wpattern, wstring, wstring + n,
+                                  flags & FNM_PERIOD, flags, NULL,
+                                  alloca_used);
+
+      free (wstring_malloc);
+      free (wpattern_malloc);
+
+      return res;
     }
 # endif  /* mbstate_t and mbsrtowcs or _LIBC.  */
 
   return internal_fnmatch (pattern, string, string + strlen (string),
-                          flags & FNM_PERIOD, flags);
+                          flags & FNM_PERIOD, flags, NULL, 0);
 }
 
 # ifdef _LIBC