X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=posix%2Ffnmatch.c;h=a707847dccd5945a1266bff6942b18f2fb9144bf;hb=174295f41363fc8749a48057c6ca3b3ef2e48613;hp=98c5ffc5cafbddc03032b10df867ca4825b9cca1;hpb=955994e1313ab81c1db2a456b5fdf7cacb016366;p=platform%2Fupstream%2Fglibc.git diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 98c5ffc..a707847 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -1,20 +1,19 @@ -/* Copyright (C) 1991-1993,1996-1999,2000,2001 Free Software Foundation, Inc. +/* Copyright (C) 1991-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, + The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with this library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ #if HAVE_CONFIG_H # include @@ -29,17 +28,18 @@ #include #include #include - -#if HAVE_STRING_H || defined _LIBC -# include -#else -# include -#endif +#include #if defined STDC_HEADERS || defined _LIBC # include #endif +#ifdef _LIBC +# include +#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) @@ -55,10 +55,12 @@ # include "../locale/localeinfo.h" # include "../locale/elem-hash.h" # include "../locale/coll-lookup.h" +# include # define CONCAT(a,b) __CONCAT(a,b) -# define mbsinit __mbsinit # define mbsrtowcs __mbsrtowcs +# define fnmatch __fnmatch +extern int fnmatch (const char *pattern, const char *string, int flags); #endif /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ @@ -206,15 +208,21 @@ __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) # else # define BTOWC(C) btowc (C) # endif +# define STRLEN(S) strlen (S) +# define STRCAT(D, S) strcat (D, S) # 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 +# define FINDIDX findidx # include "fnmatch_loop.c" @@ -230,13 +238,22 @@ __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) +# define STRCAT(D, S) __wcscat (D, S) # define MEMPCPY(D, S, N) __wmempcpy (D, S, N) # 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 version included above. */ +# define findidx findidxwc +# include +# undef findidx +# define FINDIDX findidxwc # undef IS_CHAR_CLASS /* We have to convert the wide character string in a multibyte string. But @@ -320,39 +337,136 @@ 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)); - n = mbsrtowcs (NULL, &pattern, 0, &ps); - if (__builtin_expect (n, 0) == (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)); - assert (mbsinit (&ps)); - (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps); + p = pattern; +#ifdef _LIBC + n = strnlen (pattern, 1024); +#else + n = strlen (pattern); +#endif + if (__glibc_likely (n < 1024)) + { + wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), + alloca_used); + n = mbsrtowcs (wpattern, &p, n + 1, &ps); + 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)); + goto prepare_wpattern; + } + } + else + { + prepare_wpattern: + n = mbsrtowcs (NULL, &pattern, 0, &ps); + 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 (__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); + } assert (mbsinit (&ps)); - n = mbsrtowcs (NULL, &string, 0, &ps); - if (__builtin_expect (n, 0) == (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)); - assert (mbsinit (&ps)); - (void) mbsrtowcs (wstring, &string, n + 1, &ps); +#ifdef _LIBC + n = strnlen (string, 1024); +#else + n = strlen (string); +#endif + p = string; + if (__glibc_likely (n < 1024)) + { + wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), + alloca_used); + n = mbsrtowcs (wstring, &p, n + 1, &ps); + 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)); + goto prepare_wstring; + } + } + else + { + prepare_wstring: + n = mbsrtowcs (NULL, &string, 0, &ps); + if (__glibc_unlikely (n == (size_t) -1)) + /* Something wrong. + XXX Do we have to set `errno' to something which mbsrtows hasn't + already done? */ + 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); + } + + int res = internal_fnwmatch (wpattern, wstring, wstring + n, + flags & FNM_PERIOD, flags, NULL, + alloca_used); - return internal_fnwmatch (wpattern, wstring, wstring + n, - flags & FNM_PERIOD, flags); + 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 +# undef fnmatch +versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); +# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) +strong_alias (__fnmatch, __fnmatch_old) +compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); +# endif +libc_hidden_ver (__fnmatch, fnmatch) +# endif + #endif /* _LIBC or not __GNU_LIBRARY__. */