1*8feb0f0bSmrg /* Copyright (C) 1991-2020 Free Software Foundation, Inc.
21debfc3dSmrg
31debfc3dSmrg NOTE: This source is derived from an old version taken from the GNU C
41debfc3dSmrg Library (glibc).
51debfc3dSmrg
61debfc3dSmrg This program is free software; you can redistribute it and/or modify it
71debfc3dSmrg under the terms of the GNU General Public License as published by the
81debfc3dSmrg Free Software Foundation; either version 2, or (at your option) any
91debfc3dSmrg later version.
101debfc3dSmrg
111debfc3dSmrg This program is distributed in the hope that it will be useful,
121debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with this program; if not, write to the Free Software
181debfc3dSmrg Foundation, 51 Franklin Street - Fifth Floor,
191debfc3dSmrg Boston, MA 02110-1301, USA. */
201debfc3dSmrg
211debfc3dSmrg #ifdef HAVE_CONFIG_H
221debfc3dSmrg #if defined (CONFIG_BROKETS)
231debfc3dSmrg /* We use <config.h> instead of "config.h" so that a compilation
241debfc3dSmrg using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
251debfc3dSmrg (which it would do because it found this file in $srcdir). */
261debfc3dSmrg #include <config.h>
271debfc3dSmrg #else
281debfc3dSmrg #include "config.h"
291debfc3dSmrg #endif
301debfc3dSmrg #endif
311debfc3dSmrg
321debfc3dSmrg
331debfc3dSmrg #ifndef _GNU_SOURCE
341debfc3dSmrg #define _GNU_SOURCE
351debfc3dSmrg #endif
361debfc3dSmrg
371debfc3dSmrg /* This code to undef const added in libiberty. */
381debfc3dSmrg #ifndef __STDC__
391debfc3dSmrg /* This is a separate conditional since some stdc systems
401debfc3dSmrg reject `defined (const)'. */
411debfc3dSmrg #ifndef const
421debfc3dSmrg #define const
431debfc3dSmrg #endif
441debfc3dSmrg #endif
451debfc3dSmrg
461debfc3dSmrg #include <errno.h>
471debfc3dSmrg #include <fnmatch.h>
481debfc3dSmrg #include <safe-ctype.h>
491debfc3dSmrg
501debfc3dSmrg /* Comment out all this code if we are using the GNU C Library, and are not
511debfc3dSmrg actually compiling the library itself. This code is part of the GNU C
521debfc3dSmrg Library, but also included in many other GNU distributions. Compiling
531debfc3dSmrg and linking in this code is a waste when using the GNU C library
541debfc3dSmrg (especially if it is a shared library). Rather than having every GNU
551debfc3dSmrg program understand `configure --with-gnu-libc' and omit the object files,
561debfc3dSmrg it is simpler to just do this in the source for each such file. */
571debfc3dSmrg
581debfc3dSmrg #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
591debfc3dSmrg
601debfc3dSmrg
611debfc3dSmrg #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
621debfc3dSmrg extern int errno;
631debfc3dSmrg #endif
641debfc3dSmrg
651debfc3dSmrg /* Match STRING against the filename pattern PATTERN, returning zero if
661debfc3dSmrg it matches, nonzero if not. */
671debfc3dSmrg int
fnmatch(const char * pattern,const char * string,int flags)681debfc3dSmrg fnmatch (const char *pattern, const char *string, int flags)
691debfc3dSmrg {
701debfc3dSmrg register const char *p = pattern, *n = string;
711debfc3dSmrg register unsigned char c;
721debfc3dSmrg
731debfc3dSmrg #define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c))
741debfc3dSmrg
751debfc3dSmrg while ((c = *p++) != '\0')
761debfc3dSmrg {
771debfc3dSmrg c = FOLD (c);
781debfc3dSmrg
791debfc3dSmrg switch (c)
801debfc3dSmrg {
811debfc3dSmrg case '?':
821debfc3dSmrg if (*n == '\0')
831debfc3dSmrg return FNM_NOMATCH;
841debfc3dSmrg else if ((flags & FNM_FILE_NAME) && *n == '/')
851debfc3dSmrg return FNM_NOMATCH;
861debfc3dSmrg else if ((flags & FNM_PERIOD) && *n == '.' &&
871debfc3dSmrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
881debfc3dSmrg return FNM_NOMATCH;
891debfc3dSmrg break;
901debfc3dSmrg
911debfc3dSmrg case '\\':
921debfc3dSmrg if (!(flags & FNM_NOESCAPE))
931debfc3dSmrg {
941debfc3dSmrg c = *p++;
951debfc3dSmrg c = FOLD (c);
961debfc3dSmrg }
971debfc3dSmrg if (FOLD ((unsigned char)*n) != c)
981debfc3dSmrg return FNM_NOMATCH;
991debfc3dSmrg break;
1001debfc3dSmrg
1011debfc3dSmrg case '*':
1021debfc3dSmrg if ((flags & FNM_PERIOD) && *n == '.' &&
1031debfc3dSmrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
1041debfc3dSmrg return FNM_NOMATCH;
1051debfc3dSmrg
1061debfc3dSmrg for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1071debfc3dSmrg if (((flags & FNM_FILE_NAME) && *n == '/') ||
1081debfc3dSmrg (c == '?' && *n == '\0'))
1091debfc3dSmrg return FNM_NOMATCH;
1101debfc3dSmrg
1111debfc3dSmrg if (c == '\0')
1121debfc3dSmrg return 0;
1131debfc3dSmrg
1141debfc3dSmrg {
1151debfc3dSmrg unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1161debfc3dSmrg c1 = FOLD (c1);
1171debfc3dSmrg for (--p; *n != '\0'; ++n)
1181debfc3dSmrg if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
1191debfc3dSmrg fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1201debfc3dSmrg return 0;
1211debfc3dSmrg return FNM_NOMATCH;
1221debfc3dSmrg }
1231debfc3dSmrg
1241debfc3dSmrg case '[':
1251debfc3dSmrg {
1261debfc3dSmrg /* Nonzero if the sense of the character class is inverted. */
1271debfc3dSmrg register int negate;
1281debfc3dSmrg
1291debfc3dSmrg if (*n == '\0')
1301debfc3dSmrg return FNM_NOMATCH;
1311debfc3dSmrg
1321debfc3dSmrg if ((flags & FNM_PERIOD) && *n == '.' &&
1331debfc3dSmrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
1341debfc3dSmrg return FNM_NOMATCH;
1351debfc3dSmrg
1361debfc3dSmrg negate = (*p == '!' || *p == '^');
1371debfc3dSmrg if (negate)
1381debfc3dSmrg ++p;
1391debfc3dSmrg
1401debfc3dSmrg c = *p++;
1411debfc3dSmrg for (;;)
1421debfc3dSmrg {
1431debfc3dSmrg register unsigned char cstart = c, cend = c;
1441debfc3dSmrg
1451debfc3dSmrg if (!(flags & FNM_NOESCAPE) && c == '\\')
1461debfc3dSmrg cstart = cend = *p++;
1471debfc3dSmrg
1481debfc3dSmrg cstart = cend = FOLD (cstart);
1491debfc3dSmrg
1501debfc3dSmrg if (c == '\0')
1511debfc3dSmrg /* [ (unterminated) loses. */
1521debfc3dSmrg return FNM_NOMATCH;
1531debfc3dSmrg
1541debfc3dSmrg c = *p++;
1551debfc3dSmrg c = FOLD (c);
1561debfc3dSmrg
1571debfc3dSmrg if ((flags & FNM_FILE_NAME) && c == '/')
1581debfc3dSmrg /* [/] can never match. */
1591debfc3dSmrg return FNM_NOMATCH;
1601debfc3dSmrg
1611debfc3dSmrg if (c == '-' && *p != ']')
1621debfc3dSmrg {
1631debfc3dSmrg cend = *p++;
1641debfc3dSmrg if (!(flags & FNM_NOESCAPE) && cend == '\\')
1651debfc3dSmrg cend = *p++;
1661debfc3dSmrg if (cend == '\0')
1671debfc3dSmrg return FNM_NOMATCH;
1681debfc3dSmrg cend = FOLD (cend);
1691debfc3dSmrg
1701debfc3dSmrg c = *p++;
1711debfc3dSmrg }
1721debfc3dSmrg
1731debfc3dSmrg if (FOLD ((unsigned char)*n) >= cstart
1741debfc3dSmrg && FOLD ((unsigned char)*n) <= cend)
1751debfc3dSmrg goto matched;
1761debfc3dSmrg
1771debfc3dSmrg if (c == ']')
1781debfc3dSmrg break;
1791debfc3dSmrg }
1801debfc3dSmrg if (!negate)
1811debfc3dSmrg return FNM_NOMATCH;
1821debfc3dSmrg break;
1831debfc3dSmrg
1841debfc3dSmrg matched:;
1851debfc3dSmrg /* Skip the rest of the [...] that already matched. */
1861debfc3dSmrg while (c != ']')
1871debfc3dSmrg {
1881debfc3dSmrg if (c == '\0')
1891debfc3dSmrg /* [... (unterminated) loses. */
1901debfc3dSmrg return FNM_NOMATCH;
1911debfc3dSmrg
1921debfc3dSmrg c = *p++;
1931debfc3dSmrg if (!(flags & FNM_NOESCAPE) && c == '\\')
1941debfc3dSmrg /* XXX 1003.2d11 is unclear if this is right. */
1951debfc3dSmrg ++p;
1961debfc3dSmrg }
1971debfc3dSmrg if (negate)
1981debfc3dSmrg return FNM_NOMATCH;
1991debfc3dSmrg }
2001debfc3dSmrg break;
2011debfc3dSmrg
2021debfc3dSmrg default:
2031debfc3dSmrg if (c != FOLD ((unsigned char)*n))
2041debfc3dSmrg return FNM_NOMATCH;
2051debfc3dSmrg }
2061debfc3dSmrg
2071debfc3dSmrg ++n;
2081debfc3dSmrg }
2091debfc3dSmrg
2101debfc3dSmrg if (*n == '\0')
2111debfc3dSmrg return 0;
2121debfc3dSmrg
2131debfc3dSmrg if ((flags & FNM_LEADING_DIR) && *n == '/')
2141debfc3dSmrg /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
2151debfc3dSmrg return 0;
2161debfc3dSmrg
2171debfc3dSmrg return FNM_NOMATCH;
2181debfc3dSmrg }
2191debfc3dSmrg
2201debfc3dSmrg #endif /* _LIBC or not __GNU_LIBRARY__. */
221