From 821a6bb4360ae232140ba230724642fed9db613c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 15 Mar 2001 20:04:25 +0000 Subject: [PATCH] Update. * 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. --- ChangeLog | 13 +++++++++++++ include/wchar.h | 1 + manual/pattern.texi | 32 ++++++++++++++++++++++++++++++++ posix/Versions | 4 ++++ posix/fnmatch.c | 16 ++++++++++++++++ posix/fnmatch_loop.c | 39 ++++++++++++++++++--------------------- posix/tst-fnmatch.input | 1 + wcsmbs/wcscat.c | 5 +++-- 8 files changed, 88 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index da0bcbb..b00bf55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2001-03-15 Ulrich Drepper + * 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 6f580b4..818afff 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 6479a1f..f4f1424 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 0d04fcc..a302f7b 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 98c5ffc..df4311a 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 # 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 e9c7af2..9400734 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 6ae0a2a..2191245 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 c63442a..36c02c2 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 , 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) -- 2.7.4