Merge pull request #3587 from techee/unused_remove
[geany-mirror.git] / ctags / fnmatch / fnmatch.c
blobb979ad6d94a33ef6e757d22f6b6253977379c837
1 /* Copyright (C) 1992 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. */
14 /* Modified slightly by Brian Berliner <berliner@sun.com> and
15 Jim Blandy <jimb@cyclic.com> for CVS use */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
21 /* Some file systems are case-insensitive. If FOLD_FN_CHAR is
22 #defined, it maps the character C onto its "canonical" form. In a
23 case-insensitive system, it would map all alphanumeric characters
24 to lower case. Under Windows NT, / and \ are both path component
25 separators, so FOLD_FN_CHAR would map them both to /. */
26 #ifndef FOLD_FN_CHAR
27 #define FOLD_FN_CHAR(c) (c)
28 #endif
30 /* IGNORE(@ */
31 /* #include <ansidecl.h> */
32 /* @) */
33 #include <errno.h>
34 #include <fnmatch.h>
36 #if !defined(__GNU_LIBRARY__) \
37 && !defined(STDC_HEADERS) \
38 && !defined(_CRT_ERRNO_DEFINED)
39 extern int errno;
40 #endif
42 /* Match STRING against the filename pattern PATTERN, returning zero if
43 it matches, nonzero if not. */
44 int
45 #if __STDC__
46 fnmatch (const char *pattern, const char *string, int flags)
47 #else
48 fnmatch (pattern, string, flags)
49 char *pattern;
50 char *string;
51 int flags;
52 #endif
54 register const char *p = pattern, *n = string;
55 register char c;
57 if ((flags & ~__FNM_FLAGS) != 0)
59 errno = EINVAL;
60 return -1;
63 while ((c = *p++) != '\0')
65 switch (c)
67 case '?':
68 if (*n == '\0')
69 return FNM_NOMATCH;
70 else if ((flags & FNM_PATHNAME) && *n == '/')
71 return FNM_NOMATCH;
72 else if ((flags & FNM_PERIOD) && *n == '.' &&
73 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
74 return FNM_NOMATCH;
75 break;
77 case '\\':
78 if (!(flags & FNM_NOESCAPE))
79 c = *p++;
80 if (*n != c)
81 return FNM_NOMATCH;
82 break;
84 case '*':
85 if ((flags & FNM_PERIOD) && *n == '.' &&
86 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
87 return FNM_NOMATCH;
89 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
90 if (((flags & FNM_PATHNAME) && *n == '/') ||
91 (c == '?' && *n == '\0'))
92 return FNM_NOMATCH;
94 if (c == '\0')
95 return 0;
98 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
99 for (--p; *n != '\0'; ++n)
100 if ((c == '[' || *n == c1) &&
101 fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
102 return 0;
103 return FNM_NOMATCH;
106 case '[':
108 /* Nonzero if the sense of the character class is inverted. */
109 register int not;
111 if (*n == '\0')
112 return FNM_NOMATCH;
114 if ((flags & FNM_PERIOD) && *n == '.' &&
115 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
116 return FNM_NOMATCH;
118 not = (*p == '!' || *p == '^');
119 if (not)
120 ++p;
122 c = *p++;
123 for (;;)
125 register char cstart = c, cend = c;
127 if (!(flags & FNM_NOESCAPE) && c == '\\')
128 cstart = cend = *p++;
130 if (c == '\0')
131 /* [ (unterminated) loses. */
132 return FNM_NOMATCH;
134 c = *p++;
136 if ((flags & FNM_PATHNAME) && c == '/')
137 /* [/] can never match. */
138 return FNM_NOMATCH;
140 if (c == '-' && *p != ']')
142 cend = *p++;
143 if (!(flags & FNM_NOESCAPE) && cend == '\\')
144 cend = *p++;
145 if (cend == '\0')
146 return FNM_NOMATCH;
147 c = *p++;
150 if (*n >= cstart && *n <= cend)
151 goto matched;
153 if (c == ']')
154 break;
156 if (!not)
157 return FNM_NOMATCH;
158 break;
160 matched:;
161 /* Skip the rest of the [...] that already matched. */
162 while (c != ']')
164 if (c == '\0')
165 /* [... (unterminated) loses. */
166 return FNM_NOMATCH;
168 c = *p++;
169 if (!(flags & FNM_NOESCAPE) && c == '\\')
170 /* 1003.2d11 is unclear if this is right. %%% */
171 ++p;
173 if (not)
174 return FNM_NOMATCH;
176 break;
178 default:
179 if (FOLD_FN_CHAR (c) != FOLD_FN_CHAR (*n))
180 return FNM_NOMATCH;
183 ++n;
186 if (*n == '\0')
187 return 0;
189 return FNM_NOMATCH;