* posix/fnmatch.c (STRUCT): Define.

(fnmatch): Pass NULL as last argument to internal_fn{,w}match.
	* posix/fnmatch_loop.c (struct STRUCT): New type.
	(FCT): Add ends argument.  If ends != NULL and normal * is
	seen in the pattern, store current pattern and string pointers
	and return.  Adjust recursive calls.
	(EXT): Adjust FCT callers.
	(STRUCT): Undef at the end of the file.
	* posix/Makefile (tests): Add tst-fnmatch2.
	* posix/tst-fnmatch2.c: New test.
This commit is contained in:
Ulrich Drepper 2007-04-01 19:44:33 +00:00
parent ed09a96ca8
commit 9700b0390e
4 changed files with 77 additions and 30 deletions

View File

@ -1,3 +1,16 @@
2007-03-27 Jakub Jelinek <jakub@redhat.com>
* posix/fnmatch.c (STRUCT): Define.
(fnmatch): Pass NULL as last argument to internal_fn{,w}match.
* posix/fnmatch_loop.c (struct STRUCT): New type.
(FCT): Add ends argument. If ends != NULL and normal * is
seen in the pattern, store current pattern and string pointers
and return. Adjust recursive calls.
(EXT): Adjust FCT callers.
(STRUCT): Undef at the end of the file.
* posix/Makefile (tests): Add tst-fnmatch2.
* posix/tst-fnmatch2.c: New test.
2007-04-01 Jakub Jelinek <jakub@redhat.com> 2007-04-01 Jakub Jelinek <jakub@redhat.com>
* sysdeps/ia64/fpu/fesetround.c (fesetround): Return 0 on success * sysdeps/ia64/fpu/fesetround.c (fesetround): Return 0 on success

View File

@ -90,7 +90,7 @@ tests := tstgetopt testfnm runtests runptests \
tst-execv1 tst-execv2 tst-execl1 tst-execl2 \ tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
tst-execve1 tst-execve2 tst-execle1 tst-execle2 \ tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \ tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
tst-getaddrinfo3 tst-getaddrinfo3 tst-fnmatch2
xtests := bug-ga2 xtests := bug-ga2
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
test-srcs := globtest test-srcs := globtest

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -209,6 +209,7 @@ __wcschrnul (s, c)
# define FCT internal_fnmatch # define FCT internal_fnmatch
# define EXT ext_match # define EXT ext_match
# define END end_pattern # define END end_pattern
# define STRUCT fnmatch_struct
# define L(CS) CS # define L(CS) CS
# ifdef _LIBC # ifdef _LIBC
# define BTOWC(C) __btowc (C) # define BTOWC(C) __btowc (C)
@ -235,7 +236,8 @@ __wcschrnul (s, c)
# define INT wint_t # define INT wint_t
# define FCT internal_fnwmatch # define FCT internal_fnwmatch
# define EXT ext_wmatch # define EXT ext_wmatch
# define END end_wpattern # define END end_wpattern
# define STRUCT fnwmatch_struct
# define L(CS) L##CS # define L(CS) L##CS
# define BTOWC(C) (C) # define BTOWC(C) (C)
# define STRLEN(S) __wcslen (S) # define STRLEN(S) __wcslen (S)
@ -397,12 +399,12 @@ fnmatch (pattern, string, flags)
} }
return internal_fnwmatch (wpattern, wstring, wstring + n, return internal_fnwmatch (wpattern, wstring, wstring + n,
flags & FNM_PERIOD, flags); flags & FNM_PERIOD, flags, NULL);
} }
# endif /* mbstate_t and mbsrtowcs or _LIBC. */ # endif /* mbstate_t and mbsrtowcs or _LIBC. */
return internal_fnmatch (pattern, string, string + strlen (string), return internal_fnmatch (pattern, string, string + strlen (string),
flags & FNM_PERIOD, flags); flags & FNM_PERIOD, flags, NULL);
} }
# ifdef _LIBC # ifdef _LIBC

View File

