Merge branch 'nd/no-more-fnmatch'
We started using wildmatch() in place of fnmatch(3); complete the process and stop using fnmatch(3). * nd/no-more-fnmatch: actually remove compat fnmatch source code stop using fnmatch (either native or compat) Revert "test-wildmatch: add "perf" command to compare wildmatch and fnmatch" use wildmatch() directly without fnmatch() wrapper
This commit is contained in:
commit
650c90a185
22
Makefile
22
Makefile
@ -101,14 +101,6 @@ all::
|
||||
#
|
||||
# Define NO_MKSTEMPS if you don't have mkstemps in the C library.
|
||||
#
|
||||
# Define NO_FNMATCH if you don't have fnmatch in the C library.
|
||||
#
|
||||
# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
|
||||
# FNM_CASEFOLD GNU extension.
|
||||
#
|
||||
# Define NO_WILDMATCH if you do not want to use Git's wildmatch
|
||||
# implementation as fnmatch
|
||||
#
|
||||
# Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd
|
||||
# in the C library.
|
||||
#
|
||||
@ -1283,20 +1275,6 @@ endif
|
||||
ifdef NO_STRTOULL
|
||||
COMPAT_CFLAGS += -DNO_STRTOULL
|
||||
endif
|
||||
ifdef NO_FNMATCH
|
||||
COMPAT_CFLAGS += -Icompat/fnmatch
|
||||
COMPAT_CFLAGS += -DNO_FNMATCH
|
||||
COMPAT_OBJS += compat/fnmatch/fnmatch.o
|
||||
else
|
||||
ifdef NO_FNMATCH_CASEFOLD
|
||||
COMPAT_CFLAGS += -Icompat/fnmatch
|
||||
COMPAT_CFLAGS += -DNO_FNMATCH_CASEFOLD
|
||||
COMPAT_OBJS += compat/fnmatch/fnmatch.o
|
||||
endif
|
||||
endif
|
||||
ifndef NO_WILDMATCH
|
||||
COMPAT_CFLAGS += -DUSE_WILDMATCH
|
||||
endif
|
||||
ifdef NO_SETENV
|
||||
COMPAT_CFLAGS += -DNO_SETENV
|
||||
COMPAT_OBJS += compat/setenv.o
|
||||
|
@ -4152,7 +4152,7 @@ static int use_patch(struct patch *p)
|
||||
/* See if it matches any of exclude/include rule */
|
||||
for (i = 0; i < limit_by_name.nr; i++) {
|
||||
struct string_list_item *it = &limit_by_name.items[i];
|
||||
if (!fnmatch(it->string, pathname, 0))
|
||||
if (!wildmatch(it->string, pathname, 0, NULL))
|
||||
return (it->util != NULL);
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ static int match_patterns(const char **pattern, const char *refname)
|
||||
if (!*pattern)
|
||||
return 1; /* no pattern always matches */
|
||||
while (*pattern) {
|
||||
if (!fnmatch(*pattern, refname, 0))
|
||||
if (!wildmatch(*pattern, refname, 0, NULL))
|
||||
return 1;
|
||||
pattern++;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
|
||||
return 0;
|
||||
|
||||
/* Accept only tags that match the pattern, if given */
|
||||
if (pattern && (!is_tag || fnmatch(pattern, path + 10, 0)))
|
||||
if (pattern && (!is_tag || wildmatch(pattern, path + 10, 0, NULL)))
|
||||
return 0;
|
||||
|
||||
/* Is it annotated? */
|
||||
|
@ -864,7 +864,7 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
|
||||
refname[plen] == '/' ||
|
||||
p[plen-1] == '/'))
|
||||
break;
|
||||
if (!fnmatch(p, refname, FNM_PATHNAME))
|
||||
if (!wildmatch(p, refname, WM_PATHNAME, NULL))
|
||||
break;
|
||||
}
|
||||
if (!*pattern)
|
||||
|
@ -22,7 +22,7 @@ static int tail_match(const char **pattern, const char *path)
|
||||
if (snprintf(pathbuf, sizeof(pathbuf), "/%s", path) > sizeof(pathbuf))
|
||||
return error("insanely long ref %.*s...", 20, path);
|
||||
while ((p = *(pattern++)) != NULL) {
|
||||
if (!fnmatch(p, pathbuf, 0))
|
||||
if (!wildmatch(p, pathbuf, 0, NULL))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -87,7 +87,7 @@ static int subpath_matches(const char *path, const char *filter)
|
||||
const char *subpath = path;
|
||||
|
||||
while (subpath) {
|
||||
if (!fnmatch(filter, subpath, 0))
|
||||
if (!wildmatch(filter, subpath, 0, NULL))
|
||||
return subpath - path;
|
||||
subpath = strchr(subpath, '/');
|
||||
if (subpath)
|
||||
|
@ -561,7 +561,7 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
|
||||
return; /* both given explicitly -- nothing to tweak */
|
||||
|
||||
for (ent = reflog_expire_cfg; ent; ent = ent->next) {
|
||||
if (!fnmatch(ent->pattern, ref, 0)) {
|
||||
if (!wildmatch(ent->pattern, ref, 0, NULL)) {
|
||||
if (!(slot & EXPIRE_TOTAL))
|
||||
cb->expire_total = ent->expire_total;
|
||||
if (!(slot & EXPIRE_UNREACH))
|
||||
|
@ -36,7 +36,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
|
||||
{
|
||||
struct show_data *data = cb_data;
|
||||
|
||||
if (!fnmatch(data->pattern, refname, 0)) {
|
||||
if (!wildmatch(data->pattern, refname, 0, NULL)) {
|
||||
if (data->format == REPLACE_FORMAT_SHORT)
|
||||
printf("%s\n", refname);
|
||||
else if (data->format == REPLACE_FORMAT_MEDIUM)
|
||||
|
@ -450,7 +450,7 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
|
||||
slash--;
|
||||
if (!*tail)
|
||||
return 0;
|
||||
if (fnmatch(match_ref_pattern, tail, 0))
|
||||
if (wildmatch(match_ref_pattern, tail, 0, NULL))
|
||||
return 0;
|
||||
if (starts_with(refname, "refs/heads/"))
|
||||
return append_head_ref(refname, sha1, flag, cb_data);
|
||||
|
@ -42,7 +42,7 @@ static int match_pattern(const char **patterns, const char *ref)
|
||||
if (!*patterns)
|
||||
return 1;
|
||||
for (; *patterns; patterns++)
|
||||
if (!fnmatch(*patterns, ref, 0))
|
||||
if (!wildmatch(*patterns, ref, 0, NULL))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,494 +0,0 @@
|
||||
/* 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Enable GNU extensions in fnmatch.h. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* For platforms which support the ISO C amendment 1 functionality we
|
||||
support user defined character classes. */
|
||||
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined NO_FNMATCH || defined NO_FNMATCH_CASEFOLD || \
|
||||
defined _LIBC || !defined __GNU_LIBRARY__
|
||||
|
||||
|
||||
# if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
# else
|
||||
# define ISASCII(c) isascii(c)
|
||||
# endif
|
||||
|
||||
# ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII (c) && isblank (c))
|
||||
# else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
# endif
|
||||
# ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
|
||||
# else
|
||||
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
|
||||
# endif
|
||||
|
||||
# define ISPRINT(c) (ISASCII (c) && isprint (c))
|
||||
# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
|
||||
# define ISALNUM(c) (ISASCII (c) && isalnum (c))
|
||||
# define ISALPHA(c) (ISASCII (c) && isalpha (c))
|
||||
# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
|
||||
# define ISLOWER(c) (ISASCII (c) && islower (c))
|
||||
# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
|
||||
# define ISSPACE(c) (ISASCII (c) && isspace (c))
|
||||
# define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
|
||||
|
||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* The GNU C library provides support for user-defined character classes
|
||||
and the functions from ISO C amendment 1. */
|
||||
# ifdef CHARCLASS_NAME_MAX
|
||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
||||
# else
|
||||
/* This shouldn't happen but some implementation might still have this
|
||||
problem. Use a reasonable default value. */
|
||||
# define CHAR_CLASS_MAX_LENGTH 256
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
||||
# else
|
||||
# define IS_CHAR_CLASS(string) wctype (string)
|
||||
# endif
|
||||
# else
|
||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
||||
|
||||
# define IS_CHAR_CLASS(string) \
|
||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
# if !defined _LIBC && !defined getenv
|
||||
extern char *getenv (const char *name);
|
||||
# endif
|
||||
|
||||
# ifndef errno
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
# ifndef NULL
|
||||
# define NULL 0
|
||||
# endif
|
||||
|
||||
/* This function doesn't exist on most systems. */
|
||||
|
||||
# if !defined HAVE___STRCHRNUL && !defined _LIBC
|
||||
static char *
|
||||
__strchrnul (const char *s, int c)
|
||||
|
||||
|
||||
{
|
||||
char *result = strchr (s, c);
|
||||
if (result == NULL)
|
||||
result = strchr (s, '\0');
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef internal_function
|
||||
/* Inside GNU libc we mark some function in a special way. In other
|
||||
environments simply ignore the marking. */
|
||||
# define internal_function
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int internal_fnmatch __P ((const char *pattern, const char *string,
|
||||
int no_leading_period, int flags))
|
||||
internal_function;
|
||||
static int
|
||||
internal_function
|
||||
internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags)
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
/* Trailing \ loses. */
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD ((unsigned char) *n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++)
|
||||
{
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* A slash does not match a wildcard under FNM_FILE_NAME. */
|
||||
return FNM_NOMATCH;
|
||||
else if (c == '?')
|
||||
{
|
||||
/* A ? needs to match one character. */
|
||||
if (*n == '\0')
|
||||
/* There isn't another character; no match. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
less than three characters. */
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\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;
|
||||
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
for (--p; n < endp; ++n)
|
||||
if (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
else if (c == '/' && (flags & FNM_FILE_NAME))
|
||||
{
|
||||
while (*n != '\0' && *n != '/')
|
||||
++n;
|
||||
if (*n == '/'
|
||||
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
|
||||
flags) == 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *p;
|
||||
c = FOLD (c);
|
||||
for (--p; n < endp; ++n)
|
||||
if (FOLD ((unsigned char) *n) == c
|
||||
&& (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we come here no match is possible with the wildcard. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '.' && no_leading_period && (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* `/' cannot be matched. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char fn = FOLD ((unsigned char) *n);
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD ((unsigned char) *p);
|
||||
++p;
|
||||
|
||||
if (c == fn)
|
||||
goto matched;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
/* Leave room for the null. */
|
||||
char str[CHAR_CLASS_MAX_LENGTH + 1];
|
||||
size_t c1 = 0;
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wctype_t wt;
|
||||
# endif
|
||||
const char *startp = p;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (c1 > CHAR_CLASS_MAX_LENGTH)
|
||||
/* The name is too long and therefore the pattern
|
||||
is ill-formed. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *++p;
|
||||
if (c == ':' && p[1] == ']')
|
||||
{
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (c < 'a' || c >= 'z')
|
||||
{
|
||||
/* This cannot possibly be a character class name.
|
||||
Match it as a normal range. */
|
||||
p = startp;
|
||||
c = '[';
|
||||
goto normal_bracket;
|
||||
}
|
||||
str[c1++] = c;
|
||||
}
|
||||
str[c1] = '\0';
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wt = IS_CHAR_CLASS (str);
|
||||
if (wt == 0)
|
||||
/* Invalid character class name. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (__iswctype (__btowc ((unsigned char) *n), wt))
|
||||
goto matched;
|
||||
# else
|
||||
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|
||||
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|
||||
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|
||||
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|
||||
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|
||||
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|
||||
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|
||||
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|
||||
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|
||||
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|
||||
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|
||||
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
|
||||
goto matched;
|
||||
# endif
|
||||
}
|
||||
else if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
{
|
||||
normal_bracket:
|
||||
if (FOLD (c) == fn)
|
||||
goto matched;
|
||||
|
||||
cold = c;
|
||||
c = *p++;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
/* It is a range. */
|
||||
unsigned char cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (cold <= fn && fn <= FOLD (cend))
|
||||
goto matched;
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
do
|
||||
if (*++p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
while (*p != ':' || p[1] == ']');
|
||||
p += 2;
|
||||
c = *p;
|
||||
}
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD ((unsigned char) *n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
|
||||
# undef FOLD
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fnmatch (const char *pattern, const char *string, int flags)
|
||||
|
||||
|
||||
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
@ -1,84 +0,0 @@
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
|
||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* This value is returned if the implementation does not support
|
||||
`fnmatch'. Since this is not the case here it will never be
|
||||
returned but the conformance test suites still require the symbol
|
||||
to be defined. */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# define FNM_NOSYS (-1)
|
||||
#endif
|
||||
|
||||
/* Match NAME against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__name,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
@ -108,7 +108,6 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
|
||||
HAVE_DEV_TTY = YesPlease
|
||||
ifeq ($(uname_R),5.6)
|
||||
@ -259,7 +258,6 @@ ifeq ($(uname_S),IRIX)
|
||||
# issue, comment out the NO_MMAP statement.
|
||||
NO_MMAP = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH = /usr/gnu/bin/bash
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
@ -279,7 +277,6 @@ ifeq ($(uname_S),IRIX64)
|
||||
# issue, comment out the NO_MMAP statement.
|
||||
NO_MMAP = YesPlease
|
||||
NO_REGEX = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH = /usr/gnu/bin/bash
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
@ -296,7 +293,6 @@ ifeq ($(uname_S),HP-UX)
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_HSTRERROR = YesPlease
|
||||
NO_SYS_SELECT_H = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
NO_NSEC = YesPlease
|
||||
ifeq ($(uname_R),B.11.00)
|
||||
@ -327,7 +323,6 @@ ifeq ($(uname_S),Windows)
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_FNMATCH = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
# NEEDS_LIBICONV = YesPlease
|
||||
NO_ICONV = YesPlease
|
||||
@ -389,13 +384,11 @@ ifeq ($(uname_S),Interix)
|
||||
NO_INET_NTOP = YesPlease
|
||||
NO_INET_PTON = YesPlease
|
||||
NO_SOCKADDR_STORAGE = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_R),5.2)
|
||||
NO_INET_NTOP = YesPlease
|
||||
NO_INET_PTON = YesPlease
|
||||
NO_SOCKADDR_STORAGE = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
endif
|
||||
endif
|
||||
ifeq ($(uname_S),Minix)
|
||||
@ -440,7 +433,6 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
|
||||
NO_D_TYPE_IN_DIRENT = YesPlease
|
||||
NO_HSTRERROR = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_SETENV = YesPlease
|
||||
@ -484,7 +476,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_FNMATCH = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NEEDS_LIBICONV = YesPlease
|
||||
NO_STRTOUMAX = YesPlease
|
||||
@ -538,7 +529,6 @@ ifeq ($(uname_S),QNX)
|
||||
EXPAT_NEEDS_XMLPARSE_H = YesPlease
|
||||
HAVE_STRINGS_H = YesPlease
|
||||
NEEDS_SOCKET = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
NO_GETPAGESIZE = YesPlease
|
||||
NO_ICONV = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
|
28
configure.ac
28
configure.ac
@ -901,34 +901,6 @@ GIT_CHECK_FUNC(strcasestr,
|
||||
[NO_STRCASESTR=YesPlease])
|
||||
GIT_CONF_SUBST([NO_STRCASESTR])
|
||||
#
|
||||
# Define NO_FNMATCH if you don't have fnmatch
|
||||
GIT_CHECK_FUNC(fnmatch,
|
||||
[NO_FNMATCH=],
|
||||
[NO_FNMATCH=YesPlease])
|
||||
GIT_CONF_SUBST([NO_FNMATCH])
|
||||
#
|
||||
# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
|
||||
# FNM_CASEFOLD GNU extension.
|
||||
AC_CACHE_CHECK([whether the fnmatch function supports the FNMATCH_CASEFOLD GNU extension],
|
||||
[ac_cv_c_excellent_fnmatch], [
|
||||
AC_EGREP_CPP(yippeeyeswehaveit,
|
||||
AC_LANG_PROGRAM([
|
||||
#include <fnmatch.h>
|
||||
],
|
||||
[#ifdef FNM_CASEFOLD
|
||||
yippeeyeswehaveit
|
||||
#endif
|
||||
]),
|
||||
[ac_cv_c_excellent_fnmatch=yes],
|
||||
[ac_cv_c_excellent_fnmatch=no])
|
||||
])
|
||||
if test $ac_cv_c_excellent_fnmatch = yes; then
|
||||
NO_FNMATCH_CASEFOLD=
|
||||
else
|
||||
NO_FNMATCH_CASEFOLD=YesPlease
|
||||
fi
|
||||
GIT_CONF_SUBST([NO_FNMATCH_CASEFOLD])
|
||||
#
|
||||
# Define NO_MEMMEM if you don't have memmem.
|
||||
GIT_CHECK_FUNC(memmem,
|
||||
[NO_MEMMEM=],
|
||||
|
@ -67,7 +67,7 @@ static int match_order(const char *path)
|
||||
strbuf_addstr(&p, path);
|
||||
while (p.buf[0]) {
|
||||
char *cp;
|
||||
if (!fnmatch(order[i], p.buf, 0))
|
||||
if (!wildmatch(order[i], p.buf, 0, NULL))
|
||||
return i;
|
||||
cp = strrchr(p.buf, '/');
|
||||
if (!cp)
|
||||
|
11
dir.c
11
dir.c
@ -49,7 +49,9 @@ int strncmp_icase(const char *a, const char *b, size_t count)
|
||||
|
||||
int fnmatch_icase(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
|
||||
return wildmatch(pattern, string,
|
||||
flags | (ignore_case ? WM_CASEFOLD : 0),
|
||||
NULL);
|
||||
}
|
||||
|
||||
inline int git_fnmatch(const struct pathspec_item *item,
|
||||
@ -58,7 +60,7 @@ inline int git_fnmatch(const struct pathspec_item *item,
|
||||
{
|
||||
if (prefix > 0) {
|
||||
if (ps_strncmp(item, pattern, string, prefix))
|
||||
return FNM_NOMATCH;
|
||||
return WM_NOMATCH;
|
||||
pattern += prefix;
|
||||
string += prefix;
|
||||
}
|
||||
@ -76,8 +78,9 @@ inline int git_fnmatch(const struct pathspec_item *item,
|
||||
NULL);
|
||||
else
|
||||
/* wildmatch has not learned no FNM_PATHNAME mode yet */
|
||||
return fnmatch(pattern, string,
|
||||
item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
|
||||
return wildmatch(pattern, string,
|
||||
item->magic & PATHSPEC_ICASE ? WM_CASEFOLD : 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int fnmatch_icase_mem(const char *pattern, int patternlen,
|
||||
|
@ -116,9 +116,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#ifndef USE_WILDMATCH
|
||||
#include <fnmatch.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <regex.h>
|
||||
#include <utime.h>
|
||||
@ -304,16 +301,7 @@ extern char *gitbasename(char *);
|
||||
|
||||
#include "compat/bswap.h"
|
||||
|
||||
#ifdef USE_WILDMATCH
|
||||
#include "wildmatch.h"
|
||||
#define FNM_PATHNAME WM_PATHNAME
|
||||
#define FNM_CASEFOLD WM_CASEFOLD
|
||||
#define FNM_NOMATCH WM_NOMATCH
|
||||
static inline int fnmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
return wildmatch(pattern, string, flags, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* General helper functions */
|
||||
extern void vreportf(const char *prefix, const char *err, va_list params);
|
||||
|
2
refs.c
2
refs.c
@ -1477,7 +1477,7 @@ static int filter_refs(const char *refname, const unsigned char *sha1, int flags
|
||||
void *data)
|
||||
{
|
||||
struct ref_filter *filter = (struct ref_filter *)data;
|
||||
if (fnmatch(filter->pattern, refname, 0))
|
||||
if (wildmatch(filter->pattern, refname, 0, NULL))
|
||||
return 0;
|
||||
return filter->fn(refname, sha1, flags, filter->cb_data);
|
||||
}
|
||||
|
@ -1186,7 +1186,7 @@ int ref_excluded(struct string_list *ref_excludes, const char *path)
|
||||
if (!ref_excludes)
|
||||
return 0;
|
||||
for_each_string_list_item(item, ref_excludes) {
|
||||
if (!fnmatch(item->string, path, 0))
|
||||
if (!wildmatch(item->string, path, 0, NULL))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -14,19 +14,6 @@ match() {
|
||||
! test-wildmatch wildmatch '$3' '$4'
|
||||
"
|
||||
fi
|
||||
if [ $2 = 1 ]; then
|
||||
test_expect_success "fnmatch: match '$3' '$4'" "
|
||||
test-wildmatch fnmatch '$3' '$4'
|
||||
"
|
||||
elif [ $2 = 0 ]; then
|
||||
test_expect_success "fnmatch: no match '$3' '$4'" "
|
||||
! test-wildmatch fnmatch '$3' '$4'
|
||||
"
|
||||
# else
|
||||
# test_expect_success BROKEN_FNMATCH "fnmatch: '$3' '$4'" "
|
||||
# ! test-wildmatch fnmatch '$3' '$4'
|
||||
# "
|
||||
fi
|
||||
}
|
||||
|
||||
imatch() {
|
||||
|
@ -1,85 +1,8 @@
|
||||
#ifdef USE_WILDMATCH
|
||||
#undef USE_WILDMATCH /* We need real fnmatch implementation here */
|
||||
#endif
|
||||
#include "cache.h"
|
||||
#include "wildmatch.h"
|
||||
|
||||
static int perf(int ac, char **av)
|
||||
{
|
||||
struct timeval tv1, tv2;
|
||||
struct stat st;
|
||||
int fd, i, n, flags1 = 0, flags2 = 0;
|
||||
char *buffer, *p;
|
||||
uint32_t usec1, usec2;
|
||||
const char *lang;
|
||||
const char *file = av[0];
|
||||
const char *pattern = av[1];
|
||||
|
||||
lang = getenv("LANG");
|
||||
if (lang && strcmp(lang, "C"))
|
||||
die("Please test it on C locale.");
|
||||
|
||||
if ((fd = open(file, O_RDONLY)) == -1 || fstat(fd, &st))
|
||||
die_errno("file open");
|
||||
|
||||
buffer = xmalloc(st.st_size + 2);
|
||||
if (read(fd, buffer, st.st_size) != st.st_size)
|
||||
die_errno("read");
|
||||
|
||||
buffer[st.st_size] = '\0';
|
||||
buffer[st.st_size + 1] = '\0';
|
||||
for (i = 0; i < st.st_size; i++)
|
||||
if (buffer[i] == '\n')
|
||||
buffer[i] = '\0';
|
||||
|
||||
n = atoi(av[2]);
|
||||
if (av[3] && !strcmp(av[3], "pathname")) {
|
||||
flags1 = WM_PATHNAME;
|
||||
flags2 = FNM_PATHNAME;
|
||||
}
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
for (i = 0; i < n; i++) {
|
||||
for (p = buffer; *p; p += strlen(p) + 1)
|
||||
wildmatch(pattern, p, flags1, NULL);
|
||||
}
|
||||
gettimeofday(&tv2, NULL);
|
||||
|
||||
usec1 = (uint32_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
|
||||
usec1 -= (uint32_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
|
||||
printf("wildmatch %ds %dus\n",
|
||||
(int)(usec1 / 1000000),
|
||||
(int)(usec1 % 1000000));
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
for (i = 0; i < n; i++) {
|
||||
for (p = buffer; *p; p += strlen(p) + 1)
|
||||
fnmatch(pattern, p, flags2);
|
||||
}
|
||||
gettimeofday(&tv2, NULL);
|
||||
|
||||
usec2 = (uint32_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
|
||||
usec2 -= (uint32_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
|
||||
if (usec2 > usec1)
|
||||
printf("fnmatch %ds %dus or %.2f%% slower\n",
|
||||
(int)((usec2 - usec1) / 1000000),
|
||||
(int)((usec2 - usec1) % 1000000),
|
||||
(float)(usec2 - usec1) / usec1 * 100);
|
||||
else
|
||||
printf("fnmatch %ds %dus or %.2f%% faster\n",
|
||||
(int)((usec1 - usec2) / 1000000),
|
||||
(int)((usec1 - usec2) % 1000000),
|
||||
(float)(usec1 - usec2) / usec1 * 100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!strcmp(argv[1], "perf"))
|
||||
return perf(argc - 2, argv + 2);
|
||||
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (argv[i][0] == '/')
|
||||
die("Forward slash is not allowed at the beginning of the\n"
|
||||
@ -93,8 +16,6 @@ int main(int argc, char **argv)
|
||||
return !!wildmatch(argv[3], argv[2], WM_PATHNAME | WM_CASEFOLD, NULL);
|
||||
else if (!strcmp(argv[1], "pathmatch"))
|
||||
return !!wildmatch(argv[3], argv[2], 0, NULL);
|
||||
else if (!strcmp(argv[1], "fnmatch"))
|
||||
return !!fnmatch(argv[3], argv[2], FNM_PATHNAME);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user