1169695Skan/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. 2169695Skan 3169695SkanNOTE: This source is derived from an old version taken from the GNU C 4169695SkanLibrary (glibc). 5169695Skan 6169695SkanThis program is free software; you can redistribute it and/or modify it 7169695Skanunder the terms of the GNU General Public License as published by the 8169695SkanFree Software Foundation; either version 2, or (at your option) any 9169695Skanlater version. 10169695Skan 11169695SkanThis program is distributed in the hope that it will be useful, 12169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 13169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169695SkanGNU General Public License for more details. 15169695Skan 16169695SkanYou should have received a copy of the GNU General Public License 17169695Skanalong with this program; if not, write to the Free Software 18169695SkanFoundation, 51 Franklin Street - Fifth Floor, 19169695SkanBoston, MA 02110-1301, USA. */ 20169695Skan 21169695Skan#ifdef HAVE_CONFIG_H 22169695Skan#if defined (CONFIG_BROKETS) 23169695Skan/* We use <config.h> instead of "config.h" so that a compilation 24169695Skan using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h 25169695Skan (which it would do because it found this file in $srcdir). */ 26169695Skan#include <config.h> 27169695Skan#else 28169695Skan#include "config.h" 29169695Skan#endif 30169695Skan#endif 31169695Skan 32169695Skan 33169695Skan#ifndef _GNU_SOURCE 34169695Skan#define _GNU_SOURCE 35169695Skan#endif 36169695Skan 37169695Skan/* This code to undef const added in libiberty. */ 38169695Skan#ifndef __STDC__ 39169695Skan/* This is a separate conditional since some stdc systems 40169695Skan reject `defined (const)'. */ 41169695Skan#ifndef const 42169695Skan#define const 43169695Skan#endif 44169695Skan#endif 45169695Skan 46169695Skan#include <errno.h> 47169695Skan#include <fnmatch.h> 48169695Skan#include <safe-ctype.h> 49169695Skan 50169695Skan/* Comment out all this code if we are using the GNU C Library, and are not 51169695Skan actually compiling the library itself. This code is part of the GNU C 52169695Skan Library, but also included in many other GNU distributions. Compiling 53169695Skan and linking in this code is a waste when using the GNU C library 54169695Skan (especially if it is a shared library). Rather than having every GNU 55169695Skan program understand `configure --with-gnu-libc' and omit the object files, 56169695Skan it is simpler to just do this in the source for each such file. */ 57169695Skan 58169695Skan#if defined (_LIBC) || !defined (__GNU_LIBRARY__) 59169695Skan 60169695Skan 61169695Skan#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) 62169695Skanextern int errno; 63169695Skan#endif 64169695Skan 65169695Skan/* Match STRING against the filename pattern PATTERN, returning zero if 66169695Skan it matches, nonzero if not. */ 67169695Skanint 68169695Skanfnmatch (const char *pattern, const char *string, int flags) 69169695Skan{ 70169695Skan register const char *p = pattern, *n = string; 71169695Skan register unsigned char c; 72169695Skan 73169695Skan#define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c)) 74169695Skan 75169695Skan while ((c = *p++) != '\0') 76169695Skan { 77169695Skan c = FOLD (c); 78169695Skan 79169695Skan switch (c) 80169695Skan { 81169695Skan case '?': 82169695Skan if (*n == '\0') 83169695Skan return FNM_NOMATCH; 84169695Skan else if ((flags & FNM_FILE_NAME) && *n == '/') 85169695Skan return FNM_NOMATCH; 86169695Skan else if ((flags & FNM_PERIOD) && *n == '.' && 87169695Skan (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 88169695Skan return FNM_NOMATCH; 89169695Skan break; 90169695Skan 91169695Skan case '\\': 92169695Skan if (!(flags & FNM_NOESCAPE)) 93169695Skan { 94169695Skan c = *p++; 95169695Skan c = FOLD (c); 96169695Skan } 97169695Skan if (FOLD ((unsigned char)*n) != c) 98169695Skan return FNM_NOMATCH; 99169695Skan break; 100169695Skan 101169695Skan case '*': 102169695Skan if ((flags & FNM_PERIOD) && *n == '.' && 103169695Skan (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 104169695Skan return FNM_NOMATCH; 105169695Skan 106169695Skan for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) 107169695Skan if (((flags & FNM_FILE_NAME) && *n == '/') || 108169695Skan (c == '?' && *n == '\0')) 109169695Skan return FNM_NOMATCH; 110169695Skan 111169695Skan if (c == '\0') 112169695Skan return 0; 113169695Skan 114169695Skan { 115169695Skan unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; 116169695Skan c1 = FOLD (c1); 117169695Skan for (--p; *n != '\0'; ++n) 118169695Skan if ((c == '[' || FOLD ((unsigned char)*n) == c1) && 119169695Skan fnmatch (p, n, flags & ~FNM_PERIOD) == 0) 120169695Skan return 0; 121169695Skan return FNM_NOMATCH; 122169695Skan } 123169695Skan 124169695Skan case '[': 125169695Skan { 126169695Skan /* Nonzero if the sense of the character class is inverted. */ 127169695Skan register int negate; 128169695Skan 129169695Skan if (*n == '\0') 130169695Skan return FNM_NOMATCH; 131169695Skan 132169695Skan if ((flags & FNM_PERIOD) && *n == '.' && 133169695Skan (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 134169695Skan return FNM_NOMATCH; 135169695Skan 136169695Skan negate = (*p == '!' || *p == '^'); 137169695Skan if (negate) 138169695Skan ++p; 139169695Skan 140169695Skan c = *p++; 141169695Skan for (;;) 142169695Skan { 143169695Skan register unsigned char cstart = c, cend = c; 144169695Skan 145169695Skan if (!(flags & FNM_NOESCAPE) && c == '\\') 146169695Skan cstart = cend = *p++; 147169695Skan 148169695Skan cstart = cend = FOLD (cstart); 149169695Skan 150169695Skan if (c == '\0') 151169695Skan /* [ (unterminated) loses. */ 152169695Skan return FNM_NOMATCH; 153169695Skan 154169695Skan c = *p++; 155169695Skan c = FOLD (c); 156169695Skan 157169695Skan if ((flags & FNM_FILE_NAME) && c == '/') 158169695Skan /* [/] can never match. */ 159169695Skan return FNM_NOMATCH; 160169695Skan 161169695Skan if (c == '-' && *p != ']') 162169695Skan { 163169695Skan cend = *p++; 164169695Skan if (!(flags & FNM_NOESCAPE) && cend == '\\') 165169695Skan cend = *p++; 166169695Skan if (cend == '\0') 167169695Skan return FNM_NOMATCH; 168169695Skan cend = FOLD (cend); 169169695Skan 170169695Skan c = *p++; 171169695Skan } 172169695Skan 173169695Skan if (FOLD ((unsigned char)*n) >= cstart 174169695Skan && FOLD ((unsigned char)*n) <= cend) 175169695Skan goto matched; 176169695Skan 177169695Skan if (c == ']') 178169695Skan break; 179169695Skan } 180169695Skan if (!negate) 181169695Skan return FNM_NOMATCH; 182169695Skan break; 183169695Skan 184169695Skan matched:; 185169695Skan /* Skip the rest of the [...] that already matched. */ 186169695Skan while (c != ']') 187169695Skan { 188169695Skan if (c == '\0') 189169695Skan /* [... (unterminated) loses. */ 190169695Skan return FNM_NOMATCH; 191169695Skan 192169695Skan c = *p++; 193169695Skan if (!(flags & FNM_NOESCAPE) && c == '\\') 194169695Skan /* XXX 1003.2d11 is unclear if this is right. */ 195169695Skan ++p; 196169695Skan } 197169695Skan if (negate) 198169695Skan return FNM_NOMATCH; 199169695Skan } 200169695Skan break; 201169695Skan 202169695Skan default: 203169695Skan if (c != FOLD ((unsigned char)*n)) 204169695Skan return FNM_NOMATCH; 205169695Skan } 206169695Skan 207169695Skan ++n; 208169695Skan } 209169695Skan 210169695Skan if (*n == '\0') 211169695Skan return 0; 212169695Skan 213169695Skan if ((flags & FNM_LEADING_DIR) && *n == '/') 214169695Skan /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ 215169695Skan return 0; 216169695Skan 217169695Skan return FNM_NOMATCH; 218169695Skan} 219169695Skan 220169695Skan#endif /* _LIBC or not __GNU_LIBRARY__. */ 221