~ubuntu-branches/ubuntu/hardy/xxdiff/hardy

« back to all changes in this revision

Viewing changes to diffutils-2.7/fnmatch.c

  • Committer: Bazaar Package Importer
  • Author(s): Tomas Pospisek
  • Date: 2005-03-29 08:43:56 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050329084356-nkwv8jf18nc7u5qf
Tags: 1:3.1-3
re-upload

Show diffs side-by-side

added added

removed removed

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