"Fossies" - the Fresh Open Source Software Archive

Member "sitecopy-0.16.6/lib/fnmatch.c" (2 Jan 2005, 5137 Bytes) of archive /linux/www/sitecopy-0.16.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "fnmatch.c" see the Fossies "Dox" file reference documentation.

    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
    4    Library.  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 Foundation,
   18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
   19 
   20 #if HAVE_CONFIG_H
   21 # include <config.h>
   22 #endif
   23 
   24 #include <errno.h>
   25 #include <fnmatch.h>
   26 #include <ctype.h>
   27 
   28 #if defined (STDC_HEADERS) || !defined (isascii)
   29 # define ISASCII(c) 1
   30 #else
   31 # define ISASCII(c) isascii(c)
   32 #endif
   33 
   34 #define ISUPPER(c) (ISASCII (c) && isupper (c))
   35 
   36 
   37 /* Comment out all this code if we are using the GNU C Library, and are not
   38    actually compiling the library itself.  This code is part of the GNU C
   39    Library, but also included in many other GNU distributions.  Compiling
   40    and linking in this code is a waste when using the GNU C library
   41    (especially if it is a shared library).  Rather than having every GNU
   42    program understand `configure --with-gnu-libc' and omit the object files,
   43    it is simpler to just do this in the source for each such file.  */
   44 
   45 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
   46 
   47 
   48 # ifndef errno
   49 extern int errno;
   50 # endif
   51 
   52 /* Match STRING against the filename pattern PATTERN, returning zero if
   53    it matches, nonzero if not.  */
   54 int
   55 fnmatch (pattern, string, flags)
   56      const char *pattern;
   57      const char *string;
   58      int flags;
   59 {
   60   register const char *p = pattern, *n = string;
   61   register char c;
   62 
   63 /* Note that this evalutes C many times.  */
   64 # define FOLD(c)    ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
   65 
   66   while ((c = *p++) != '\0')
   67     {
   68       c = FOLD (c);
   69 
   70       switch (c)
   71     {
   72     case '?':
   73       if (*n == '\0')
   74         return FNM_NOMATCH;
   75       else if ((flags & FNM_FILE_NAME) && *n == '/')
   76         return FNM_NOMATCH;
   77       else if ((flags & FNM_PERIOD) && *n == '.' &&
   78            (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
   79         return FNM_NOMATCH;
   80       break;
   81 
   82     case '\\':
   83       if (!(flags & FNM_NOESCAPE))
   84         {
   85           c = *p++;
   86           c = FOLD (c);
   87         }
   88       if (FOLD (*n) != c)
   89         return FNM_NOMATCH;
   90       break;
   91 
   92     case '*':
   93       if ((flags & FNM_PERIOD) && *n == '.' &&
   94           (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
   95         return FNM_NOMATCH;
   96 
   97       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
   98         if (((flags & FNM_FILE_NAME) && *n == '/') ||
   99         (c == '?' && *n == '\0'))
  100           return FNM_NOMATCH;
  101 
  102       if (c == '\0')
  103         return 0;
  104 
  105       {
  106         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  107         c1 = FOLD (c1);
  108         for (--p; *n != '\0'; ++n)
  109           if ((c == '[' || FOLD (*n) == c1) &&
  110           fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  111         return 0;
  112         return FNM_NOMATCH;
  113       }
  114 
  115     case '[':
  116       {
  117         /* Nonzero if the sense of the character class is inverted.  */
  118         register int not;
  119 
  120         if (*n == '\0')
  121           return FNM_NOMATCH;
  122 
  123         if ((flags & FNM_PERIOD) && *n == '.' &&
  124         (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  125           return FNM_NOMATCH;
  126 
  127         not = (*p == '!' || *p == '^');
  128         if (not)
  129           ++p;
  130 
  131         c = *p++;
  132         for (;;)
  133           {
  134         register char cstart = c, cend = c;
  135 
  136         if (!(flags & FNM_NOESCAPE) && c == '\\')
  137           cstart = cend = *p++;
  138 
  139         cstart = cend = FOLD (cstart);
  140 
  141         if (c == '\0')
  142           /* [ (unterminated) loses.  */
  143           return FNM_NOMATCH;
  144 
  145         c = *p++;
  146         c = FOLD (c);
  147 
  148         if ((flags & FNM_FILE_NAME) && c == '/')
  149           /* [/] can never match.  */
  150           return FNM_NOMATCH;
  151 
  152         if (c == '-' && *p != ']')
  153           {
  154             cend = *p++;
  155             if (!(flags & FNM_NOESCAPE) && cend == '\\')
  156               cend = *p++;
  157             if (cend == '\0')
  158               return FNM_NOMATCH;
  159             cend = FOLD (cend);
  160 
  161             c = *p++;
  162           }
  163 
  164         if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
  165           goto matched;
  166 
  167         if (c == ']')
  168           break;
  169           }
  170         if (!not)
  171           return FNM_NOMATCH;
  172         break;
  173 
  174       matched:;
  175         /* Skip the rest of the [...] that already matched.  */
  176         while (c != ']')
  177           {
  178         if (c == '\0')
  179           /* [... (unterminated) loses.  */
  180           return FNM_NOMATCH;
  181 
  182         c = *p++;
  183         if (!(flags & FNM_NOESCAPE) && c == '\\')
  184           /* XXX 1003.2d11 is unclear if this is right.  */
  185           ++p;
  186           }
  187         if (not)
  188           return FNM_NOMATCH;
  189       }
  190       break;
  191 
  192     default:
  193       if (c != FOLD (*n))
  194         return FNM_NOMATCH;
  195     }
  196 
  197       ++n;
  198     }
  199 
  200   if (*n == '\0')
  201     return 0;
  202 
  203   if ((flags & FNM_LEADING_DIR) && *n == '/')
  204     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
  205     return 0;
  206 
  207   return FNM_NOMATCH;
  208 
  209 # undef FOLD
  210 }
  211 
  212 #endif  /* _LIBC or not __GNU_LIBRARY__.  */