mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 22:08:56 +00:00
fnmatch: Use native on Unix, emulate on Win32
This commit is contained in:
parent
6507743400
commit
e9c6571d7f
489
src/fnmatch.c
489
src/fnmatch.c
@ -1,489 +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 <errno.h>
|
|
||||||
#include <fnmatch.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#if defined _MSC_VER
|
|
||||||
# define HAVE_STRING_H 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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 _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 ();
|
|
||||||
# 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 = (unsigned char) 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 = (unsigned char) 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 = (unsigned char) 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;
|
|
||||||
fn = (unsigned char) FOLD ((unsigned char) *n);
|
|
||||||
|
|
||||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
|
||||||
{
|
|
||||||
if (*p == '\0')
|
|
||||||
return FNM_NOMATCH;
|
|
||||||
c = (unsigned char) 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 */
|
|
@ -2,6 +2,7 @@
|
|||||||
#define INCLUDE_posix__w32_h__
|
#define INCLUDE_posix__w32_h__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
#define p_lstat(p,b) lstat(p,b)
|
#define p_lstat(p,b) lstat(p,b)
|
||||||
#define p_readlink(a, b, c) readlink(a, b, c)
|
#define p_readlink(a, b, c) readlink(a, b, c)
|
||||||
@ -10,5 +11,6 @@
|
|||||||
#define p_mkdir(p,m) mkdir(p, m)
|
#define p_mkdir(p,m) mkdir(p, m)
|
||||||
#define p_fsync(fd) fsync(fd)
|
#define p_fsync(fd) fsync(fd)
|
||||||
#define p_realpath(p, po) realpath(p, po)
|
#define p_realpath(p, po) realpath(p, po)
|
||||||
|
#define p_fnmatch(p, s, f) fnmatch(p, s, f)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "fnmatch.h"
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "posix.h"
|
||||||
|
|
||||||
#ifdef _MSV_VER
|
#ifdef _MSV_VER
|
||||||
# include <Shlwapi.h>
|
# include <Shlwapi.h>
|
||||||
#else
|
|
||||||
# include <fnmatch.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void git_libgit2_version(int *major, int *minor, int *rev)
|
void git_libgit2_version(int *major, int *minor, int *rev)
|
||||||
@ -31,7 +29,7 @@ int git__fnmatch(const char *pattern, const char *name, int flags)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = fnmatch(pattern, name, flags);
|
ret = p_fnmatch(pattern, name, flags);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case 0:
|
case 0:
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
|
205
src/win32/fnmatch.c
Normal file
205
src/win32/fnmatch.c
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1989, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Guido van Rossum.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
|
||||||
|
* Compares a filename or pathname to a pattern.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fnmatch.h"
|
||||||
|
|
||||||
|
#define EOS '\0'
|
||||||
|
|
||||||
|
#define RANGE_MATCH 1
|
||||||
|
#define RANGE_NOMATCH 0
|
||||||
|
#define RANGE_ERROR (-1)
|
||||||
|
|
||||||
|
static int rangematch(const char *, char, int, char **);
|
||||||
|
|
||||||
|
int
|
||||||
|
p_fnmatch(const char *pattern, const char *string, int flags)
|
||||||
|
{
|
||||||
|
const char *stringstart;
|
||||||
|
char *newp;
|
||||||
|
char c, test;
|
||||||
|
|
||||||
|
for (stringstart = string;;)
|
||||||
|
switch (c = *pattern++) {
|
||||||
|
case EOS:
|
||||||
|
if ((flags & FNM_LEADING_DIR) && *string == '/')
|
||||||
|
return (0);
|
||||||
|
return (*string == EOS ? 0 : FNM_NOMATCH);
|
||||||
|
case '?':
|
||||||
|
if (*string == EOS)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
if (*string == '/' && (flags & FNM_PATHNAME))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||||
|
(string == stringstart ||
|
||||||
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
++string;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
c = *pattern;
|
||||||
|
/* Collapse multiple stars. */
|
||||||
|
while (c == '*')
|
||||||
|
c = *++pattern;
|
||||||
|
|
||||||
|
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||||
|
(string == stringstart ||
|
||||||
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
/* Optimize for pattern with * at end or before /. */
|
||||||
|
if (c == EOS) {
|
||||||
|
if (flags & FNM_PATHNAME)
|
||||||
|
return ((flags & FNM_LEADING_DIR) ||
|
||||||
|
strchr(string, '/') == NULL ?
|
||||||
|
0 : FNM_NOMATCH);
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
} else if (c == '/' && (flags & FNM_PATHNAME)) {
|
||||||
|
if ((string = strchr(string, '/')) == NULL)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* General case, use recursion. */
|
||||||
|
while ((test = *string) != EOS) {
|
||||||
|
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
|
||||||
|
return (0);
|
||||||
|
if (test == '/' && (flags & FNM_PATHNAME))
|
||||||
|
break;
|
||||||
|
++string;
|
||||||
|
}
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
case '[':
|
||||||
|
if (*string == EOS)
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
if (*string == '/' && (flags & FNM_PATHNAME))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||||
|
(string == stringstart ||
|
||||||
|
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
|
||||||
|
switch (rangematch(pattern, *string, flags, &newp)) {
|
||||||
|
case RANGE_ERROR:
|
||||||
|
/* not a good range, treat as normal text */
|
||||||
|
goto normal;
|
||||||
|
case RANGE_MATCH:
|
||||||
|
pattern = newp;
|
||||||
|
break;
|
||||||
|
case RANGE_NOMATCH:
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
}
|
||||||
|
++string;
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
if (!(flags & FNM_NOESCAPE)) {
|
||||||
|
if ((c = *pattern++) == EOS) {
|
||||||
|
c = '\\';
|
||||||
|
--pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
normal:
|
||||||
|
if (c != *string && !((flags & FNM_CASEFOLD) &&
|
||||||
|
(tolower((unsigned char)c) ==
|
||||||
|
tolower((unsigned char)*string))))
|
||||||
|
return (FNM_NOMATCH);
|
||||||
|
++string;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rangematch(const char *pattern, char test, int flags, char **newp)
|
||||||
|
{
|
||||||
|
int negate, ok;
|
||||||
|
char c, c2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A bracket expression starting with an unquoted circumflex
|
||||||
|
* character produces unspecified results (IEEE 1003.2-1992,
|
||||||
|
* 3.13.2). This implementation treats it like '!', for
|
||||||
|
* consistency with the regular expression syntax.
|
||||||
|
* J.T. Conklin (conklin@ngai.kaleida.com)
|
||||||
|
*/
|
||||||
|
if ((negate = (*pattern == '!' || *pattern == '^')))
|
||||||
|
++pattern;
|
||||||
|
|
||||||
|
if (flags & FNM_CASEFOLD)
|
||||||
|
test = (char)tolower((unsigned char)test);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A right bracket shall lose its special meaning and represent
|
||||||
|
* itself in a bracket expression if it occurs first in the list.
|
||||||
|
* -- POSIX.2 2.8.3.2
|
||||||
|
*/
|
||||||
|
ok = 0;
|
||||||
|
c = *pattern++;
|
||||||
|
do {
|
||||||
|
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||||
|
c = *pattern++;
|
||||||
|
if (c == EOS)
|
||||||
|
return (RANGE_ERROR);
|
||||||
|
if (c == '/' && (flags & FNM_PATHNAME))
|
||||||
|
return (RANGE_NOMATCH);
|
||||||
|
if ((flags & FNM_CASEFOLD))
|
||||||
|
c = (char)tolower((unsigned char)c);
|
||||||
|
if (*pattern == '-'
|
||||||
|
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
|
||||||
|
pattern += 2;
|
||||||
|
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
|
||||||
|
c2 = *pattern++;
|
||||||
|
if (c2 == EOS)
|
||||||
|
return (RANGE_ERROR);
|
||||||
|
if (flags & FNM_CASEFOLD)
|
||||||
|
c2 = (char)tolower((unsigned char)c2);
|
||||||
|
if (c <= test && test <= c2)
|
||||||
|
ok = 1;
|
||||||
|
} else if (c == test)
|
||||||
|
ok = 1;
|
||||||
|
} while ((c = *pattern++) != ']');
|
||||||
|
|
||||||
|
*newp = (char *)pattern;
|
||||||
|
return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
|
||||||
|
}
|
||||||
|
|
48
src/win32/fnmatch.h
Normal file
48
src/win32/fnmatch.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDE_fnmatch__w32_h__
|
||||||
|
#define INCLUDE_fnmatch__w32_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#define FNM_NOMATCH 1 /* Match failed. */
|
||||||
|
#define FNM_NOSYS 2 /* Function not supported (unused). */
|
||||||
|
|
||||||
|
#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
|
||||||
|
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
|
||||||
|
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
|
||||||
|
#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
|
||||||
|
#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
|
||||||
|
|
||||||
|
#define FNM_IGNORECASE FNM_CASEFOLD
|
||||||
|
#define FNM_FILE_NAME FNM_PATHNAME
|
||||||
|
|
||||||
|
extern int p_fnmatch(const char *pattern, const char *string, int flags);
|
||||||
|
|
||||||
|
#endif /* _FNMATCH_H */
|
||||||
|
|
@ -2,6 +2,7 @@
|
|||||||
#define INCLUDE_posix__w32_h__
|
#define INCLUDE_posix__w32_h__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "fnmatch.h"
|
||||||
|
|
||||||
GIT_INLINE(int) p_link(const char *GIT_UNUSED(old), const char *GIT_UNUSED(new))
|
GIT_INLINE(int) p_link(const char *GIT_UNUSED(old), const char *GIT_UNUSED(new))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user