Blame posix/fnmatch.c

Packit Service 82fcde
/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#if HAVE_CONFIG_H
Packit Service 82fcde
# include <config.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Enable GNU extensions in fnmatch.h.  */
Packit Service 82fcde
#ifndef _GNU_SOURCE
Packit Service 82fcde
# define _GNU_SOURCE	1
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <fnmatch.h>
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
Packit Service 82fcde
#if defined STDC_HEADERS || defined _LIBC
Packit Service 82fcde
# include <stdlib.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
# include <alloca.h>
Packit Service 82fcde
#else
Packit Service 82fcde
# define alloca_account(size., var) alloca (size)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* For platform which support the ISO C amendement 1 functionality we
Packit Service 82fcde
   support user defined character classes.  */
Packit Service 82fcde
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
Packit Service 82fcde
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
Packit Service 82fcde
# include <wchar.h>
Packit Service 82fcde
# include <wctype.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* We need some of the locale data (the collation sequence information)
Packit Service 82fcde
   but there is no interface to get this information in general.  Therefore
Packit Service 82fcde
   we support a correct implementation only in glibc.  */
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
# include "../locale/localeinfo.h"
Packit Service 82fcde
# include "../locale/elem-hash.h"
Packit Service 82fcde
# include "../locale/coll-lookup.h"
Packit Service 82fcde
# include <shlib-compat.h>
Packit Service 82fcde
Packit Service 82fcde
# define CONCAT(a,b) __CONCAT(a,b)
Packit Service 82fcde
# define mbsrtowcs __mbsrtowcs
Packit Service 82fcde
# define fnmatch __fnmatch
Packit Service 82fcde
extern int fnmatch (const char *pattern, const char *string, int flags);
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */
Packit Service 82fcde
#define NO_LEADING_PERIOD(flags) \
Packit Service 82fcde
  ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
Packit Service 82fcde
Packit Service 82fcde
/* Comment out all this code if we are using the GNU C Library, and are not
Packit Service 82fcde
   actually compiling the library itself.  This code is part of the GNU C
Packit Service 82fcde
   Library, but also included in many other GNU distributions.  Compiling
Packit Service 82fcde
   and linking in this code is a waste when using the GNU C library
Packit Service 82fcde
   (especially if it is a shared library).  Rather than having every GNU
Packit Service 82fcde
   program understand `configure --with-gnu-libc' and omit the object files,
Packit Service 82fcde
   it is simpler to just do this in the source for each such file.  */
Packit Service 82fcde
Packit Service 82fcde
#if defined _LIBC || !defined __GNU_LIBRARY__
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
# if defined STDC_HEADERS || !defined isascii
Packit Service 82fcde
#  define ISASCII(c) 1
Packit Service 82fcde
# else
Packit Service 82fcde
#  define ISASCII(c) isascii(c)
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
# ifdef isblank
Packit Service 82fcde
#  define ISBLANK(c) (ISASCII (c) && isblank (c))
Packit Service 82fcde
# else
Packit Service 82fcde
#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
Packit Service 82fcde
# endif
Packit Service 82fcde
# ifdef isgraph
Packit Service 82fcde
#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
Packit Service 82fcde
# else
Packit Service 82fcde
#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
# define ISPRINT(c) (ISASCII (c) && isprint (c))
Packit Service 82fcde
# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
Packit Service 82fcde
# define ISALNUM(c) (ISASCII (c) && isalnum (c))
Packit Service 82fcde
# define ISALPHA(c) (ISASCII (c) && isalpha (c))
Packit Service 82fcde
# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
Packit Service 82fcde
# define ISLOWER(c) (ISASCII (c) && islower (c))
Packit Service 82fcde
# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
Packit Service 82fcde
# define ISSPACE(c) (ISASCII (c) && isspace (c))
Packit Service 82fcde
# define ISUPPER(c) (ISASCII (c) && isupper (c))
Packit Service 82fcde
# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
Packit Service 82fcde
Packit Service 82fcde
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
Packit Service 82fcde
Packit Service 82fcde
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
Packit Service 82fcde
/* The GNU C library provides support for user-defined character classes
Packit Service 82fcde
   and the functions from ISO C amendement 1.  */
Packit Service 82fcde
#  ifdef CHARCLASS_NAME_MAX
Packit Service 82fcde
#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
Packit Service 82fcde
#  else
Packit Service 82fcde
/* This shouldn't happen but some implementation might still have this
Packit Service 82fcde
   problem.  Use a reasonable default value.  */
