1*b1e83836Smrg /* Copyright (C) 1991-2022 Free Software Foundation, Inc.
24fee23f9Smrg
34fee23f9Smrg NOTE: This source is derived from an old version taken from the GNU C
44fee23f9Smrg Library (glibc).
54fee23f9Smrg
64fee23f9Smrg This program is free software; you can redistribute it and/or modify it
74fee23f9Smrg under the terms of the GNU General Public License as published by the
84fee23f9Smrg Free Software Foundation; either version 2, or (at your option) any
94fee23f9Smrg later version.
104fee23f9Smrg
114fee23f9Smrg This program is distributed in the hope that it will be useful,
124fee23f9Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
144fee23f9Smrg GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg You should have received a copy of the GNU General Public License
174fee23f9Smrg along with this program; if not, write to the Free Software
184fee23f9Smrg Foundation, 51 Franklin Street - Fifth Floor,
194fee23f9Smrg Boston, MA 02110-1301, USA. */
204fee23f9Smrg
214fee23f9Smrg #ifdef HAVE_CONFIG_H
224fee23f9Smrg #if defined (CONFIG_BROKETS)
234fee23f9Smrg /* We use <config.h> instead of "config.h" so that a compilation
244fee23f9Smrg using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
254fee23f9Smrg (which it would do because it found this file in $srcdir). */
264fee23f9Smrg #include <config.h>
274fee23f9Smrg #else
284fee23f9Smrg #include "config.h"
294fee23f9Smrg #endif
304fee23f9Smrg #endif
314fee23f9Smrg
324fee23f9Smrg
334fee23f9Smrg #ifndef _GNU_SOURCE
344fee23f9Smrg #define _GNU_SOURCE
354fee23f9Smrg #endif
364fee23f9Smrg
374fee23f9Smrg /* This code to undef const added in libiberty. */
384fee23f9Smrg #ifndef __STDC__
394fee23f9Smrg /* This is a separate conditional since some stdc systems
404fee23f9Smrg reject `defined (const)'. */
414fee23f9Smrg #ifndef const
424fee23f9Smrg #define const
434fee23f9Smrg #endif
444fee23f9Smrg #endif
454fee23f9Smrg
464fee23f9Smrg #include <errno.h>
474fee23f9Smrg #include <fnmatch.h>
484fee23f9Smrg #include <safe-ctype.h>
494fee23f9Smrg
504fee23f9Smrg /* Comment out all this code if we are using the GNU C Library, and are not
514fee23f9Smrg actually compiling the library itself. This code is part of the GNU C
524fee23f9Smrg Library, but also included in many other GNU distributions. Compiling
534fee23f9Smrg and linking in this code is a waste when using the GNU C library
544fee23f9Smrg (especially if it is a shared library). Rather than having every GNU
554fee23f9Smrg program understand `configure --with-gnu-libc' and omit the object files,
564fee23f9Smrg it is simpler to just do this in the source for each such file. */
574fee23f9Smrg
584fee23f9Smrg #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
594fee23f9Smrg
604fee23f9Smrg
614fee23f9Smrg #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
624fee23f9Smrg extern int errno;
634fee23f9Smrg #endif
644fee23f9Smrg
654fee23f9Smrg /* Match STRING against the filename pattern PATTERN, returning zero if
664fee23f9Smrg it matches, nonzero if not. */
674fee23f9Smrg int
fnmatch(const char * pattern,const char * string,int flags)684fee23f9Smrg fnmatch (const char *pattern, const char *string, int flags)
694fee23f9Smrg {
704fee23f9Smrg register const char *p = pattern, *n = string;
714fee23f9Smrg register unsigned char c;
724fee23f9Smrg
734fee23f9Smrg #define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c))
744fee23f9Smrg
754fee23f9Smrg while ((c = *p++) != '\0')
764fee23f9Smrg {
774fee23f9Smrg c = FOLD (c);
784fee23f9Smrg
794fee23f9Smrg switch (c)
804fee23f9Smrg {
814fee23f9Smrg case '?':
824fee23f9Smrg if (*n == '\0')
834fee23f9Smrg return FNM_NOMATCH;
844fee23f9Smrg else if ((flags & FNM_FILE_NAME) && *n == '/')
854fee23f9Smrg return FNM_NOMATCH;
864fee23f9Smrg else if ((flags & FNM_PERIOD) && *n == '.' &&
874fee23f9Smrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
884fee23f9Smrg return FNM_NOMATCH;
894fee23f9Smrg break;
904fee23f9Smrg
914fee23f9Smrg case '\\':
924fee23f9Smrg if (!(flags & FNM_NOESCAPE))
934fee23f9Smrg {
944fee23f9Smrg c = *p++;
954fee23f9Smrg c = FOLD (c);
964fee23f9Smrg }
974fee23f9Smrg if (FOLD ((unsigned char)*n) != c)
984fee23f9Smrg return FNM_NOMATCH;
994fee23f9Smrg break;
1004fee23f9Smrg
1014fee23f9Smrg case '*':
1024fee23f9Smrg if ((flags & FNM_PERIOD) && *n == '.' &&
1034fee23f9Smrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
1044fee23f9Smrg return FNM_NOMATCH;
1054fee23f9Smrg
1064fee23f9Smrg for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1074fee23f9Smrg if (((flags & FNM_FILE_NAME) && *n == '/') ||
1084fee23f9Smrg (c == '?' && *n == '\0'))
1094fee23f9Smrg return FNM_NOMATCH;
1104fee23f9Smrg
1114fee23f9Smrg if (c == '\0')
1124fee23f9Smrg return 0;
1134fee23f9Smrg
1144fee23f9Smrg {
1154fee23f9Smrg unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1164fee23f9Smrg c1 = FOLD (c1);
1174fee23f9Smrg for (--p; *n != '\0'; ++n)
1184fee23f9Smrg if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
1194fee23f9Smrg fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1204fee23f9Smrg return 0;
1214fee23f9Smrg return FNM_NOMATCH;
1224fee23f9Smrg }
1234fee23f9Smrg
1244fee23f9Smrg case '[':
1254fee23f9Smrg {
1264fee23f9Smrg /* Nonzero if the sense of the character class is inverted. */
1274fee23f9Smrg register int negate;
1284fee23f9Smrg
1294fee23f9Smrg if (*n == '\0')
1304fee23f9Smrg return FNM_NOMATCH;
1314fee23f9Smrg
1324fee23f9Smrg if ((flags & FNM_PERIOD) && *n == '.' &&
1334fee23f9Smrg (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
1344fee23f9Smrg return FNM_NOMATCH;
1354fee23f9Smrg
1364fee23f9Smrg negate = (*p == '!' || *p == '^');
1374fee23f9Smrg if (negate)
1384fee23f9Smrg ++p;
1394fee23f9Smrg
1404fee23f9Smrg c = *p++;
1414fee23f9Smrg for (;;)
1424fee23f9Smrg {
1434fee23f9Smrg register unsigned char cstart = c, cend = c;
1444fee23f9Smrg
1454fee23f9Smrg if (!(flags & FNM_NOESCAPE) && c == '\\')
1464fee23f9Smrg cstart = cend = *p++;
1474fee23f9Smrg
1484fee23f9Smrg cstart = cend = FOLD (cstart);
1494fee23f9Smrg
1504fee23f9Smrg if (c == '\0')
1514fee23f9Smrg /* [ (unterminated) loses. */
1524fee23f9Smrg return FNM_NOMATCH;
1534fee23f9Smrg
1544fee23f9Smrg c = *p++;
1554fee23f9Smrg c = FOLD (c);
1564fee23f9Smrg
1574fee23f9Smrg if ((flags & FNM_FILE_NAME) && c == '/')
1584fee23f9Smrg /* [/] can never match. */
1594fee23f9Smrg return FNM_NOMATCH;
1604fee23f9Smrg
1614fee23f9Smrg if (c == '-' && *p != ']')
1624fee23f9Smrg {
1634fee23f9Smrg cend = *p++;
1644fee23f9Smrg if (!(flags & FNM_NOESCAPE) && cend == '\\')
1654fee23f9Smrg cend = *p++;
1664fee23f9Smrg if (cend == '\0')
1674fee23f9Smrg return FNM_NOMATCH;
1684fee23f9Smrg cend = FOLD (cend);
1694fee23f9Smrg
1704fee23f9Smrg c = *p++;
1714fee23f9Smrg }
1724fee23f9Smrg
1734fee23f9Smrg if (FOLD ((unsigned char)*n) >= cstart
1744fee23f9Smrg && FOLD ((unsigned char)*n) <= cend)
1754fee23f9Smrg goto matched;
1764fee23f9Smrg
1774fee23f9Smrg if (c == ']')
1784fee23f9Smrg break;
1794fee23f9Smrg }
1804fee23f9Smrg if (!negate)
1814fee23f9Smrg return FNM_NOMATCH;
1824fee23f9Smrg break;
1834fee23f9Smrg
1844fee23f9Smrg matched:;
1854fee23f9Smrg /* Skip the rest of the [...] that already matched. */
1864fee23f9Smrg while (c != ']')
1874fee23f9Smrg {
1884fee23f9Smrg if (c == '\0')
1894fee23f9Smrg /* [... (unterminated) loses. */
1904fee23f9Smrg return FNM_NOMATCH;
1914fee23f9Smrg
1924fee23f9Smrg c = *p++;
1934fee23f9Smrg if (!(flags & FNM_NOESCAPE) && c == '\\')
1944fee23f9Smrg /* XXX 1003.2d11 is unclear if this is right. */
1954fee23f9Smrg ++p;
1964fee23f9Smrg }
1974fee23f9Smrg if (negate)
1984fee23f9Smrg return FNM_NOMATCH;
1994fee23f9Smrg }
2004fee23f9Smrg break;
2014fee23f9Smrg
2024fee23f9Smrg default:
2034fee23f9Smrg if (c != FOLD ((unsigned char)*n))
2044fee23f9Smrg return FNM_NOMATCH;
2054fee23f9Smrg }
2064fee23f9Smrg
2074fee23f9Smrg ++n;
2084fee23f9Smrg }
2094fee23f9Smrg
2104fee23f9Smrg if (*n == '\0')
2114fee23f9Smrg return 0;
2124fee23f9Smrg
2134fee23f9Smrg if ((flags & FNM_LEADING_DIR) && *n == '/')
2144fee23f9Smrg /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
2154fee23f9Smrg return 0;
2164fee23f9Smrg
2174fee23f9Smrg return FNM_NOMATCH;
2184fee23f9Smrg }
2194fee23f9Smrg
2204fee23f9Smrg #endif /* _LIBC or not __GNU_LIBRARY__. */
221