aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--include/wchar.h1
-rw-r--r--manual/pattern.texi32
-rw-r--r--posix/Versions4
-rw-r--r--posix/fnmatch.c16
-rw-r--r--posix/fnmatch_loop.c39
-rw-r--r--posix/tst-fnmatch.input1
-rw-r--r--wcsmbs/wcscat.c5
8 files changed, 88 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index da0bcbbf56..b00bf556bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2001-03-15 Ulrich Drepper <drepper@redhat.com>
+ * posix/tst-fnmatch.input: Add test case for FNM_PERIOD handling with
+ FNM_EXTMATCH.
+
+ * posix/fnmatch_loop.c: Optimize handling of ?() and @().
+ * posix/fnmatch.c: Define STRLEN and STRCAT appropriately.
+
+ * posix/Versions [libc] (GLIBC_2.2.3): Add fnmatch.
+ * posix/fnmatch.c: Define with new default version GLIBC_2.2.3 to
+ avoid running binaries with libc versions without FNM_EXTMATCH support.
+
+ * include/wchar.h: Add prototype for __wcscat.
+ * wcsmbs/wcscat.c: Define __wcscat and make wcscat weak alias.
+
* posix/fnmatch.h (FNM_EXTMATCH): Define.
* posix/fnmatch.c (NO_LEADING_PERIOD): Define.
(posixly_correct): Move global variable here.
diff --git a/include/wchar.h b/include/wchar.h
index 6f580b43fc..818afff3ea 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -11,6 +11,7 @@ extern int __wcsncasecmp (__const wchar_t *__s1, __const wchar_t *__s2,
extern size_t __wcslen (__const wchar_t *__s) __attribute_pure__;
extern size_t __wcsnlen (__const wchar_t *__s, size_t __maxlen)
__attribute_pure__;
+extern wchar_t *__wcscat (wchar_t *dest, const wchar_t *src);
extern wint_t __btowc (int __c);
extern int __mbsinit (__const __mbstate_t *__ps);
extern size_t __mbrtowc (wchar_t *__restrict __pwc,
diff --git a/manual/pattern.texi b/manual/pattern.texi
index 6479a1fbec..f4f1424092 100644
--- a/manual/pattern.texi
+++ b/manual/pattern.texi
@@ -99,6 +99,38 @@ would match the string @samp{foobar/frobozz}.
@comment GNU
@item FNM_CASEFOLD
Ignore case in comparing @var{string} to @var{pattern}.
+
+@comment fnmatch.h
+@comment GNU
+@item FNM_EXTMATCH
+@cindex Korn Shell
+@pindex ksh
+Recognize beside the normal patterns also the extended patterns
+introduced in @file{ksh}. The patterns are written in the form
+explained in the following table where @var{pattern-list} is a @code{|}
+separated list of patterns.
+
+@table @code
+@item ?(@var{pattern-list})
+The pattern matches if zero or one occurences of any of the patterns
+in the @var{pattern-list} allow matching the input string.
+
+@item *(@var{pattern-list})
+The pattern matches if zero or more occurences of any of the patterns
+in the @var{pattern-list} allow matching the input string.
+
+@item +(@var{pattern-list})
+The pattern matches if one or more occurences of any of the patterns
+in the @var{pattern-list} allow matching the input string.
+
+@item @@(@var{pattern-list})
+The pattern matches if exactly one occurence of any of the patterns in
+the @var{pattern-list} allows matching the input string.
+
+@item !(@var{pattern-list})
+The pattern matches if the input string cannot be matched with any of
+the patterns in the @var{pattern-list}.
+@end table
@end table
@node Globbing
diff --git a/posix/Versions b/posix/Versions
index 0d04fccc22..a302f7bed3 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -109,4 +109,8 @@ libc {
# Used in macros.
__sysconf;
}
+ GLIBC_2.2.3 {
+ # Extended Interface.
+ fnmatch;
+ }
}
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index 98c5ffc5ca..df4311a79c 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -55,10 +55,13 @@
# include "../locale/localeinfo.h"
# include "../locale/elem-hash.h"
# include "../locale/coll-lookup.h"
+# include <shlib-compat.h>
# 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. */
@@ -212,6 +215,8 @@ __wcschrnul (s, 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)
@@ -233,6 +238,8 @@ __wcschrnul (s, c)
# 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 STRCOLL(S1, S2) wcscoll (S1, S2)
@@ -355,4 +362,13 @@ fnmatch (pattern, string, flags)
flags & FNM_PERIOD, flags);
}
+# 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
+# endif
+
#endif /* _LIBC or not __GNU_LIBRARY__. */
diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c
index e9c7af2b7e..940073412e 100644
--- a/posix/fnmatch_loop.c
+++ b/posix/fnmatch_loop.c
@@ -1011,6 +1011,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
CHAR str[0];
} *list = NULL;
struct patternlist **lastp = &list;
+ size_t pattern_len = STRLEN (pattern);
const CHAR *p;
const CHAR *rs;
@@ -1049,9 +1050,14 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
{
/* This means we found the end of the pattern. */
#define NEW_PATTERN \
- struct patternlist *newp = alloca (sizeof (struct patternlist) \
- + ((p - startp + 1) \
- * sizeof (CHAR))); \
+ struct patternlist *newp; \
+ \
+ if (opt == L('?') || opt == L('@')) \
+ newp = alloca (sizeof (struct patternlist) \
+ + (pattern_len * sizeof (CHAR))); \
+ else \
+ newp = alloca (sizeof (struct patternlist) \
+ + ((p - startp + 1) * sizeof (CHAR))); \
*((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
newp->next = NULL; \
*lastp = newp; \
@@ -1117,24 +1123,15 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
case L('@'):
do
- {
- for (rs = string; rs <= string_end; ++rs)
- /* First match the prefix with the current pattern with the
- current pattern. */
- if (FCT (list->str, string, rs, no_leading_period,
- flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
- /* This was successful. Now match the rest of the strings
- with the rest of the pattern. */
- && (FCT (p, rs, string_end,
- rs == string
- ? no_leading_period
- : (rs[-1] == '/' && NO_LEADING_PERIOD (flags)
- ? 1 : 0),
- flags & FNM_FILE_NAME
- ? flags : flags & ~FNM_PERIOD) == 0))
- /* It worked. Signal success. */
- return 0;
- }
+ /* I cannot believe it but `strcat' is actually acceptable
+ here. Match the entire string with the prefix from the
+ pattern list and the rest of the pattern following the
+ pattern list. */
+ if (FCT (STRCAT (list->str, p), string, string_end,
+ no_leading_period,
+ flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
+ /* It worked. Signal success. */
+ return 0;
while ((list = list->next) != NULL);
/* None of the patterns lead to a match. */
diff --git a/posix/tst-fnmatch.input b/posix/tst-fnmatch.input
index 6ae0a2aa82..219124556e 100644
--- a/posix/tst-fnmatch.input
+++ b/posix/tst-fnmatch.input
@@ -714,3 +714,4 @@ C "]" "!([!]a[])" 0 EXTMATCH
C ")" "*([)])" 0 EXTMATCH
C "*" "*([*(])" 0 EXTMATCH
C "abcd" "*!(|a)cd" NOMATCH EXTMATCH
+C "ab/.a" "+([abc])/*" NOMATCH EXTMATCH|PATHNAME|PERIOD
diff --git a/wcsmbs/wcscat.c b/wcsmbs/wcscat.c
index c63442a546..36c02c22ec 100644
--- a/wcsmbs/wcscat.c
+++ b/wcsmbs/wcscat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
@@ -22,7 +22,7 @@
/* Append SRC on the end of DEST. */
wchar_t *
-wcscat (dest, src)
+__wcscat (dest, src)
wchar_t *dest;
const wchar_t *src;
{
@@ -48,3 +48,4 @@ wcscat (dest, src)
return dest;
}
+weak_alias (__wcscat, wcscat)