home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.7z / ftp.whtech.com / emulators / v9t9 / linux / sources / V9t9 / source / fnmatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-10-19  |  5.6 KB  |  229 lines

  1. /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2.  *
  3.  * This library is free software; you can redistribute it and/or
  4.  * modify it under the terms of the GNU Library General Public
  5.  * License as published by the Free Software Foundation; either
  6.  * version 2 of the License, or (at your option) any later version.
  7.  *
  8.  * This library 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 GNU
  11.  * Library General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU Library General Public
  14.  * License along with this library; if not, write to the
  15.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16.  * Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. /*
  20.  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
  21.  * file for a list of people on the GTK+ Team.  See the ChangeLog
  22.  * files for a list of changes.  These files are distributed with
  23.  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  24.  */
  25.  
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29.  
  30. #include <errno.h>
  31.  
  32. /* Added for GTK. We need to make sure that all constants are defined
  33.  * to properly compile this file */
  34. #ifndef _GNU_SOURCE
  35. #define _GNU_SOURCE
  36. #endif
  37. #include "fnmatch.h"
  38.  
  39. /* We need glib.h for G_DIR_SEPARATOR and G_OS_WIN32 */
  40. #include <glib.h>
  41. #include <ctype.h>
  42.  
  43.  
  44. /* Comment out all this code if we are using the GNU C Library, and are not
  45.    actually compiling the library itself.  This code is part of the GNU C
  46.    Library, but also included in many other GNU distributions.  Compiling
  47.    and linking in this code is a waste when using the GNU C library
  48.    (especially if it is a shared library).  Rather than having every GNU
  49.    program understand `configure --with-gnu-libc' and omit the object files,
  50.    it is simpler to just do this in the source for each such file.  */
  51.  
  52. #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  53.  
  54. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) && !(defined(__MWERKS__) && defined(__MSL__))
  55. extern int errno;
  56. #endif
  57.  
  58. /* Match STRING against the filename pattern PATTERN, returning zero if
  59.    it matches, nonzero if not.  */
  60. int
  61. fnmatch (pattern, string, flags)
  62.      const char *pattern;
  63.      const char *string;
  64.      int flags;
  65. {
  66.   register const char *p = pattern, *n = string;
  67.   register char c;
  68.  
  69. /* Note that this evalutes C many times.  */
  70. #if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
  71. #define FOLD(c)    ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
  72. #else
  73. #define FOLD(c)    (tolower (c))
  74. #endif
  75.  
  76.   while ((c = *p++) != '\0')
  77.     {
  78.       c = FOLD (c);
  79.  
  80.       switch (c)
  81.     {
  82.     case '?':
  83.       if (*n == '\0')
  84.         return FNM_NOMATCH;
  85.       else if ((flags & FNM_FILE_NAME) && *n == G_DIR_SEPARATOR)
  86.         return FNM_NOMATCH;
  87.       else if ((flags & FNM_PERIOD) && *n == '.' &&
  88.            (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
  89.         return FNM_NOMATCH;
  90.       break;
  91. #ifndef G_OS_WIN32
  92.     case '\\':
  93.       if (!(flags & FNM_NOESCAPE))
  94.         {
  95.           c = *p++;
  96.           c = FOLD (c);
  97.         }
  98.       if (FOLD (*n) != c)
  99.         return FNM_NOMATCH;
  100.       break;
  101. #endif
  102.     case '*':
  103.       if ((flags & FNM_PERIOD) && *n == '.' &&
  104.           (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
  105.         return FNM_NOMATCH;
  106.  
  107.       for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  108.         if (((flags & FNM_FILE_NAME) && *n == G_DIR_SEPARATOR) ||
  109.         (c == '?' && *n == '\0'))
  110.           return FNM_NOMATCH;
  111.  
  112.       if (c == '\0')
  113.         return 0;
  114.  
  115.       {
  116. #ifndef G_OS_WIN32
  117.         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  118. #else
  119.         char c1 = c;
  120. #endif
  121.         c1 = FOLD (c1);
  122.         for (--p; *n != '\0'; ++n)
  123.           if ((c == '[' || FOLD (*n) == c1) &&
  124.           fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
  125.         return 0;
  126.         return FNM_NOMATCH;
  127.       }
  128.  
  129.     case '[':
  130.       {
  131.         /* Nonzero if the sense of the character class is inverted.  */
  132.         register int not;
  133.  
  134.         if (*n == '\0')
  135.           return FNM_NOMATCH;
  136.  
  137.         if ((flags & FNM_PERIOD) && *n == '.' &&
  138.         (n == string || ((flags & FNM_FILE_NAME) && n[-1] == G_DIR_SEPARATOR)))
  139.           return FNM_NOMATCH;
  140.  
  141.         not = (*p == '!' || *p == '^');
  142.         if (not)
  143.           ++p;
  144.  
  145.         c = *p++;
  146.         for (;;)
  147.           {
  148.         register char cstart = c, cend = c;
  149. #ifndef G_OS_WIN32
  150.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  151.           cstart = cend = *p++;
  152. #endif
  153.         cstart = cend = FOLD (cstart);
  154.  
  155.         if (c == '\0')
  156.           /* [ (unterminated) loses.  */
  157.           return FNM_NOMATCH;
  158.  
  159.         c = *p++;
  160.         c = FOLD (c);
  161.  
  162.         if ((flags & FNM_FILE_NAME) && c == G_DIR_SEPARATOR)
  163.           /* [/] can never match.  */
  164.           return FNM_NOMATCH;
  165.  
  166.         if (c == '-' && *p != ']')
  167.           {
  168.             cend = *p++;
  169. #ifndef G_OS_WIN32
  170.             if (!(flags & FNM_NOESCAPE) && cend == '\\')
  171.               cend = *p++;
  172. #endif
  173.             if (cend == '\0')
  174.               return FNM_NOMATCH;
  175.             cend = FOLD (cend);
  176.  
  177.             c = *p++;
  178.           }
  179.  
  180.         if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
  181.           goto matched;
  182.  
  183.         if (c == ']')
  184.           break;
  185.           }
  186.         if (!not)
  187.           return FNM_NOMATCH;
  188.         break;
  189.  
  190.       matched:;
  191.         /* Skip the rest of the [...] that already matched.  */
  192.         while (c != ']')
  193.           {
  194.         if (c == '\0')
  195.           /* [... (unterminated) loses.  */
  196.           return FNM_NOMATCH;
  197.  
  198.         c = *p++;
  199. #ifndef G_OS_WIN32
  200.         if (!(flags & FNM_NOESCAPE) && c == '\\')
  201.           /* XXX 1003.2d11 is unclear if this is right.  */
  202.           ++p;
  203. #endif
  204.           }
  205.         if (not)
  206.           return FNM_NOMATCH;
  207.       }
  208.       break;
  209.  
  210.     default:
  211.       if (c != FOLD (*n))
  212.         return FNM_NOMATCH;
  213.     }
  214.  
  215.       ++n;
  216.     }
  217.  
  218.   if (*n == '\0')
  219.     return 0;
  220.  
  221.   if ((flags & FNM_LEADING_DIR) && *n == G_DIR_SEPARATOR)
  222.     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
  223.     return 0;
  224.  
  225.   return FNM_NOMATCH;
  226. }
  227.  
  228. #endif    /* _LIBC or not __GNU_LIBRARY__.  */
  229.