source: trunk/third/gtk/gtk/fnmatch.c @ 14482

Revision 14482, 5.2 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 02111-1307, USA.
17 */
18
19/*
20 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
21 * file for a list of people on the GTK+ Team.  See the ChangeLog
22 * files for a list of changes.  These files are distributed with
23 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include <errno.h>
31
32/* Added for GTK. We need to make sure that all constants are defined
33 * to properly compile this file */
34#ifndef _GNU_SOURCE
35#define _GNU_SOURCE
36#endif
37#include "fnmatch.h"
38
39#include <ctype.h>
40
41
42/* Comment out all this code if we are using the GNU C Library, and are not
43   actually compiling the library itself.  This code is part of the GNU C
44   Library, but also included in many other GNU distributions.  Compiling
45   and linking in this code is a waste when using the GNU C library
46   (especially if it is a shared library).  Rather than having every GNU
47   program understand `configure --with-gnu-libc' and omit the object files,
48   it is simpler to just do this in the source for each such file.  */
49
50#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
51
52
53#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
54extern int errno;
55#endif
56
57/* Match STRING against the filename pattern PATTERN, returning zero if
58   it matches, nonzero if not.  */
59int
60fnmatch (pattern, string, flags)
61     const char *pattern;
62     const char *string;
63     int flags;
64{
65  register const char *p = pattern, *n = string;
66  register char c;
67
68/* Note that this evalutes C many times.  */
69#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
70
71  while ((c = *p++) != '\0')
72    {
73      c = FOLD (c);
74
75      switch (c)
76        {
77        case '?':
78          if (*n == '\0')
79            return FNM_NOMATCH;
80          else if ((flags & FNM_FILE_NAME) && *n == '/')
81            return FNM_NOMATCH;
82          else if ((flags & FNM_PERIOD) && *n == '.' &&
83                   (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
84            return FNM_NOMATCH;
85          break;
86
87        case '\\':
88          if (!(flags & FNM_NOESCAPE))
89            {
90              c = *p++;
91              c = FOLD (c);
92            }
93          if (FOLD (*n) != c)
94            return FNM_NOMATCH;
95          break;
96
97        case '*':
98          if ((flags & FNM_PERIOD) && *n == '.' &&
99              (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
100            return FNM_NOMATCH;
101
102          for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
103            if (((flags & FNM_FILE_NAME) && *n == '/') ||
104                (c == '?' && *n == '\0'))
105              return FNM_NOMATCH;
106
107          if (c == '\0')
108            return 0;
109
110          {
111            char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
112            c1 = FOLD (c1);
113            for (--p; *n != '\0'; ++n)
114              if ((c == '[' || FOLD (*n) == c1) &&
115                  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
116                return 0;
117            return FNM_NOMATCH;
118          }
119
120        case '[':
121          {
122            /* Nonzero if the sense of the character class is inverted.  */
123            register int not;
124
125            if (*n == '\0')
126              return FNM_NOMATCH;
127
128            if ((flags & FNM_PERIOD) && *n == '.' &&
129                (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
130              return FNM_NOMATCH;
131
132            not = (*p == '!' || *p == '^');
133            if (not)
134              ++p;
135
136            c = *p++;
137            for (;;)
138              {
139                register char cstart = c, cend = c;
140
141                if (!(flags & FNM_NOESCAPE) && c == '\\')
142                  cstart = cend = *p++;
143
144                cstart = cend = FOLD (cstart);
145
146                if (c == '\0')
147                  /* [ (unterminated) loses.  */
148                  return FNM_NOMATCH;
149
150                c = *p++;
151                c = FOLD (c);
152
153                if ((flags & FNM_FILE_NAME) && c == '/')
154                  /* [/] can never match.  */
155                  return FNM_NOMATCH;
156
157                if (c == '-' && *p != ']')
158                  {
159                    cend = *p++;
160                    if (!(flags & FNM_NOESCAPE) && cend == '\\')
161                      cend = *p++;
162                    if (cend == '\0')
163                      return FNM_NOMATCH;
164                    cend = FOLD (cend);
165
166                    c = *p++;
167                  }
168
169                if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
170                  goto matched;
171
172                if (c == ']')
173                  break;
174              }
175            if (!not)
176              return FNM_NOMATCH;
177            break;
178
179          matched:;
180            /* Skip the rest of the [...] that already matched.  */
181            while (c != ']')
182              {
183                if (c == '\0')
184                  /* [... (unterminated) loses.  */
185                  return FNM_NOMATCH;
186
187                c = *p++;
188                if (!(flags & FNM_NOESCAPE) && c == '\\')
189                  /* XXX 1003.2d11 is unclear if this is right.  */
190                  ++p;
191              }
192            if (not)
193              return FNM_NOMATCH;
194          }
195          break;
196
197        default:
198          if (c != FOLD (*n))
199            return FNM_NOMATCH;
200        }
201
202      ++n;
203    }
204
205  if (*n == '\0')
206    return 0;
207
208  if ((flags & FNM_LEADING_DIR) && *n == '/')
209    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
210    return 0;
211
212  return FNM_NOMATCH;
213}
214
215#endif  /* _LIBC or not __GNU_LIBRARY__.  */
Note: See TracBrowser for help on using the repository browser.