Update.
authorUlrich Drepper <drepper@redhat.com>
Thu, 15 Mar 2001 20:04:25 +0000 (20:04 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 15 Mar 2001 20:04:25 +0000 (20:04 +0000)
* 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
include/wchar.h
manual/pattern.texi
posix/Versions
posix/fnmatch.c
posix/fnmatch_loop.c
posix/tst-fnmatch.input
wcsmbs/wcscat.c

index da0bcbb..b00bf55 100644 (file)
--- 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.
index 6f580b4..818afff 100644 (file)
@@ -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,
index 6479a1f..f4f1424 100644 (file)
@@ -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
index 0d04fcc..a302f7b 100644 (file)
@@ -109,4 +109,8 @@ libc {
     # Used in macros.
     __sysconf;
   }
+  GLIBC_2.2.3 {
+    # Extended Interface.
+    fnmatch;
+  }
 }
index 98c5ffc..df4311a 100644 (file)
 # 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__.  */
index e9c7af2..9400734 100644 (file)
@@ -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.  */
index 6ae0a2a..2191245 100644 (file)
@@ -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
index c63442a..36c02c2 100644 (file)
@@ -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)