aboutsummaryrefslogtreecommitdiff
path: root/posix/fnmatch.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-04-26 07:50:45 +0000
committerUlrich Drepper <drepper@redhat.com>1999-04-26 07:50:45 +0000
commit45a89cc6c636d0e68b32e7c5ee43911209d19087 (patch)
treec7fcd9ec4983aec593be0927f20d92fbf24f5005 /posix/fnmatch.c
parent62ece32bb4a0aebd2895d9e16b235eee70ce5ce3 (diff)
downloadglibc-45a89cc6c636d0e68b32e7c5ee43911209d19087.zip
glibc-45a89cc6c636d0e68b32e7c5ee43911209d19087.tar.gz
glibc-45a89cc6c636d0e68b32e7c5ee43911209d19087.tar.bz2
Update.
1999-04-26 Ulrich Drepper <drepper@cygnus.com> * posix/fnmatch.c: Include string.h also for glibc. (fnmatch, case '?'): Optimize if cascades a bit. (fnmatch, case '*'): Correct handling if FNM_PATHNAME is set. * posix/testfnm.c: Add test cases for * with FNM_PATHNAME errors.
Diffstat (limited to 'posix/fnmatch.c')
-rw-r--r--posix/fnmatch.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index dc389ef..e0ff2c3 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This library is free software; you can redistribute it and/or
@@ -29,7 +29,7 @@
#include <fnmatch.h>
#include <ctype.h>
-#if HAVE_STRING_H
+#if HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
@@ -154,9 +154,9 @@ fnmatch (pattern, string, flags)
case '?':
if (*n == '\0')
return FNM_NOMATCH;
- else if ((flags & FNM_FILE_NAME) && *n == '/')
+ else if (*n == '/' && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
- else if ((flags & FNM_PERIOD) && *n == '.' &&
+ else if (*n == '.' && (flags & FNM_PERIOD) &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
return FNM_NOMATCH;
break;
@@ -175,13 +175,13 @@ fnmatch (pattern, string, flags)
break;
case '*':
- if ((flags & FNM_PERIOD) && *n == '.' &&
+ if (*n == '.' && (flags & FNM_PERIOD) &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
- if ((flags & FNM_FILE_NAME) && *n == '/')
+ if (*n == '/' && (flags & FNM_FILE_NAME))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
else if (c == '?')
@@ -199,17 +199,38 @@ fnmatch (pattern, string, flags)
}
if (c == '\0')
- return 0;
+ /* The wildcard(s) is/are the last element of the pattern.
+ If the name is a file name and contains another slash
+ this does mean it cannot match. */
+ return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
+ ? FNM_NOMATCH : 0);
+ else
+ {
+ const char *endp;
- {
- unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
- c1 = FOLD (c1);
- for (--p; *n != '\0'; ++n)
- if ((c == '[' || FOLD ((unsigned char) *n) == c1) &&
- fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
- return 0;
- return FNM_NOMATCH;
- }
+ if (!(flags & FNM_FILE_NAME) || (endp = strchr (n, '/')) == NULL)
+ endp = strchr (n, '\0');
+
+ if (c == '[')
+ {
+ for (--p; n < endp; ++n)
+ if (fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ }
+ else
+ {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *p;
+ c = FOLD (c);
+ for (--p; n < endp; ++n)
+ if (FOLD ((unsigned char) *n) == c
+ && fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ }
+ }
+
+ /* If we come here no match is possible with the wildcard. */
+ return FNM_NOMATCH;
case '[':
{