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