Packit Service 82fcde
#   define CHAR_CLASS_MAX_LENGTH 256
Packit Service 82fcde
#  endif
Packit Service 82fcde
Packit Service 82fcde
#  ifdef _LIBC
Packit Service 82fcde
#   define IS_CHAR_CLASS(string) __wctype (string)
Packit Service 82fcde
#  else
Packit Service 82fcde
#   define IS_CHAR_CLASS(string) wctype (string)
Packit Service 82fcde
#  endif
Packit Service 82fcde
Packit Service 82fcde
#  ifdef _LIBC
Packit Service 82fcde
#   define ISWCTYPE(WC, WT)	__iswctype (WC, WT)
Packit Service 82fcde
#  else
Packit Service 82fcde
#   define ISWCTYPE(WC, WT)	iswctype (WC, WT)
Packit Service 82fcde
#  endif
Packit Service 82fcde
Packit Service 82fcde
#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
Packit Service 82fcde
/* In this case we are implementing the multibyte character handling.  */
Packit Service 82fcde
#   define HANDLE_MULTIBYTE	1
Packit Service 82fcde
#  endif
Packit Service 82fcde
Packit Service 82fcde
# else
Packit Service 82fcde
#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
Packit Service 82fcde
Packit Service 82fcde
#  define IS_CHAR_CLASS(string)						      \
Packit Service 82fcde
   (STREQ (string, "alpha") || STREQ (string, "upper")			      \
Packit Service 82fcde
    || STREQ (string, "lower") || STREQ (string, "digit")		      \
Packit Service 82fcde
    || STREQ (string, "alnum") || STREQ (string, "xdigit")		      \
Packit Service 82fcde
    || STREQ (string, "space") || STREQ (string, "print")		      \
Packit Service 82fcde
    || STREQ (string, "punct") || STREQ (string, "graph")		      \
Packit Service 82fcde
    || STREQ (string, "cntrl") || STREQ (string, "blank"))
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
/* Avoid depending on library functions or files
Packit Service 82fcde
   whose names are inconsistent.  */
