1273635Smav/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. 2273635Smav 3273635SmavNOTE: This source is derived from an old version taken from the GNU C 4273635SmavLibrary (glibc). 5273635Smav 6273635SmavThis program is free software; you can redistribute it and/or modify it 7273635Smavunder the terms of the GNU General Public License as published by the 8273635SmavFree Software Foundation; either version 2, or (at your option) any 9273635Smavlater version. 10273635Smav 11273635SmavThis program is distributed in the hope that it will be useful, 12273635Smavbut WITHOUT ANY WARRANTY; without even the implied warranty of 13273635SmavMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14273635SmavGNU General Public License for more details. 15273635Smav 16273635SmavYou should have received a copy of the GNU General Public License 17273635Smavalong with this program; if not, write to the Free Software 18273635SmavFoundation, 51 Franklin Street - Fifth Floor, 19273635SmavBoston, MA 02110-1301, USA. */ 20273635Smav 21273635Smav#ifdef HAVE_CONFIG_H 22273635Smav#if defined (CONFIG_BROKETS) 23273635Smav/* We use <config.h> instead of "config.h" so that a compilation 24273635Smav using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h 25273635Smav (which it would do because it found this file in $srcdir). */ 26273635Smav#include <config.h> 27273635Smav#else 28273635Smav#include "config.h" 29273635Smav#endif 30273635Smav#endif 31273635Smav 32273635Smav 33273635Smav#ifndef _GNU_SOURCE 34273635Smav#define _GNU_SOURCE 35273635Smav#endif 36273635Smav 37273635Smav/* This code to undef const added in libiberty. */ 38273635Smav#ifndef __STDC__ 39273635Smav/* This is a separate conditional since some stdc systems 40273635Smav reject `defined (const)'. */ 41273635Smav#ifndef const 42273635Smav#define const 43273635Smav#endif 44273635Smav#endif 45273635Smav 46273635Smav#include <errno.h> 47273635Smav#include <fnmatch.h> 48273635Smav#include <safe-ctype.h> 49273635Smav 50273635Smav/* Comment out all this code if we are using the GNU C Library, and are not 51273635Smav actually compiling the library itself. This code is part of the GNU C 52273635Smav Library, but also included in many other GNU distributions. Compiling 53273635Smav and linking in this code is a waste when using the GNU C library 54273635Smav (especially if it is a shared library). Rather than having every GNU 55273635Smav program understand `configure --with-gnu-libc' and omit the object files, 56273635Smav it is simpler to just do this in the source for each such file. */ 57273635Smav 58273635Smav#if defined (_LIBC) || !defined (__GNU_LIBRARY__) 59273635Smav 60274939Smav 61273635Smav#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) 62273635Smavextern int errno; 63273635Smav#endif 64273635Smav 65273635Smav/* Match STRING against the filename pattern PATTERN, returning zero if 66273635Smav it matches, nonzero if not. */ 67273635Smavint 68273635Smavfnmatch (const char *pattern, const char *string, int flags) 69273635Smav{ 70273635Smav register const char *p = pattern, *n = string; 71273635Smav register unsigned char c; 72273635Smav 73273635Smav#define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c)) 74273635Smav 75273635Smav while ((c = *p++) != '\0') 76273635Smav { 77273635Smav c = FOLD (c); 78273635Smav 79273635Smav switch (c) 80273635Smav { 81273635Smav case '?': 82273635Smav if (*n == '\0') 83273635Smav return FNM_NOMATCH; 84273635Smav else if ((flags & FNM_FILE_NAME) && *n == '/') 85273635Smav return FNM_NOMATCH; 86273635Smav else if ((flags & FNM_PERIOD) && *n == '.' && 87273635Smav (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 88273635Smav return FNM_NOMATCH; 89273635Smav break; 90273635Smav 91273635Smav case '\\': 92273635Smav if (!(flags & FNM_NOESCAPE)) 93273635Smav { 94273635Smav c = *p++; 95273635Smav c = FOLD (c); 96273635Smav } 97273635Smav if (FOLD ((unsigned char)*n) != c) 98273635Smav return FNM_NOMATCH; 99273635Smav break; 100273635Smav 101273635Smav case '*': 102273635Smav if ((flags & FNM_PERIOD) && *n == '.' && 103273635Smav (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 104273635Smav return FNM_NOMATCH; 105273635Smav 106273635Smav for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) 107273635Smav if (((flags & FNM_FILE_NAME) && *n == '/') || 108273635Smav (c == '?' && *n == '\0')) 109273635Smav return FNM_NOMATCH; 110273635Smav 111273635Smav if (c == '\0') 112273635Smav return 0; 113273635Smav 114273635Smav { 115273635Smav unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; 116273635Smav c1 = FOLD (c1); 117273635Smav for (--p; *n != '\0'; ++n) 118273635Smav if ((c == '[' || FOLD ((unsigned char)*n) == c1) && 119273635Smav fnmatch (p, n, flags & ~FNM_PERIOD) == 0) 120273635Smav return 0; 121273635Smav return FNM_NOMATCH; 122273635Smav } 123273635Smav 124273635Smav case '[': 125273635Smav { 126273635Smav /* Nonzero if the sense of the character class is inverted. */ 127273635Smav register int negate; 128273635Smav 129273635Smav if (*n == '\0') 130273635Smav return FNM_NOMATCH; 131273635Smav 132273635Smav if ((flags & FNM_PERIOD) && *n == '.' && 133273635Smav (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) 134273635Smav return FNM_NOMATCH; 135273635Smav 136273635Smav negate = (*p == '!' || *p == '^'); 137273635Smav if (negate) 138273635Smav ++p; 139273635Smav 140273635Smav c = *p++; 141273635Smav for (;;) 142273635Smav { 143273635Smav register unsigned char cstart = c, cend = c; 144273635Smav 145273635Smav if (!(flags & FNM_NOESCAPE) && c == '\\') 146273635Smav cstart = cend = *p++; 147273635Smav 148273635Smav cstart = cend = FOLD (cstart); 149273635Smav 150273635Smav if (c == '\0') 151273635Smav /* [ (unterminated) loses. */ 152273635Smav return FNM_NOMATCH; 153273635Smav 154273635Smav c = *p++; 155273635Smav c = FOLD (c); 156273635Smav 157273635Smav if ((flags & FNM_FILE_NAME) && c == '/') 158273635Smav /* [/] can never match. */ 159273635Smav return FNM_NOMATCH; 160273635Smav 161273635Smav if (c == '-' && *p != ']') 162273635Smav { 163273635Smav cend = *p++; 164273635Smav if (!(flags & FNM_NOESCAPE) && cend == '\\') 165273635Smav cend = *p++; 166273635Smav if (cend == '\0') 167273635Smav return FNM_NOMATCH; 168273635Smav cend = FOLD (cend); 169273635Smav 170273635Smav c = *p++; 171273635Smav } 172273635Smav 173273635Smav if (FOLD ((unsigned char)*n) >= cstart 174273635Smav && FOLD ((unsigned char)*n) <= cend) 175273635Smav goto matched; 176273635Smav 177273635Smav if (c == ']') 178273635Smav break; 179273635Smav } 180273635Smav if (!negate) 181273635Smav return FNM_NOMATCH; 182273635Smav break; 183273635Smav 184273635Smav matched:; 185273635Smav /* Skip the rest of the [...] that already matched. */ 186273635Smav while (c != ']') 187273635Smav { 188273635Smav if (c == '\0') 189273635Smav /* [... (unterminated) loses. */ 190273635Smav return FNM_NOMATCH; 191273635Smav 192273635Smav c = *p++; 193273635Smav if (!(flags & FNM_NOESCAPE) && c == '\\') 194273635Smav /* XXX 1003.2d11 is unclear if this is right. */ 195273635Smav ++p; 196273635Smav } 197273635Smav if (negate) 198273635Smav return FNM_NOMATCH; 199273635Smav } 200273635Smav break; 201273635Smav 202273635Smav default: 203273635Smav if (c != FOLD ((unsigned char)*n)) 204273635Smav return FNM_NOMATCH; 205273635Smav } 206273635Smav 207273635Smav ++n; 208273635Smav } 209273635Smav 210273635Smav if (*n == '\0') 211273635Smav return 0; 212273635Smav 213273635Smav if ((flags & FNM_LEADING_DIR) && *n == '/') 214273635Smav /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ 215273635Smav return 0; 216273635Smav 217273635Smav return FNM_NOMATCH; 218273635Smav} 219273635Smav 220273635Smav#endif /* _LIBC or not __GNU_LIBRARY__. */ 221273635Smav