@ -1,5 +1,5 @@
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2003,2004,2005 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2003,2004,2005,
Free Software Foundation, Inc. 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -17,10 +17,18 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
struct STRUCT
{
const CHAR *pattern;
const CHAR *string;
int no_leading_period;
};
/* Match STRING against the filename pattern PATTERN, returning zero if /* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */ it matches, nonzero if not. */
static int FCT (const CHAR *pattern, const CHAR *string, static int FCT (const CHAR *pattern, const CHAR *string,
const CHAR *string_end, int no_leading_period, int flags) const CHAR *string_end, int no_leading_period, int flags,
struct STRUCT *ends)
internal_function; internal_function;
static int EXT (INT opt, const CHAR *pattern, const CHAR *string, static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
const CHAR *string_end, int no_leading_period, int flags) const CHAR *string_end, int no_leading_period, int flags)
@ -29,12 +37,13 @@ static const CHAR *END (const CHAR *patternp) internal_function;
static int static int
internal_function internal_function
FCT (pattern, string, string_end, no_leading_period, flags) FCT (pattern, string, string_end, no_leading_period, flags, ends)
const CHAR *pattern; const CHAR *pattern;
const CHAR *string; const CHAR *string;
const CHAR *string_end; const CHAR *string_end;
int no_leading_period; int no_leading_period;
int flags; int flags;
struct STRUCT *ends;
{ {
register const CHAR *p = pattern, *n = string; register const CHAR *p = pattern, *n = string;
register UCHAR c; register UCHAR c;
@ -97,6 +106,13 @@ FCT (pattern, string, string_end, no_leading_period, flags)
if (res != -1) if (res != -1)
return res; return res;
} }
else if (ends != NULL)
{
ends->pattern = p - 1;
ends->string = n;
ends->no_leading_period = no_leading_period;
return 0;
}
if (n != string_end && *n == L('.') && no_leading_period) if (n != string_end && *n == L('.') && no_leading_period)
return FNM_NOMATCH; return FNM_NOMATCH;
@ -157,7 +173,9 @@ FCT (pattern, string, string_end, no_leading_period, flags)
else else
{ {
const CHAR *endp; const CHAR *endp;
struct STRUCT end;
end.pattern = NULL;
endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'), endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'),
string_end - n); string_end - n);
if (endp == NULL) if (endp == NULL)
@ -170,36 +188,46 @@ FCT (pattern, string, string_end, no_leading_period, flags)
{ {
int flags2 = ((flags & FNM_FILE_NAME) int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD)); ? flags : (flags & ~FNM_PERIOD));
int no_leading_period2 = no_leading_period;
for (--p; n < endp; ++n, no_leading_period2 = 0) for (--p; n < endp; ++n, no_leading_period = 0)
if (FCT (p, n, string_end, no_leading_period2, flags2) if (FCT (p, n, string_end, no_leading_period, flags2,
== 0) &end) == 0)
return 0; goto found;
} }
else if (c == L('/') && (flags & FNM_FILE_NAME)) else if (c == L('/') && (flags & FNM_FILE_NAME))
{ {
while (n < string_end && *n != L('/')) while (n < string_end && *n != L('/'))
++n; ++n;
if (n < string_end && *n == L('/') if (n < string_end && *n == L('/')
&& (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags,
== 0)) NULL) == 0))
return 0; return 0;
} }
else else
{ {
int flags2 = ((flags & FNM_FILE_NAME) int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD)); ? flags : (flags & ~FNM_PERIOD));
int no_leading_period2 = no_leading_period;
if (c == L('\\') && !(flags & FNM_NOESCAPE)) if (c == L('\\') && !(flags & FNM_NOESCAPE))
c = *p; c = *p;
c = FOLD (c); c = FOLD (c);
for (--p; n < endp; ++n, no_leading_period2 = 0) for (--p; n < endp; ++n, no_leading_period = 0)
if (FOLD ((UCHAR) *n) == c if (FOLD ((UCHAR) *n) == c
&& (FCT (p, n, string_end, no_leading_period2, flags2) && (FCT (p, n, string_end, no_leading_period, flags2,
== 0)) &end) == 0))
return 0; {
found:
if (end.pattern == NULL)
return 0;
break;
}
if (end.pattern != NULL)
{
p = end.pattern;
n = end.string;
no_leading_period = end.no_leading_period;
continue;
}
} }
} }
@ -1098,7 +1126,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
switch (opt) switch (opt)
{ {
case L('*'): case L('*'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0) if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
return 0; return 0;
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -1109,7 +1137,8 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
/* First match the prefix with the current pattern with the /* First match the prefix with the current pattern with the
current pattern. */ current pattern. */
if (FCT (list->str, string, rs, no_leading_period, if (FCT (list->str, string, rs, no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
NULL) == 0
/* This was successful. Now match the rest with the rest /* This was successful. Now match the rest with the rest
of the pattern. */ of the pattern. */
&& (FCT (p, rs, string_end, && (FCT (p, rs, string_end,
@ -1117,7 +1146,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
? no_leading_period ? no_leading_period
: rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
flags & FNM_FILE_NAME flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0 ? flags : flags & ~FNM_PERIOD, NULL) == 0
/* This didn't work. Try the whole pattern. */ /* This didn't work. Try the whole pattern. */
|| (rs != string || (rs != string
&& FCT (pattern - 1, rs, string_end, && FCT (pattern - 1, rs, string_end,
@ -1126,7 +1155,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
: (rs[-1] == '/' && NO_LEADING_PERIOD (flags) : (rs[-1] == '/' && NO_LEADING_PERIOD (flags)
? 1 : 0), ? 1 : 0),
flags & FNM_FILE_NAME flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0))) ? flags : flags & ~FNM_PERIOD, NULL) == 0)))
/* It worked. Signal success. */ /* It worked. Signal success. */
return 0; return 0;
} }
@ -1136,7 +1165,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
return FNM_NOMATCH; return FNM_NOMATCH;
case L('?'): case L('?'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0) if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
return 0; return 0;
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -1148,7 +1177,8 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
pattern list. */ pattern list. */
if (FCT (STRCAT (list->str, p), string, string_end, if (FCT (STRCAT (list->str, p), string, string_end,
no_leading_period, no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
NULL) == 0)
/* It worked. Signal success. */ /* It worked. Signal success. */
return 0; return 0;
while ((list = list->next) != NULL); while ((list = list->next) != NULL);
@ -1163,7 +1193,8 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
for (runp = list; runp != NULL; runp = runp->next) for (runp = list; runp != NULL; runp = runp->next)
if (FCT (runp->str, string, rs, no_leading_period, if (FCT (runp->str, string, rs, no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
NULL) == 0)
break; break;
/* If none of the patterns matched see whether the rest does. */ /* If none of the patterns matched see whether the rest does. */
@ -1172,8 +1203,8 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
rs == string rs == string
? no_leading_period ? no_leading_period
: rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
== 0)) NULL) == 0))
/* This is successful. */ /* This is successful. */
return 0; return 0;
} }
@ -1198,6 +1229,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
#undef FCT #undef FCT
#undef EXT #undef EXT
#undef END #undef END
#undef STRUCT
#undef MEMPCPY #undef MEMPCPY
#undef MEMCHR #undef MEMCHR
#undef STRCOLL #undef STRCOLL