Packit Service 82fcde
Packit Service 82fcde
# if !defined _LIBC && !defined getenv
Packit Service 82fcde
extern char *getenv ();
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
# ifndef errno
Packit Service 82fcde
extern int errno;
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
/* Global variable.  */
Packit Service 82fcde
static int posixly_correct;
Packit Service 82fcde
Packit Service 82fcde
/* This function doesn't exist on most systems.  */
Packit Service 82fcde
Packit Service 82fcde
# if !defined HAVE___STRCHRNUL && !defined _LIBC
Packit Service 82fcde
static char *
Packit Service 82fcde
__strchrnul (const char *s, int c)
Packit Service 82fcde
{
Packit Service 82fcde
  char *result = strchr (s, c);
Packit Service 82fcde
  if (result == NULL)
Packit Service 82fcde
    result = strchr (s, '\0');
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
# if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
Packit Service 82fcde
static wchar_t *
Packit Service 82fcde
__wcschrnul (const wchar_t *s, wint_t c)
Packit Service 82fcde
{
Packit Service 82fcde
  wchar_t *result = wcschr (s, c);
Packit Service 82fcde
  if (result == NULL)
Packit Service 82fcde
    result = wcschr (s, '\0');
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
/* Note that this evaluates C many times.  */
Packit Service 82fcde
# ifdef _LIBC
Packit Service 82fcde
#  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
Packit Service 82fcde
# else
Packit Service 82fcde
#  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
Packit Service 82fcde
# endif
Packit Service 82fcde
# define CHAR	char
Packit Service 82fcde
# define UCHAR	unsigned char
Packit Service 82fcde
# define INT	int
Packit Service 82fcde
# define FCT	internal_fnmatch
Packit Service 82fcde
# define EXT	ext_match
Packit Service 82fcde
# define END	end_pattern
Packit Service 82fcde
# define STRUCT	fnmatch_struct
Packit Service 82fcde
# define L(CS)	CS
Packit Service 82fcde
# ifdef _LIBC
Packit Service 82fcde
#  define BTOWC(C)	__btowc (C)
Packit Service 82fcde
# else
Packit Service 82fcde
#  define BTOWC(C)	btowc (C)
Packit Service 82fcde
# endif
Packit Service 82fcde
# define STRLEN(S) strlen (S)
Packit Service 82fcde
# define STRCAT(D, S) strcat (D, S)
Packit Service 82fcde
# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
Packit Service 82fcde
# define MEMCHR(S, C, N) memchr (S, C, N)
Packit Service 82fcde
# define STRCOLL(S1, S2) strcoll (S1, S2)
Packit Service 82fcde
# define WIDE_CHAR_VERSION 0
Packit Service 82fcde
# include <locale/weight.h>
Packit Service 82fcde
# define FINDIDX findidx
Packit Service 82fcde
# include "fnmatch_loop.c"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
# if HANDLE_MULTIBYTE
Packit Service 82fcde
/* Note that this evaluates C many times.  */
Packit Service 82fcde
#  ifdef _LIBC
Packit Service 82fcde
#   define FOLD(c) ((flags & FNM_CASEFOLD) ? __towlower (c) : (c))
Packit Service 82fcde
#  else
Packit Service 82fcde
#   define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
Packit Service 82fcde
#  endif
Packit Service 82fcde
#  define CHAR	wchar_t
Packit Service 82fcde
#  define UCHAR	wint_t
Packit Service 82fcde
#  define INT	wint_t
Packit Service 82fcde
#  define FCT	internal_fnwmatch
Packit Service 82fcde
#  define EXT	ext_wmatch
Packit Service 82fcde
#  define END	end_wpattern
Packit Service 82fcde
#  define STRUCT fnwmatch_struct
Packit Service 82fcde
#  define L(CS)	L##CS
Packit Service 82fcde
#  define BTOWC(C)	(C)
Packit Service 82fcde
#  define STRLEN(S) __wcslen (S)
Packit Service 82fcde
#  define STRCAT(D, S) __wcscat (D, S)
Packit Service 82fcde
#  define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
Packit Service 82fcde
#  define MEMCHR(S, C, N) __wmemchr (S, C, N)
Packit Service 82fcde
#  define STRCOLL(S1, S2) wcscoll (S1, S2)
Packit Service 82fcde
#  define WIDE_CHAR_VERSION 1
Packit Service 82fcde
/* Change the name the header defines so it doesn't conflict with
Packit Service 82fcde
   the <locale/weight.h> version included above.  */
Packit Service 82fcde
#  define findidx findidxwc
Packit Service 82fcde
#  include <locale/weightwc.h>
Packit Service 82fcde
#  undef findidx
Packit Service 82fcde
#  define FINDIDX findidxwc
Packit Service 82fcde
Packit Service 82fcde
#  undef IS_CHAR_CLASS
Packit Service 82fcde
/* We have to convert the wide character string in a multibyte string.  But
Packit Service 82fcde
   we know that the character class names consist of alphanumeric characters
Packit Service 82fcde
   from the portable character set, and since the wide character encoding
Packit Service 82fcde
   for a member of the portable character set is the same code point as
Packit Service 82fcde
   its single-byte encoding, we can use a simplified method to convert the
Packit Service 82fcde
   string to a multibyte character string.  */
Packit Service 82fcde
static wctype_t
Packit Service 82fcde
is_char_class (const wchar_t *wcs)
Packit Service 82fcde
{
Packit Service 82fcde
  char s[CHAR_CLASS_MAX_LENGTH + 1];
Packit Service 82fcde
  char *cp = s;
Packit Service 82fcde
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Test for a printable character from the portable character set.  */
Packit Service 82fcde
#  ifdef _LIBC
Packit Service 82fcde
      if (*wcs < 0x20 || *wcs > 0x7e
Packit Service 82fcde
	  || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
Packit Service 82fcde
	return (wctype_t) 0;
Packit Service 82fcde
#  else
Packit Service 82fcde
      switch (*wcs)
Packit Service 82fcde
	{
Packit Service 82fcde
	case L' ': case L'!': case L'"': case L'#': case L'%':
Packit Service 82fcde
	case L'&': case L'\'': case L'(': case L')': case L'*':
Packit Service 82fcde
	case L'+': case L',': case L'-': case L'.': case L'/':
Packit Service 82fcde
	case L'0': case L'1': case L'2': case L'3': case L'4':
Packit Service 82fcde
	case L'5': case L'6': case L'7': case L'8': case L'9':
Packit Service 82fcde
	case L':': case L';': case L'<': case L'=': case L'>':
Packit Service 82fcde
	case L'?':
Packit Service 82fcde
	case L'A': case L'B': case L'C': case L'D': case L'E':
Packit Service 82fcde
	case L'F': case L'G': case L'H': case L'I': case L'J':
Packit Service 82fcde
	case L'K': case L'L': case L'M': case L'N': case L'O':
Packit Service 82fcde
	case L'P': case L'Q': case L'R': case L'S': case L'T':
Packit Service 82fcde
	case L'U': case L'V': case L'W': case L'X': case L'Y':
Packit Service 82fcde
	case L'Z':
Packit Service 82fcde
	case L'[': case L'\\': case L']': case L'^': case L'_':
Packit Service 82fcde
	case L'a': case L'b': case L'c': case L'd': case L'e':
Packit Service 82fcde
	case L'f': case L'g': case L'h': case L'i': case L'j':
Packit Service 82fcde
	case L'k': case L'l': case L'm': case L'n': case L'o':
Packit Service 82fcde
	case L'p': case L'q': case L'r': case L's': case L't':
Packit Service 82fcde
	case L'u': case L'v': case L'w': case L'x': case L'y':
Packit Service 82fcde
	case L'z': case L'{': case L'|': case L'}': case L'~':
Packit Service 82fcde
	  break;
Packit Service 82fcde
	default:
Packit Service 82fcde
	  return (wctype_t) 0;
Packit Service 82fcde
	}
Packit Service 82fcde
#  endif
Packit Service 82fcde
Packit Service 82fcde
      /* Avoid overrunning the buffer.  */
Packit Service 82fcde
      if (cp == s + CHAR_CLASS_MAX_LENGTH)
Packit Service 82fcde
	return (wctype_t) 0;
Packit Service 82fcde
Packit Service 82fcde
      *cp++ = (char) *wcs++;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (*wcs != L'\0');
Packit Service 82fcde
Packit Service 82fcde
  *cp = '\0';
Packit Service 82fcde
Packit Service 82fcde
#  ifdef _LIBC
Packit Service 82fcde
  return __wctype (s);
Packit Service 82fcde
#  else
Packit Service 82fcde
  return wctype (s);
Packit Service 82fcde
#  endif
Packit Service 82fcde
}
Packit Service 82fcde
#  define IS_CHAR_CLASS(string) is_char_class (string)
Packit Service 82fcde
Packit Service 82fcde
#  include "fnmatch_loop.c"
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
fnmatch (const char *pattern, const char *string, int flags)
Packit Service 82fcde
{
Packit Service 82fcde
# if HANDLE_MULTIBYTE
Packit Service 82fcde
  if (__builtin_expect (MB_CUR_MAX, 1) != 1)
Packit Service 82fcde
    {
Packit Service e9f235
      const char *orig_pattern = pattern;
Packit Service 82fcde
      mbstate_t ps;
Packit Service 82fcde
      size_t n;
Packit Service 82fcde
      const char *p;
Packit Service 82fcde
      wchar_t *wpattern_malloc = NULL;
Packit Service 82fcde
      wchar_t *wpattern;
Packit Service 82fcde
      wchar_t *wstring_malloc = NULL;
Packit Service 82fcde
      wchar_t *wstring;
Packit Service 82fcde
      size_t alloca_used = 0;
Packit Service 82fcde
Packit Service 82fcde
      /* Convert the strings into wide characters.  */
Packit Service 82fcde
      memset (&ps, '\0', sizeof (ps));
Packit Service 82fcde
      p = pattern;
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
      n = __strnlen (pattern, 1024);
Packit Service 82fcde
#else
Packit Service 82fcde
      n = strlen (pattern);
Packit Service 82fcde
#endif
Packit Service 82fcde
      if (__glibc_likely (n < 1024))
Packit Service 82fcde
	{
Packit Service 82fcde
	  wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
Packit Service 82fcde
						 alloca_used);
Packit Service 82fcde
	  n = mbsrtowcs (wpattern, &p, n + 1, &ps);
Packit Service 82fcde
	  if (__glibc_unlikely (n == (size_t) -1))
Packit Service e9f235
	    /* Something wrong: Fall back to single byte matching. */
Packit Service e9f235
	    goto try_singlebyte;
Packit Service 82fcde
	  if (p)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      memset (&ps, '\0', sizeof (ps));
Packit Service 82fcde
	      goto prepare_wpattern;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	prepare_wpattern:
Packit Service 82fcde
	  n = mbsrtowcs (NULL, &pattern, 0, &ps);
Packit Service 82fcde
	  if (__glibc_unlikely (n == (size_t) -1))
Packit Service e9f235
	    /*Something wrong: Fall back to single byte matching. */
Packit Service e9f235
	    goto try_singlebyte;
Packit Service 82fcde
	  if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      __set_errno (ENOMEM);
Packit Service 82fcde
	      return -2;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  wpattern_malloc = wpattern
Packit Service 82fcde
	    = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
Packit Service 82fcde
	  assert (mbsinit (&ps);;
Packit Service 82fcde
	  if (wpattern == NULL)
Packit Service 82fcde
	    return -2;
Packit Service 82fcde
	  (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      assert (mbsinit (&ps);;
Packit Service 82fcde
#ifdef _LIBC
Packit Service 82fcde
      n = __strnlen (string, 1024);
Packit Service 82fcde
#else
Packit Service 82fcde
      n = strlen (string);
Packit Service 82fcde
#endif
Packit Service 82fcde
      p = string;
Packit Service 82fcde
      if (__glibc_likely (n < 1024))
Packit Service 82fcde
	{
Packit Service 82fcde
	  wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
Packit Service 82fcde
						alloca_used);
Packit Service 82fcde
	  n = mbsrtowcs (wstring, &p, n + 1, &ps);
Packit Service 82fcde
	  if (__glibc_unlikely (n == (size_t) -1))
Packit Service e9f235
	    /* Something wrong: Fall back to single byte matching. */
Packit Service e9f235
	    goto free_and_try_singlebyte;
Packit Service 82fcde
	  if (p)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      memset (&ps, '\0', sizeof (ps));
Packit Service 82fcde
	      goto prepare_wstring;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	prepare_wstring:
Packit Service 82fcde
	  n = mbsrtowcs (NULL, &string, 0, &ps);
Packit Service 82fcde
	  if (__glibc_unlikely (n == (size_t) -1))
Packit Service e9f235
	    /* Something wrong: Fall back to singlebyte matching. */
Packit Service e9f235
	    goto free_and_try_singlebyte;
Packit Service 82fcde
	  if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      free (wpattern_malloc);
Packit Service 82fcde
	      __set_errno (ENOMEM);
Packit Service 82fcde
	      return -2;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  wstring_malloc = wstring
Packit Service 82fcde
	    = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
Packit Service 82fcde
	  if (wstring == NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      free (wpattern_malloc);
Packit Service 82fcde
	      return -2;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  assert (mbsinit (&ps);;
Packit Service 82fcde
	  (void) mbsrtowcs (wstring, &string, n + 1, &ps);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      int res = internal_fnwmatch (wpattern, wstring, wstring + n,
Packit Service 82fcde
				   flags & FNM_PERIOD, flags, NULL,
Packit Service 82fcde
				   alloca_used);
Packit Service 82fcde
Packit Service 82fcde
      free (wstring_malloc);
Packit Service 82fcde
      free (wpattern_malloc);
Packit Service 82fcde
Packit Service 82fcde
      return res;
Packit Service e9f235
      free_and_try_singlebyte:
Packit Service e9f235
	free(wpattern_malloc);
Packit Service e9f235
      try_singlebyte:
Packit Service e9f235
	pattern = orig_pattern;
Packit Service 82fcde
    }
Packit Service 82fcde
# endif  /* mbstate_t and mbsrtowcs or _LIBC.  */
Packit Service 82fcde
Packit Service 82fcde
  return internal_fnmatch (pattern, string, string + strlen (string),
Packit Service 82fcde
			   flags & FNM_PERIOD, flags, NULL, 0);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
# ifdef _LIBC
Packit Service 82fcde
#  undef fnmatch
Packit Service 82fcde
versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
Packit Service 82fcde
#  if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
Packit Service 82fcde
strong_alias (__fnmatch, __fnmatch_old)
Packit Service 82fcde
compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
Packit Service 82fcde
#  endif
Packit Service 82fcde
libc_hidden_ver (__fnmatch, fnmatch)
Packit Service 82fcde
# endif
Packit Service 82fcde
Packit Service 82fcde
#endif	/* _LIBC or not __GNU_LIBRARY__.  */