home *** CD-ROM | disk | FTP | other *** search
/ Dream 49 / Amiga_Dream_49.iso / beos / utils / mkisofs-1.000 / mkisofs-1.11-beos / fnmatch.c < prev    next >
C/C++ Source or Header  |  1998-01-25  |  6KB  |  231 lines

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