home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / fnmatch.c < prev    next >
C/C++ Source or Header  |  1997-09-10  |  5KB  |  181 lines

  1. /* Copyright (C) 1991 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. /*
  20. $Id: fnmatch.c 2.1 1995/06/24 16:30:03 MH Rel MH $
  21. */
  22.  
  23. #include <errno.h>
  24. #include <fnmatch.h>
  25.  
  26. #if !defined(__GNU_LIBRARY__) && !defined(HAVE_PROTO)
  27. extern int errno;
  28. #endif
  29.  
  30. /* Match STRING against the filename pattern PATTERN, returning zero if
  31.    it matches, nonzero if not.  */
  32. int
  33. fnmatch(pattern, string, flags)
  34.      char *pattern;
  35.      char *string;
  36.      int flags;
  37. {
  38.   register char *p = pattern, *n = string;
  39.   register char c;
  40.  
  41.   if ((flags & ~__FNM_FLAGS) != 0)
  42.     {
  43.       errno = EINVAL;
  44.       return -1;
  45.     }
  46.  
  47.   while ((c = *p++) != '\0')
  48.     switch (c)
  49.       {
  50.       case '?':
  51.         if (*n == '\0')
  52.           return FNM_NOMATCH;
  53.         else if ((flags & FNM_PATHNAME) && *n == '/')
  54.           return FNM_NOMATCH;
  55.         else if ((flags & FNM_PERIOD) && *n == '.' &&
  56.                  (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  57.           return FNM_NOMATCH;
  58.         else
  59.           ++n;
  60.         break;
  61.  
  62.       case '\\':
  63.         if (!(flags & FNM_NOESCAPE))
  64.           c = *p++;
  65.         if (*n++ != c)
  66.           return FNM_NOMATCH;
  67.         break;
  68.  
  69.       case '*':
  70.         if ((flags & FNM_PERIOD) && *n == '.' &&
  71.             (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  72.           return FNM_NOMATCH;
  73.  
  74.         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  75.           if (((flags & FNM_PATHNAME) && *n == '/') ||
  76.               (c == '?' && *n == '\0'))
  77.             return FNM_NOMATCH;
  78.  
  79.         if (c == '\0')
  80.           return 0;
  81.  
  82.         {
  83.           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  84.           for (--p; *n != '\0'; ++n)
  85.             if ((c == '[' || *n == c1) &&
  86.                 fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
  87.               return 0;
  88.           return FNM_NOMATCH;
  89.         }
  90.  
  91.       case '[':
  92.         {
  93.           /* Nonzero if this if the sense of
  94.              the character class is inverted.  */
  95.           register int not;
  96.  
  97.           if (*n == '\0')
  98.             return FNM_NOMATCH;
  99.  
  100.           if ((flags & FNM_PERIOD) && *n == '.' &&
  101.               (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  102.             return FNM_NOMATCH;
  103.  
  104.           not = *p == '!';
  105.           if (not)
  106.             ++p;
  107.  
  108.           c = *p++;
  109.           for (;;)
  110.             {
  111.               register char cstart = c, cend = c;
  112.  
  113.               if (!(flags & FNM_NOESCAPE) && c == '\\')
  114.                 cstart = cend = *p++;
  115.  
  116.               if (c == '\0')
  117.                 /* [ (unterminated) loses.  */
  118.                 return FNM_NOMATCH;
  119.  
  120.               c = *p++;
  121.               if ((flags & FNM_PATHNAME) && c == '/')
  122.                 /* [/] can never match.  */
  123.                 return FNM_NOMATCH;
  124.  
  125.               if (c == '-')
  126.                 {
  127.                   cend = *p++;
  128.                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
  129.                     cend = *p++;
  130.                   if (cend == '\0')
  131.                     return FNM_NOMATCH;
  132.                   c = *p++;
  133.                 }
  134.               if (*n >= cstart && *n <= cend)
  135.                 goto matched;
  136.  
  137.               if (c == ']')
  138.                 break;
  139.             }
  140.           if (!not)
  141.             return FNM_NOMATCH;
  142.           break;
  143.  
  144.         matched:;
  145.           /* Skip the rest of the [...] that already matched.  */
  146.           while (c != ']')
  147.             {
  148.               if (c == '\0')
  149.                 /* [... (unterminated) loses.  */
  150.                 return FNM_NOMATCH;
  151.  
  152.               c = *p++;
  153.               if (!(flags & FNM_NOESCAPE) && c == '\\')
  154.                 /* 1003.2d11 is unclear if this is right.  %%% */
  155.                 ++p;
  156.             }
  157.           if (not)
  158.             return FNM_NOMATCH;
  159.  
  160.           ++n;
  161.         }
  162.         break;
  163.  
  164.       default:
  165.         if ((flags & FNM_IGNORECASE))                     /* MH */
  166.           {                                               /* MH */
  167.            if (toupper(c) != toupper(*n++))               /* MH */
  168.               return FNM_NOMATCH;                         /* MH */
  169.           }                                               /* MH */
  170.         else                                              /* MH */
  171.            if (c != *n++)
  172.               return FNM_NOMATCH;
  173.  
  174.       }
  175.  
  176.   if (*n == '\0')
  177.     return 0;
  178.  
  179.   return FNM_NOMATCH;
  180. }
  181.