fnmatch.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:6k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2. NOTE: The canonical source of this file is maintained with the GNU C Library.
  3. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  15. static char rcsid[] ="$Id: fnmatch.c,v 1.4 1999/03/02 03:41:25 eric Exp $";
  16. #ifdef HAVE_CONFIG_H
  17. #include <config.h>
  18. #endif
  19. #include <errno.h>
  20. #include <fnmatch.h>
  21. #ifndef __STDC__
  22. #define const
  23. #endif
  24. #ifndef FNM_FILE_NAME
  25. #define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name.  */
  26. #endif
  27. #ifndef FNM_LEADING_DIR
  28. #define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match.  */
  29. #endif
  30. #ifndef FNM_CASEFOLD
  31. #define FNM_CASEFOLD (1 << 4) /* Compare without regard to case.  */
  32. #endif
  33. #include <ctype.h>
  34. #if defined (STDC_HEADERS) || !defined (isascii)
  35. #define ISASCII(c) 1
  36. #else
  37. #define ISASCII(c) isascii(c)
  38. #endif
  39. #define ISUPPER(c) (ISASCII (c) && isupper (c))
  40. /* Comment out all this code if we are using the GNU C Library, and are not
  41.    actually compiling the library itself.  This code is part of the GNU C
  42.    Library, but also included in many other GNU distributions.  Compiling
  43.    and linking in this code is a waste when using the GNU C library
  44.    (especially if it is a shared library).  Rather than having every GNU
  45.    program understand `configure --with-gnu-libc' and omit the object files,
  46.    it is simpler to just do this in the source for each such file.  */
  47. #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  48. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  49. extern int errno;
  50. #endif
  51. /* Match STRING against the filename pattern PATTERN, returning zero if
  52.    it matches, nonzero if not.  */
  53. int
  54. fnmatch (pattern, string, flags)
  55.      const char *pattern;
  56.      const char *string;
  57.      int flags;
  58. {
  59.   register const char *p = pattern, *n = string;
  60.   register char c;
  61. /* Note that this evalutes C many times.  */
  62. #define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
  63.   while ((c = *p++) != '')
  64.     {
  65.       c = FOLD ((unsigned char)c);
  66.       switch (c)
  67. {
  68. case '?':
  69.   if (*n == '')
  70.     return FNM_NOMATCH;
  71.   else if ((flags & FNM_FILE_NAME) && *n == '/')
  72.     return FNM_NOMATCH;
  73.   else if ((flags & FNM_PERIOD) && *n == '.' &&
  74.    (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  75.     return FNM_NOMATCH;
  76.   break;
  77. case '\':
  78.   if (!(flags & FNM_NOESCAPE))
  79.     {
  80.       c = *p++;
  81.       c = FOLD ((unsigned char )c);
  82.     }
  83.   if (FOLD ((unsigned char )*n) != c)
  84.     return FNM_NOMATCH;
  85.   break;
  86. case '*':
  87.   if ((flags & FNM_PERIOD) && *n == '.' &&
  88.       (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  89.     return FNM_NOMATCH;
  90.   for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  91.     if (((flags & FNM_FILE_NAME) && *n == '/') ||
  92. (c == '?' && *n == ''))
  93.       return FNM_NOMATCH;
  94.   if (c == '')
  95.     return 0;
  96.   {
  97.     char c1 = (!(flags & FNM_NOESCAPE) && c == '\') ? *p : c;
  98.     c1 = FOLD ((unsigned char )c1);
  99.     for (--p; *n != ''; ++n)
  100.       if ((c == '[' || FOLD ((unsigned char )*n) == c1) &&
  101.   fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  102. return 0;
  103.     return FNM_NOMATCH;
  104.   }
  105. case '[':
  106.   {
  107.     /* Nonzero if the sense of the character class is inverted.  */
  108.     register int not;
  109.     if (*n == '')
  110.       return FNM_NOMATCH;
  111.     if ((flags & FNM_PERIOD) && *n == '.' &&
  112. (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
  113.       return FNM_NOMATCH;
  114.     not = (*p == '!' || *p == '^');
  115.     if (not)
  116.       ++p;
  117.     c = *p++;
  118.     for (;;)
  119.       {
  120. register char cstart = c, cend = c;
  121. if (!(flags & FNM_NOESCAPE) && c == '\')
  122.   cstart = cend = *p++;
  123. cstart = cend = FOLD ((unsigned char)cstart);
  124. if (c == '')
  125.   /* [ (unterminated) loses.  */
  126.   return FNM_NOMATCH;
  127. c = *p++;
  128. c = FOLD ((unsigned char)c);
  129. if ((flags & FNM_FILE_NAME) && c == '/')
  130.   /* [/] can never match.  */
  131.   return FNM_NOMATCH;
  132. if (c == '-' && *p != ']')
  133.   {
  134.     cend = *p++;
  135.     if (!(flags & FNM_NOESCAPE) && cend == '\')
  136.       cend = *p++;
  137.     if (cend == '')
  138.       return FNM_NOMATCH;
  139.     cend = FOLD ((unsigned char)cend);
  140.     c = *p++;
  141.   }
  142. if (FOLD ((unsigned char)*n) >= cstart && FOLD ((unsigned char)*n) <= cend)
  143.   goto matched;
  144. if (c == ']')
  145.   break;
  146.       }
  147.     if (!not)
  148.       return FNM_NOMATCH;
  149.     break;
  150.   matched:;
  151.     /* Skip the rest of the [...] that already matched.  */
  152.     while (c != ']')
  153.       {
  154. if (c == '')
  155.   /* [... (unterminated) loses.  */
  156.   return FNM_NOMATCH;
  157. c = *p++;
  158. if (!(flags & FNM_NOESCAPE) && c == '\')
  159.   /* XXX 1003.2d11 is unclear if this is right.  */
  160.   ++p;
  161.       }
  162.     if (not)
  163.       return FNM_NOMATCH;
  164.   }
  165.   break;
  166. default:
  167.   if (c != FOLD ((unsigned char)*n))
  168.     return FNM_NOMATCH;
  169. }
  170.       ++n;
  171.     }
  172.   if (*n == '')
  173.     return 0;
  174.   if ((flags & FNM_LEADING_DIR) && *n == '/')
  175.     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
  176.     return 0;
  177.   return FNM_NOMATCH;
  178. }
  179. #endif /* _LIBC or not __GNU_LIBRARY__.  */