home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / lib / fnmatch.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  194 lines

  1. /* Copyright (C) 1992 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  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.
  8.  
  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.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. /* Modified slightly by Brian Berliner <berliner@sun.com> and
  20.    Jim Blandy <jimb@cyclic.com> for CVS use */
  21.  
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25.  
  26. /* Some file systems are case-insensitive.  If FOLD_FN_CHAR is
  27.    #defined, it maps the character C onto its "canonical" form.  In a
  28.    case-insensitive system, it would map all alphanumeric characters
  29.    to lower case.  Under Windows NT, / and \ are both path component
  30.    separators, so FOLD_FN_CHAR would map them both to /.  */
  31. #ifndef FOLD_FN_CHAR
  32. #define FOLD_FN_CHAR(c) (c)
  33. #endif
  34.  
  35. /* IGNORE(@ */
  36. /* #include <ansidecl.h> */
  37. /* @) */
  38. #include <errno.h>
  39. #include <fnmatch.h>
  40.  
  41. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  42. extern int errno;
  43. #endif
  44.  
  45. /* Match STRING against the filename pattern PATTERN, returning zero if
  46.    it matches, nonzero if not.  */
  47. int
  48. #if __STDC__
  49. fnmatch (const char *pattern, const char *string, int flags)
  50. #else
  51. fnmatch (pattern, string, flags)
  52.     char *pattern;
  53.     char *string;
  54.     int flags;
  55. #endif
  56. {
  57.   register const char *p = pattern, *n = string;
  58.   register char c;
  59.  
  60.   if ((flags & ~__FNM_FLAGS) != 0)
  61.     {
  62.       errno = EINVAL;
  63.       return -1;
  64.     }
  65.  
  66.   while ((c = *p++) != '\0')
  67.     {
  68.       switch (c)
  69.     {
  70.     case '?':
  71.       if (*n == '\0')
  72.         return FNM_NOMATCH;
  73.       else if ((flags & FNM_PATHNAME) && *n == '/')
  74.         return FNM_NOMATCH;
  75.       else if ((flags & FNM_PERIOD) && *n == '.' &&
  76.            (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  77.         return FNM_NOMATCH;
  78.       break;
  79.       
  80.     case '\\':
  81.       if (!(flags & FNM_NOESCAPE))
  82.         c = *p++;
  83.       if (*n != c)
  84.         return FNM_NOMATCH;
  85.       break;
  86.       
  87.     case '*':
  88.       if ((flags & FNM_PERIOD) && *n == '.' &&
  89.           (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  90.         return FNM_NOMATCH;
  91.       
  92.       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  93.         if (((flags & FNM_PATHNAME) && *n == '/') ||
  94.         (c == '?' && *n == '\0'))
  95.           return FNM_NOMATCH;
  96.       
  97.       if (c == '\0')
  98.         return 0;
  99.       
  100.       {
  101.         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  102.         for (--p; *n != '\0'; ++n)
  103.           if ((c == '[' || *n == c1) &&
  104.           fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
  105.         return 0;
  106.         return FNM_NOMATCH;
  107.       }
  108.       
  109.     case '[':
  110.       {
  111.         /* Nonzero if the sense of the character class is inverted.  */
  112.         register int not;
  113.         
  114.         if (*n == '\0')
  115.           return FNM_NOMATCH;
  116.         
  117.         if ((flags & FNM_PERIOD) && *n == '.' &&
  118.         (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  119.           return FNM_NOMATCH;
  120.         
  121.         not = (*p == '!' || *p == '^');
  122.         if (not)
  123.           ++p;
  124.         
  125.         c = *p++;
  126.         for (;;)
  127.           {
  128.         register char cstart = c, cend = c;
  129.         
  130.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  131.           cstart = cend = *p++;
  132.         
  133.         if (c == '\0')
  134.           /* [ (unterminated) loses.  */
  135.           return FNM_NOMATCH;
  136.         
  137.         c = *p++;
  138.         
  139.         if ((flags & FNM_PATHNAME) && c == '/')
  140.           /* [/] can never match.  */
  141.           return FNM_NOMATCH;
  142.         
  143.         if (c == '-' && *p != ']')
  144.           {
  145.             cend = *p++;
  146.             if (!(flags & FNM_NOESCAPE) && cend == '\\')
  147.               cend = *p++;
  148.             if (cend == '\0')
  149.               return FNM_NOMATCH;
  150.             c = *p++;
  151.           }
  152.         
  153.         if (*n >= cstart && *n <= cend)
  154.           goto matched;
  155.         
  156.         if (c == ']')
  157.           break;
  158.           }
  159.         if (!not)
  160.           return FNM_NOMATCH;
  161.         break;
  162.         
  163.       matched:;
  164.         /* Skip the rest of the [...] that already matched.  */
  165.         while (c != ']')
  166.           {
  167.         if (c == '\0')
  168.           /* [... (unterminated) loses.  */
  169.           return FNM_NOMATCH;
  170.         
  171.         c = *p++;
  172.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  173.           /* 1003.2d11 is unclear if this is right.  %%% */
  174.           ++p;
  175.           }
  176.         if (not)
  177.           return FNM_NOMATCH;
  178.       }
  179.       break;
  180.       
  181.     default:
  182.       if (FOLD_FN_CHAR (c) != FOLD_FN_CHAR (*n))
  183.         return FNM_NOMATCH;
  184.     }
  185.       
  186.       ++n;
  187.     }
  188.  
  189.   if (*n == '\0')
  190.     return 0;
  191.  
  192.   return FNM_NOMATCH;
  193. }
  194.