[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
fnmatch: Overcome wchar_t limitations
|
From: |
Bruno Haible |
|
Subject: |
fnmatch: Overcome wchar_t limitations |
|
Date: |
Tue, 25 Jul 2023 02:46:21 +0200 |
This patch fixes the remaining problems of fnmatch() on Cygwin,
native Windows, and AIX in 32-bit mode.
I think the code changes are in glibc style, because
- they use upper-case names for macros,
- the macro names are aligned to the type and function names used
by glibc,
- the #ifdef _LIBC alternative comes first.
The fnmatch replacement uses char32_t only when needed, i.e. for
the three platforms listed above. When char32_t is not needed, we
can just continue to use wchar_t, because
- the wchar_t-based code is needed for glibc source code compatibility,
- fewer dependencies need to be compiled into the binaries if we can
use libc built-in functions instead of gnulib c32_* and u32_* functions.
Packages that use the 'fnmatch' or 'fnmatch-gnu' module don't need to
update their *_LDADD variables, if they don't use the 'libunistring-optional'
module.
(Like in <https://lists.gnu.org/archive/html/bug-gnulib/2023-07/msg00000.html>.)
2023-07-24 Bruno Haible <bruno@clisp.org>
fnmatch: Overcome wchar_t limitations.
* m4/fnmatch.m4 (gl_FUNC_FNMATCH_POSIX): Set REPLACE_FNMATCH to 1 on
AIX in 32-bit mode.
* lib/fnmatch.c: Include <uchar.h>. Conditionally include unistr.h.
(UCHAR_TO_WCHAR): Renamed from BTOWC.
(WCHAR_T, WINT_T, BTOWC, MBSRTOWCS, WCSLEN, WCSCAT, WMEMPCPY, WMEMCHR,
TOWLOWER, WCTYPE_T, WCTYPE, ISWCTYPE): New macros.
(IS_CHAR_CLASS): Use WCTYPE instead of wctype.
(UCHAR_TO_WCHAR): Use BTOWC instead of btowc.
(FOLD): Use TOWLOWER instead of towlower.
(CHAR): Use WCHAR_T instead of wchar_t.
(UCHAR, INT): Use WINT_T instead of wint_t.
(STRLEN): Use WCSLEN instead of wcslen.
(STRCAT): Use WCSCAT instead of wcscat.
(MEMPCPY): Use WMEMPCPY instead of wmempcpy.
(MEMCHR): Use WMEMCHR instead of wmemchr.
(is_char_class): Use WCTYPE_T instead of wctype_t, WCHAR_T instead of
wchar_t, WCTYPE instead of wctype.
(fnmatch): Use WCHAR_T instead of wchar_t, MBSRTOWCS instead of
mbsrtowcs.
* lib/fnmatch_loop.c (FCT): Use WCTYPE_T instead of wctype_t, ISWCTYPE
instead of iswctype. Update for renamed BTOWC.
* modules/fnmatch (Depends-on): Add btoc32, c32tolower,
c32_get_type_test, c32_apply_type_test, mbsrtoc32s, unistr/u32-chr,
unistr/u32-pcpy, unistr/u32-strcat, unistr/u32-strlen.
(Link): Add $(LIBUNISTRING).
* modules/fnmatch-tests (Makefile.am): Link test-fnmatch with
$(LIBUNISTRING).
* doc/posix-functions/fnmatch.texi: Move the Cygwin, mingw, MSVC, AIX
bug descriptions to the "fixed by Gnulib" section.
diff --git a/doc/posix-functions/fnmatch.texi b/doc/posix-functions/fnmatch.texi
index ba76c45dd1..1e662a43c1 100644
--- a/doc/posix-functions/fnmatch.texi
+++ b/doc/posix-functions/fnmatch.texi
@@ -50,7 +50,26 @@
Unicode BMP on some platforms:
@c Failing test cases:
@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
-Solaris 10.
+Solaris 10, Cygwin 3.4.6,
+@c Failing test cases:
+@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
+@c fnmatch ("x[[:alnum:]]y", "x\360\220\214\260y", 0) == 0
+@c fnmatch ("x[[:alpha:]]y", "x\360\220\214\260y", 0) == 0
+@c fnmatch ("x[[:graph:]]y", "x\360\240\200\200y", 0) == 0
+@c fnmatch ("x[[:lower:]]y", "x\360\220\221\201y", 0) == 0
+@c fnmatch ("x[[:print:]]y", "x\360\240\200\200y", 0) == 0
+@c fnmatch ("x[[:punct:]]y", "x\360\235\204\200y", 0) == 0
+@c fnmatch ("x[[:upper:]]y", "x\360\220\220\231y", 0) == 0
+MSVC,
+@c Failing test cases:
+@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
+@c fnmatch ("x[[:alnum:]]y", "x\360\220\214\260y", 0) == 0
+@c fnmatch ("x[[:alpha:]]y", "x\360\220\214\260y", 0) == 0
+@c fnmatch ("x[[:graph:]]y", "x\360\240\200\200y", 0) == 0
+@c fnmatch ("x[[:lower:]]y", "x\360\220\221\201y", 0) == 0
+@c fnmatch ("x[[:print:]]y", "x\360\240\200\200y", 0) == 0
+@c fnmatch ("x[[:upper:]]y", "x\360\220\220\231y", 0) == 0
+32-bit AIX.
@item
In the pattern, negated character ranges (such as @code{[!a-z]}) are not
supported on some platforms:
@@ -154,31 +173,6 @@
Portability problems not fixed by Gnulib:
@itemize
-@item
-The @code{"?"} pattern character fails to match characters outside the
-Unicode BMP on some platforms:
-@c Failing test cases:
-@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
-Cygwin 3.4.6,
-@c Failing test cases:
-@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
-@c fnmatch ("x[[:alnum:]]y", "x\360\220\214\260y", 0) == 0
-@c fnmatch ("x[[:alpha:]]y", "x\360\220\214\260y", 0) == 0
-@c fnmatch ("x[[:graph:]]y", "x\360\240\200\200y", 0) == 0
-@c fnmatch ("x[[:lower:]]y", "x\360\220\221\201y", 0) == 0
-@c fnmatch ("x[[:print:]]y", "x\360\240\200\200y", 0) == 0
-@c fnmatch ("x[[:punct:]]y", "x\360\235\204\200y", 0) == 0
-@c fnmatch ("x[[:upper:]]y", "x\360\220\220\231y", 0) == 0
-MSVC,
-@c Failing test cases:
-@c fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
-@c fnmatch ("x[[:alnum:]]y", "x\360\220\214\260y", 0) == 0
-@c fnmatch ("x[[:alpha:]]y", "x\360\220\214\260y", 0) == 0
-@c fnmatch ("x[[:graph:]]y", "x\360\240\200\200y", 0) == 0
-@c fnmatch ("x[[:lower:]]y", "x\360\220\221\201y", 0) == 0
-@c fnmatch ("x[[:print:]]y", "x\360\240\200\200y", 0) == 0
-@c fnmatch ("x[[:upper:]]y", "x\360\220\220\231y", 0) == 0
-32-bit AIX.
@end itemize
Note: Gnulib's replacement function has some limitations:
@@ -187,14 +181,4 @@
It does not implement patterns with
collating elements (such as @code{"[[.ch.]]"}) or
equivalence classes (such as @code{"[[=a=]]"}).
-@item
-In the pattern, the character class @code{[:blank:]} inside bracket
-expressions is not supported on some platforms:
-@c Failing test cases:
-@c fnmatch ("[[:blank:]]", " ", 0) == 0
-mingw.
-@c Additionally, on mingw 10, there are test failures:
-@c fnmatch ("x?y", "x\223\372y", 0) == 0
-@c fnmatch ("x?y", "x\244\351y", 0) == 0
-@c fnmatch ("x?y", "x\310\325y", 0) == 0
@end itemize
diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index 32cfb48d0f..d86bc49e64 100644
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -35,9 +35,40 @@
#if defined _LIBC || HAVE_ALLOCA
# include <alloca.h>
#endif
-#include <wchar.h>
-#include <wctype.h>
#include <stddef.h>
+#include <uchar.h>
+#if defined _LIBC || !_GL_SMALL_WCHAR_T
+/* It's OK to use wchar_t, since it's wide enough. */
+# include <wchar.h>
+# include <wctype.h>
+# define WCHAR_T wchar_t
+# define WINT_T wint_t
+# define BTOWC btowc
+# define MBSRTOWCS mbsrtowcs
+# define WCSLEN wcslen
+# define WCSCAT wcscat
+# define WMEMPCPY wmempcpy
+# define WMEMCHR wmemchr
+# define TOWLOWER towlower
+# define WCTYPE_T wctype_t
+# define WCTYPE wctype
+# define ISWCTYPE iswctype
+#else
+/* wchar_t is too small, use char32_t instead. */
+# include "unistr.h"
+# define WCHAR_T char32_t
+# define WINT_T char32_t
+# define BTOWC btoc32
+# define MBSRTOWCS mbsrtoc32s
+# define WCSLEN u32_strlen
+# define WCSCAT u32_strcat
+# define WMEMPCPY u32_pcpy
+# define WMEMCHR(S, C, N) u32_chr (S, N, C)
+# define TOWLOWER c32tolower
+# define WCTYPE_T c32_type_test_t
+# define WCTYPE c32_get_type_test
+# define ISWCTYPE c32_apply_type_test
+#endif
/* We need some of the locale data (the collation sequence information)
but there is no interface to get this information in general. Therefore
@@ -111,7 +142,7 @@ typedef ptrdiff_t idx_t;
# define CHAR_CLASS_MAX_LENGTH 256
#endif
-#define IS_CHAR_CLASS(string) wctype (string)
+#define IS_CHAR_CLASS(string) WCTYPE (string)
/* Avoid depending on library functions or files
whose names are inconsistent. */
@@ -129,7 +160,7 @@ static int posixly_correct;
#define END end_pattern
#define STRUCT fnmatch_struct
#define L_(CS) CS
-#define BTOWC(C) btowc (C)
+#define UCHAR_TO_WCHAR(C) BTOWC (C)
#define STRLEN(S) strlen (S)
#define STRCAT(D, S) strcat (D, S)
#define MEMPCPY(D, S, N) mempcpy (D, S, N)
@@ -142,19 +173,19 @@ static int posixly_correct;
#include "fnmatch_loop.c"
-#define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
-#define CHAR wchar_t
-#define UCHAR wint_t
-#define INT wint_t
+#define FOLD(c) ((flags & FNM_CASEFOLD) ? TOWLOWER (c) : (c))
+#define CHAR WCHAR_T
+#define UCHAR WINT_T
+#define INT WINT_T
#define FCT internal_fnwmatch
#define EXT ext_wmatch
#define END end_wpattern
#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 UCHAR_TO_WCHAR(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 WIDE_CHAR_VERSION 1
#ifdef _LIBC
/* Change the name the header defines so it doesn't conflict with
@@ -172,8 +203,8 @@ static int posixly_correct;
for a member of the portable character set is the same code point as
its single-byte encoding, we can use a simplified method to convert the
string to a multibyte character string. */
-static wctype_t
-is_char_class (const wchar_t *wcs)
+static WCTYPE_T
+is_char_class (const WCHAR_T *wcs)
{
char s[CHAR_CLASS_MAX_LENGTH + 1];
char *cp = s;
@@ -184,7 +215,7 @@ is_char_class (const wchar_t *wcs)
#ifdef _LIBC
if (*wcs < 0x20 || *wcs > 0x7e
|| *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
- return (wctype_t) 0;
+ return (WCTYPE_T) 0;
#else
switch (*wcs)
{
@@ -210,13 +241,13 @@ is_char_class (const wchar_t *wcs)
case L'z': case L'{': case L'|': case L'}': case L'~':
break;
default:
- return (wctype_t) 0;
+ return (WCTYPE_T) 0;
}
#endif
/* Avoid overrunning the buffer. */
if (cp == s + CHAR_CLASS_MAX_LENGTH)
- return (wctype_t) 0;
+ return (WCTYPE_T) 0;
*cp++ = (char) *wcs++;
}
@@ -224,7 +255,7 @@ is_char_class (const wchar_t *wcs)
*cp = '\0';
- return wctype (s);
+ return WCTYPE (s);
}
#define IS_CHAR_CLASS(string) is_char_class (string)
@@ -239,10 +270,10 @@ fnmatch (const char *pattern, const char *string, int
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;
+ 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. */
@@ -251,9 +282,9 @@ fnmatch (const char *pattern, const char *string, int flags)
n = strnlen (pattern, 1024);
if (__glibc_likely (n < 1024))
{
- wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
+ wpattern = (WCHAR_T *) alloca_account ((n + 1) * sizeof (WCHAR_T),
alloca_used);
- n = mbsrtowcs (wpattern, &p, n + 1, &ps);
+ 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
@@ -268,23 +299,23 @@ fnmatch (const char *pattern, const char *string, int
flags)
else
{
prepare_wpattern:
- n = mbsrtowcs (NULL, &pattern, 0, &ps);
+ 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)))
+ 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));
+ = (WCHAR_T *) malloc ((n + 1) * sizeof (WCHAR_T));
assert (mbsinit (&ps));
if (wpattern == NULL)
return -2;
- (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
+ (void) MBSRTOWCS (wpattern, &pattern, n + 1, &ps);
}
assert (mbsinit (&ps));
@@ -292,9 +323,9 @@ fnmatch (const char *pattern, const char *string, int flags)
p = string;
if (__glibc_likely (n < 1024))
{
- wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
+ wstring = (WCHAR_T *) alloca_account ((n + 1) * sizeof (WCHAR_T),
alloca_used);
- n = mbsrtowcs (wstring, &p, n + 1, &ps);
+ n = MBSRTOWCS (wstring, &p, n + 1, &ps);
if (__glibc_unlikely (n == (size_t) -1))
{
/* Something wrong.
@@ -313,13 +344,13 @@ fnmatch (const char *pattern, const char *string, int
flags)
else
{
prepare_wstring:
- n = mbsrtowcs (NULL, &string, 0, &ps);
+ 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)))
+ if (__glibc_unlikely (n >= (size_t) -1 / sizeof (WCHAR_T)))
{
free (wpattern_malloc);
__set_errno (ENOMEM);
@@ -327,14 +358,14 @@ fnmatch (const char *pattern, const char *string, int
flags)
}
wstring_malloc = wstring
- = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
+ = (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);
+ (void) MBSRTOWCS (wstring, &string, n + 1, &ps);
}
int res = internal_fnwmatch (wpattern, wstring, wstring + n,
diff --git a/lib/fnmatch_loop.c b/lib/fnmatch_loop.c
index 68a3b7a5bc..42e84b80cf 100644
--- a/lib/fnmatch_loop.c
+++ b/lib/fnmatch_loop.c
@@ -270,7 +270,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR
*string_end,
/* Leave room for the null. */
CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
size_t c1 = 0;
- wctype_t wt;
+ WCTYPE_T wt;
const CHAR *startp = p;
for (;;)
@@ -310,7 +310,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR
*string_end,
if (_ISCTYPE ((UCHAR) *n, wt))
goto matched;
#else
- if (iswctype (BTOWC ((UCHAR) *n), wt))
+ if (ISWCTYPE (UCHAR_TO_WCHAR ((UCHAR) *n), wt))
goto matched;
#endif
c = *p++;
@@ -1206,6 +1206,6 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string,
const CHAR *string_end,
#undef STRLEN
#undef STRCAT
#undef L_
-#undef BTOWC
+#undef UCHAR_TO_WCHAR
#undef WIDE_CHAR_VERSION
#undef FINDIDX
diff --git a/m4/fnmatch.m4 b/m4/fnmatch.m4
index eba70de2bc..2e1442eff7 100644
--- a/m4/fnmatch.m4
+++ b/m4/fnmatch.m4
@@ -1,4 +1,4 @@
-# Check for fnmatch - serial 17 -*- coding: utf-8 -*-
+# Check for fnmatch - serial 18 -*- coding: utf-8 -*-
# Copyright (C) 2000-2007, 2009-2023 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
@@ -158,6 +158,14 @@ AC_DEFUN([gl_FUNC_FNMATCH_POSIX]
*yes) ;;
*) REPLACE_FNMATCH=1 ;;
esac
+ dnl On AIX 7.2 in 32-bit mode, fnmatch()'s only POSIX compliance problem is
+ dnl that is does not support characters outside the Unicode BMP correctly.
+ dnl Test case: fnmatch ("x?y", "x\360\237\230\213y", 0) == 0
+ dnl This is due to wchar_t being only 16 bits wide.
+ AC_REQUIRE([gl_UCHAR_H])
+ if test $SMALL_WCHAR_T = 1; then
+ REPLACE_FNMATCH=1
+ fi
fi
if test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; then
gl_REPLACE_FNMATCH_H
diff --git a/modules/fnmatch b/modules/fnmatch
index 8114ecf437..edd5619317 100644
--- a/modules/fnmatch
+++ b/modules/fnmatch
@@ -9,27 +9,37 @@ m4/fnmatch.m4
Depends-on:
fnmatch-h
-alloca-opt [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-attribute [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-btowc [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-builtin-expect [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-flexmember [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-idx [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-isblank [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-iswctype [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-libc-config [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-stdbool [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-stdckdint [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-strnlen [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-wchar [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-wctype-h [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-wmemchr [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-wmempcpy [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-memchr [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-memcmp [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-mempcpy [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-mbsrtowcs [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
-mbsinit [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+alloca-opt [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+attribute [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+builtin-expect [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+flexmember [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+idx [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+isblank [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+libc-config [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+stdbool [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+stdckdint [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+strnlen [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+uchar [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+memchr [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+memcmp [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+mempcpy [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+mbsinit [test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1]
+btowc [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+iswctype [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+mbsrtowcs [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+wchar [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+wctype-h [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+wmemchr [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+wmempcpy [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 0]
+btoc32 [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+c32tolower [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+c32_get_type_test [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+c32_apply_type_test [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+mbsrtoc32s [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+unistr/u32-chr [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+unistr/u32-pcpy [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+unistr/u32-strcat [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
+unistr/u32-strlen [{ test $HAVE_FNMATCH = 0 || test $REPLACE_FNMATCH = 1; }
&& test $SMALL_WCHAR_T = 1]
configure.ac:
gl_FUNC_FNMATCH_POSIX
@@ -47,6 +57,7 @@ Include:
<fnmatch.h>
Link:
+$(LTLIBUNISTRING) when linking with libtool, $(LIBUNISTRING) otherwise
$(MBRTOWC_LIB)
License:
diff --git a/modules/fnmatch-tests b/modules/fnmatch-tests
index 23ef17b03c..2d66f6f361 100644
--- a/modules/fnmatch-tests
+++ b/modules/fnmatch-tests
@@ -45,4 +45,4 @@ TESTS_ENVIRONMENT += \
LOCALE_JA='@LOCALE_JA@' \
LOCALE_ZH_CN='@LOCALE_ZH_CN@'
check_PROGRAMS += test-fnmatch test-fnmatch-w32
-test_fnmatch_LDADD = $(LDADD) $(SETLOCALE_LIB) $(MBRTOWC_LIB)
+test_fnmatch_LDADD = $(LDADD) $(SETLOCALE_LIB) $(LIBUNISTRING) $(MBRTOWC_LIB)
- fnmatch: Overcome wchar_t limitations,
Bruno Haible <=