home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / src / fnmatch.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  190 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 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. General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public
  15. License along with the GNU C Library; see the file COPYING.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <errno.h>
  20. #include "fnmatch.h"
  21.  
  22. #if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS)
  23. #  if !defined (errno)
  24. extern int errno;
  25. #  endif /* !errno */
  26. #endif
  27.  
  28. /* Match STRING against the filename pattern PATTERN, returning zero if
  29.    it matches, FNM_NOMATCH if not.  */
  30. int
  31. fnmatch (pattern, string, flags)
  32.      char *pattern;
  33.      char *string;
  34.      int flags;
  35. {
  36.   register char *p = pattern, *n = string;
  37.   register char c;
  38.  
  39.   if ((flags & ~__FNM_FLAGS) != 0)
  40.     {
  41.       errno = EINVAL;
  42.       return (-1);
  43.     }
  44.  
  45.   while ((c = *p++) != '\0')
  46.     {
  47.       switch (c)
  48.     {
  49.     case '?':
  50.       if (*n == '\0')
  51.         return (FNM_NOMATCH);
  52.       else if ((flags & FNM_PATHNAME) && *n == '/')
  53.         return (FNM_NOMATCH);
  54.       else if ((flags & FNM_PERIOD) && *n == '.' &&
  55.            (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  56.         return (FNM_NOMATCH);
  57.       break;
  58.  
  59.     case '\\':
  60.       if (!(flags & FNM_NOESCAPE))
  61.         c = *p++;
  62.       if (*n != c)
  63.         return (FNM_NOMATCH);
  64.       break;
  65.  
  66.     case '*':
  67.       if ((flags & FNM_PERIOD) && *n == '.' &&
  68.           (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  69.         return (FNM_NOMATCH);
  70.  
  71.       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  72.         if (((flags & FNM_PATHNAME) && *n == '/') ||
  73.         (c == '?' && *n == '\0'))
  74.           return (FNM_NOMATCH);
  75.  
  76.       if (c == '\0')
  77.         return (0);
  78.  
  79.       {
  80.         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  81.         for (--p; *n != '\0'; ++n)
  82.           if ((c == '[' || *n == c1) &&
  83.           fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  84.         return (0);
  85.         return (FNM_NOMATCH);
  86.       }
  87.  
  88.     case '[':
  89.       {
  90.         /* Nonzero if the sense of the character class is inverted.  */
  91.         register int not;
  92.  
  93.         if (*n == '\0')
  94.           return (FNM_NOMATCH);
  95.  
  96.         if ((flags & FNM_PERIOD) && *n == '.' &&
  97.         (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  98.           return (FNM_NOMATCH);
  99.  
  100.         /* Make sure there is a closing `]'.  If there isn't, the `['
  101.            is just a character to be matched. */
  102.         {
  103.           register char *np;
  104.  
  105.           for (np = p; np && *np && *np != ']'; np++);
  106.  
  107.           if (np && !*np)
  108.         {
  109.           if (*n != '[')
  110.             return (FNM_NOMATCH);
  111.           goto next_char;
  112.         }
  113.         }
  114.           
  115.         not = (*p == '!' || *p == '^');
  116.         if (not)
  117.           ++p;
  118.  
  119.         c = *p++;
  120.         for (;;)
  121.           {
  122.         register char cstart = c, cend = c;
  123.  
  124.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  125.           cstart = cend = *p++;
  126.  
  127.         if (c == '\0')
  128.           /* [ (unterminated) loses.  */
  129.           return (FNM_NOMATCH);
  130.  
  131.         c = *p++;
  132.  
  133.         if ((flags & FNM_PATHNAME) && c == '/')
  134.           /* [/] can never match.  */
  135.           return (FNM_NOMATCH);
  136.  
  137.         if (c == '-' && *p != ']')
  138.           {
  139.             cend = *p++;
  140.             if (!(flags & FNM_NOESCAPE) && cend == '\\')
  141.               cend = *p++;
  142.             if (cend == '\0')
  143.               return (FNM_NOMATCH);
  144.             c = *p++;
  145.           }
  146.  
  147.         if (*n >= cstart && *n <= cend)
  148.           goto matched;
  149.  
  150.         if (c == ']')
  151.           break;
  152.           }
  153.         if (!not)
  154.           return (FNM_NOMATCH);
  155.  
  156.       next_char:
  157.         break;
  158.  
  159.       matched:
  160.         /* Skip the rest of the [...] that already matched.  */
  161.         while (c != ']')
  162.           {
  163.         if (c == '\0')
  164.           /* [... (unterminated) loses.  */
  165.           return (FNM_NOMATCH);
  166.  
  167.         c = *p++;
  168.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  169.           /* 1003.2d11 is unclear if this is right.  %%% */
  170.           ++p;
  171.           }
  172.         if (not)
  173.           return (FNM_NOMATCH);
  174.       }
  175.       break;
  176.  
  177.     default:
  178.       if (c != *n)
  179.         return (FNM_NOMATCH);
  180.     }
  181.  
  182.       ++n;
  183.     }
  184.  
  185.   if (*n == '\0')
  186.     return (0);
  187.  
  188.   return (FNM_NOMATCH);
  189. }
  190.