100bf4279Sespie /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
200bf4279Sespie
3f5dd06f4Sespie NOTE: This source is derived from an old version taken from the GNU C
4f5dd06f4Sespie Library (glibc).
500bf4279Sespie
600bf4279Sespie This program is free software; you can redistribute it and/or modify it
700bf4279Sespie under the terms of the GNU General Public License as published by the
800bf4279Sespie Free Software Foundation; either version 2, or (at your option) any
900bf4279Sespie later version.
1000bf4279Sespie
1100bf4279Sespie This program is distributed in the hope that it will be useful,
1200bf4279Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
1300bf4279Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1400bf4279Sespie GNU General Public License for more details.
1500bf4279Sespie
1600bf4279Sespie You should have received a copy of the GNU General Public License
1700bf4279Sespie along with this program; if not, write to the Free Software
18*150b7e42Smiod Foundation, 51 Franklin Street - Fifth Floor,
19*150b7e42Smiod Boston, MA 02110-1301, USA. */
2000bf4279Sespie
2100bf4279Sespie #ifdef HAVE_CONFIG_H
2200bf4279Sespie #if defined (CONFIG_BROKETS)
2300bf4279Sespie /* We use <config.h> instead of "config.h" so that a compilation
2400bf4279Sespie using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
2500bf4279Sespie (which it would do because it found this file in $srcdir). */
2600bf4279Sespie #include <config.h>
2700bf4279Sespie #else
2800bf4279Sespie #include "config.h"
2900bf4279Sespie #endif
3000bf4279Sespie #endif
3100bf4279Sespie
3200bf4279Sespie
3300bf4279Sespie #ifndef _GNU_SOURCE
3400bf4279Sespie #define _GNU_SOURCE
3500bf4279Sespie #endif
3600bf4279Sespie
3700bf4279Sespie /* This code to undef const added in libiberty. */
3800bf4279Sespie #ifndef __STDC__
3900bf4279Sespie /* This is a separate conditional since some stdc systems
4000bf4279Sespie reject `defined (const)'. */
4100bf4279Sespie #ifndef const
4200bf4279Sespie #define const
4300bf4279Sespie #endif
4400bf4279Sespie #endif
4500bf4279Sespie
4600bf4279Sespie #include <errno.h>
4700bf4279Sespie #include <fnmatch.h>
48f5dd06f4Sespie #include <safe-ctype.h>
4900bf4279Sespie
5000bf4279Sespie /* Comment out all this code if we are using the GNU C Library, and are not
5100bf4279Sespie actually compiling the library itself. This code is part of the GNU C
5200bf4279Sespie Library, but also included in many other GNU distributions. Compiling
5300bf4279Sespie and linking in this code is a waste when using the GNU C library
5400bf4279Sespie (especially if it is a shared library). Rather than having every GNU
5500bf4279Sespie program understand `configure --with-gnu-libc' and omit the object files,
5600bf4279Sespie it is simpler to just do this in the source for each such file. */
5700bf4279Sespie
5800bf4279Sespie #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
5900bf4279Sespie
6000bf4279Sespie
6100bf4279Sespie #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
6200bf4279Sespie extern int errno;
6300bf4279Sespie #endif
6400bf4279Sespie
6500bf4279Sespie /* Match STRING against the filename pattern PATTERN, returning zero if
6600bf4279Sespie it matches, nonzero if not. */
6700bf4279Sespie int
fnmatch(const char * pattern,const char * string,int flags)68*150b7e42Smiod fnmatch (const char *pattern, const char *string, int flags)
6900bf4279Sespie {
7000bf4279Sespie register const char *p = pattern, *n = string;
7100bf4279Sespie register unsigned char c;
7200bf4279Sespie
73f5dd06f4Sespie #define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c))
7400bf4279Sespie
7500bf4279Sespie while ((c = *p++) != '\0')
7600bf4279Sespie {
7700bf4279Sespie c = FOLD (c);
7800bf4279Sespie
7900bf4279Sespie switch (c)
8000bf4279Sespie {
8100bf4279Sespie case '?':
8200bf4279Sespie if (*n == '\0')
8300bf4279Sespie return FNM_NOMATCH;
8400bf4279Sespie else if ((flags & FNM_FILE_NAME) && *n == '/')
8500bf4279Sespie return FNM_NOMATCH;
8600bf4279Sespie else if ((flags & FNM_PERIOD) && *n == '.' &&
8700bf4279Sespie (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
8800bf4279Sespie return FNM_NOMATCH;
8900bf4279Sespie break;
9000bf4279Sespie
9100bf4279Sespie case '\\':
9200bf4279Sespie if (!(flags & FNM_NOESCAPE))
9300bf4279Sespie {
9400bf4279Sespie c = *p++;
9500bf4279Sespie c = FOLD (c);
9600bf4279Sespie }
9700bf4279Sespie if (FOLD ((unsigned char)*n) != c)
9800bf4279Sespie return FNM_NOMATCH;
9900bf4279Sespie break;
10000bf4279Sespie
10100bf4279Sespie case '*':
10200bf4279Sespie if ((flags & FNM_PERIOD) && *n == '.' &&
10300bf4279Sespie (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
10400bf4279Sespie return FNM_NOMATCH;
10500bf4279Sespie
10600bf4279Sespie for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
10700bf4279Sespie if (((flags & FNM_FILE_NAME) && *n == '/') ||
10800bf4279Sespie (c == '?' && *n == '\0'))
10900bf4279Sespie return FNM_NOMATCH;
11000bf4279Sespie
11100bf4279Sespie if (c == '\0')
11200bf4279Sespie return 0;
11300bf4279Sespie
11400bf4279Sespie {
11500bf4279Sespie unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
11600bf4279Sespie c1 = FOLD (c1);
11700bf4279Sespie for (--p; *n != '\0'; ++n)
11800bf4279Sespie if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
11900bf4279Sespie fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
12000bf4279Sespie return 0;
12100bf4279Sespie return FNM_NOMATCH;
12200bf4279Sespie }
12300bf4279Sespie
12400bf4279Sespie case '[':
12500bf4279Sespie {
12600bf4279Sespie /* Nonzero if the sense of the character class is inverted. */
127*150b7e42Smiod register int negate;
12800bf4279Sespie
12900bf4279Sespie if (*n == '\0')
13000bf4279Sespie return FNM_NOMATCH;
13100bf4279Sespie
13200bf4279Sespie if ((flags & FNM_PERIOD) && *n == '.' &&
13300bf4279Sespie (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
13400bf4279Sespie return FNM_NOMATCH;
13500bf4279Sespie
136*150b7e42Smiod negate = (*p == '!' || *p == '^');
137*150b7e42Smiod if (negate)
13800bf4279Sespie ++p;
13900bf4279Sespie
14000bf4279Sespie c = *p++;
14100bf4279Sespie for (;;)
14200bf4279Sespie {
14300bf4279Sespie register unsigned char cstart = c, cend = c;
14400bf4279Sespie
14500bf4279Sespie if (!(flags & FNM_NOESCAPE) && c == '\\')
14600bf4279Sespie cstart = cend = *p++;
14700bf4279Sespie
14800bf4279Sespie cstart = cend = FOLD (cstart);
14900bf4279Sespie
15000bf4279Sespie if (c == '\0')
15100bf4279Sespie /* [ (unterminated) loses. */
15200bf4279Sespie return FNM_NOMATCH;
15300bf4279Sespie
15400bf4279Sespie c = *p++;
15500bf4279Sespie c = FOLD (c);
15600bf4279Sespie
15700bf4279Sespie if ((flags & FNM_FILE_NAME) && c == '/')
15800bf4279Sespie /* [/] can never match. */
15900bf4279Sespie return FNM_NOMATCH;
16000bf4279Sespie
16100bf4279Sespie if (c == '-' && *p != ']')
16200bf4279Sespie {
16300bf4279Sespie cend = *p++;
16400bf4279Sespie if (!(flags & FNM_NOESCAPE) && cend == '\\')
16500bf4279Sespie cend = *p++;
16600bf4279Sespie if (cend == '\0')
16700bf4279Sespie return FNM_NOMATCH;
16800bf4279Sespie cend = FOLD (cend);
16900bf4279Sespie
17000bf4279Sespie c = *p++;
17100bf4279Sespie }
17200bf4279Sespie
17300bf4279Sespie if (FOLD ((unsigned char)*n) >= cstart
17400bf4279Sespie && FOLD ((unsigned char)*n) <= cend)
17500bf4279Sespie goto matched;
17600bf4279Sespie
17700bf4279Sespie if (c == ']')
17800bf4279Sespie break;
17900bf4279Sespie }
180*150b7e42Smiod if (!negate)
18100bf4279Sespie return FNM_NOMATCH;
18200bf4279Sespie break;
18300bf4279Sespie
18400bf4279Sespie matched:;
18500bf4279Sespie /* Skip the rest of the [...] that already matched. */
18600bf4279Sespie while (c != ']')
18700bf4279Sespie {
18800bf4279Sespie if (c == '\0')
18900bf4279Sespie /* [... (unterminated) loses. */
19000bf4279Sespie return FNM_NOMATCH;
19100bf4279Sespie
19200bf4279Sespie c = *p++;
19300bf4279Sespie if (!(flags & FNM_NOESCAPE) && c == '\\')
19400bf4279Sespie /* XXX 1003.2d11 is unclear if this is right. */
19500bf4279Sespie ++p;
19600bf4279Sespie }
197*150b7e42Smiod if (negate)
19800bf4279Sespie return FNM_NOMATCH;
19900bf4279Sespie }
20000bf4279Sespie break;
20100bf4279Sespie
20200bf4279Sespie default:
20300bf4279Sespie if (c != FOLD ((unsigned char)*n))
20400bf4279Sespie return FNM_NOMATCH;
20500bf4279Sespie }
20600bf4279Sespie
20700bf4279Sespie ++n;
20800bf4279Sespie }
20900bf4279Sespie
21000bf4279Sespie if (*n == '\0')
21100bf4279Sespie return 0;
21200bf4279Sespie
21300bf4279Sespie if ((flags & FNM_LEADING_DIR) && *n == '/')
21400bf4279Sespie /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
21500bf4279Sespie return 0;
21600bf4279Sespie
21700bf4279Sespie return FNM_NOMATCH;
21800bf4279Sespie }
21900bf4279Sespie
22000bf4279Sespie #endif /* _LIBC or not __GNU_LIBRARY__. */
221