Home | History | Annotate | Download | only in glob
      1 /* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
      2 This file is part of the GNU C Library.
      3 
      4 This 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 This 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 License
     15 along with this library; see the file COPYING.LIB.  If not, write to the Free
     16 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
     17 USA.  */
     18 
     19 #if HAVE_CONFIG_H
     20 # include <config.h>
     21 #endif
     22 
     23 /* Enable GNU extensions in fnmatch.h.  */
     24 #ifndef _GNU_SOURCE
     25 # define _GNU_SOURCE	1
     26 #endif
     27 
     28 #include <errno.h>
     29 #include <fnmatch.h>
     30 #include <ctype.h>
     31 
     32 #if HAVE_STRING_H || defined _LIBC
     33 # include <string.h>
     34 #else
     35 # include <strings.h>
     36 #endif
     37 
     38 #if defined STDC_HEADERS || defined _LIBC
     39 # include <stdlib.h>
     40 #endif
     41 
     42 /* For platform which support the ISO C amendement 1 functionality we
     43    support user defined character classes.  */
     44 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
     45 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
     46 # include <wchar.h>
     47 # include <wctype.h>
     48 #endif
     49 
     50 /* Comment out all this code if we are using the GNU C Library, and are not
     51    actually compiling the library itself.  This code is part of the GNU C
     52    Library, but also included in many other GNU distributions.  Compiling
     53    and linking in this code is a waste when using the GNU C library
     54    (especially if it is a shared library).  Rather than having every GNU
     55    program understand `configure --with-gnu-libc' and omit the object files,
     56    it is simpler to just do this in the source for each such file.  */
     57 
     58 #if defined _LIBC || !defined __GNU_LIBRARY__
     59 
     60 
     61 # if defined STDC_HEADERS || !defined isascii
     62 #  define ISASCII(c) 1
     63 # else
     64 #  define ISASCII(c) isascii(c)
     65 # endif
     66 
     67 # ifdef isblank
     68 #  define ISBLANK(c) (ISASCII (c) && isblank (c))
     69 # else
     70 #  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
     71 # endif
     72 # ifdef isgraph
     73 #  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
     74 # else
     75 #  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
     76 # endif
     77 
     78 # define ISPRINT(c) (ISASCII (c) && isprint (c))
     79 # define ISDIGIT(c) (ISASCII (c) && isdigit (c))
     80 # define ISALNUM(c) (ISASCII (c) && isalnum (c))
     81 # define ISALPHA(c) (ISASCII (c) && isalpha (c))
     82 # define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
     83 # define ISLOWER(c) (ISASCII (c) && islower (c))
     84 # define ISPUNCT(c) (ISASCII (c) && ispunct (c))
     85 # define ISSPACE(c) (ISASCII (c) && isspace (c))
     86 # define ISUPPER(c) (ISASCII (c) && isupper (c))
     87 # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
     88 
     89 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
     90 
     91 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
     92 /* The GNU C library provides support for user-defined character classes
     93    and the functions from ISO C amendement 1.  */
     94 #  ifdef CHARCLASS_NAME_MAX
     95 #   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
     96 #  else
     97 /* This shouldn't happen but some implementation might still have this
     98    problem.  Use a reasonable default value.  */
     99 #   define CHAR_CLASS_MAX_LENGTH 256
    100 #  endif
    101 
    102 #  ifdef _LIBC
    103 #   define IS_CHAR_CLASS(string) __wctype (string)
    104 #  else
    105 #   define IS_CHAR_CLASS(string) wctype (string)
    106 #  endif
    107 # else
    108 #  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
    109 
    110 #  define IS_CHAR_CLASS(string)						      \
    111    (STREQ (string, "alpha") || STREQ (string, "upper")			      \
    112     || STREQ (string, "lower") || STREQ (string, "digit")		      \
    113     || STREQ (string, "alnum") || STREQ (string, "xdigit")		      \
    114     || STREQ (string, "space") || STREQ (string, "print")		      \
    115     || STREQ (string, "punct") || STREQ (string, "graph")		      \
    116     || STREQ (string, "cntrl") || STREQ (string, "blank"))
    117 # endif
    118 
    119 /* Avoid depending on library functions or files
    120    whose names are inconsistent.  */
    121 
    122 # if !defined _LIBC && !defined getenv
    123 extern char *getenv ();
    124 # endif
    125 
    126 # ifndef errno
    127 extern int errno;
    128 # endif
    129 
    130 /* This function doesn't exist on most systems.  */
    131 
    132 # if !defined HAVE___STRCHRNUL && !defined _LIBC
    133 static char *
    134 __strchrnul (s, c)
    135      const char *s;
    136      int c;
    137 {
    138   char *result = strchr (s, c);
    139   if (result == NULL)
    140     result = strchr (s, '\0');
    141   return result;
    142 }
    143 # endif
    144 
    145 # ifndef internal_function
    146 /* Inside GNU libc we mark some function in a special way.  In other
    147    environments simply ignore the marking.  */
    148 #  define internal_function
    149 # endif
    150 
    151 /* Match STRING against the filename pattern PATTERN, returning zero if
    152    it matches, nonzero if not.  */
    153 static int internal_fnmatch __P ((const char *pattern, const char *string,
    154 				  int no_leading_period, int flags))
    155      internal_function;
    156 static int
    157 internal_function
    158 internal_fnmatch (pattern, string, no_leading_period, flags)
    159      const char *pattern;
    160      const char *string;
    161      int no_leading_period;
    162      int flags;
    163 {
    164   register const char *p = pattern, *n = string;
    165   register unsigned char c;
    166 
    167 /* Note that this evaluates C many times.  */
    168 # ifdef _LIBC
    169 #  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
    170 # else
    171 #  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
    172 # endif
    173 
    174   while ((c = *p++) != '\0')
    175     {
    176       c = FOLD (c);
    177 
    178       switch (c)
    179 	{
    180 	case '?':
    181 	  if (*n == '\0')
    182 	    return FNM_NOMATCH;
    183 	  else if (*n == '/' && (flags & FNM_FILE_NAME))
    184 	    return FNM_NOMATCH;
    185 	  else if (*n == '.' && no_leading_period
    186 		   && (n == string
    187 		       || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
    188 	    return FNM_NOMATCH;
    189 	  break;
    190 
    191 	case '\\':
    192 	  if (!(flags & FNM_NOESCAPE))
    193 	    {
    194 	      c = *p++;
    195 	      if (c == '\0')
    196 		/* Trailing \ loses.  */
    197 		return FNM_NOMATCH;
    198 	      c = FOLD (c);
    199 	    }
    200 	  if (FOLD ((unsigned char) *n) != c)
    201 	    return FNM_NOMATCH;
    202 	  break;
    203 
    204 	case '*':
    205 	  if (*n == '.' && no_leading_period
    206 	      && (n == string
    207 		  || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
    208 	    return FNM_NOMATCH;
    209 
    210 	  for (c = *p++; c == '?' || c == '*'; c = *p++)
    211 	    {
    212 	      if (*n == '/' && (flags & FNM_FILE_NAME))
    213 		/* A slash does not match a wildcard under FNM_FILE_NAME.  */
    214 		return FNM_NOMATCH;
    215 	      else if (c == '?')
    216 		{
    217 		  /* A ? needs to match one character.  */
    218 		  if (*n == '\0')
    219 		    /* There isn't another character; no match.  */
    220 		    return FNM_NOMATCH;
    221 		  else
    222 		    /* One character of the string is consumed in matching
    223 		       this ? wildcard, so *??? won't match if there are
    224 		       less than three characters.  */
    225 		    ++n;
    226 		}
    227 	    }
    228 
    229 	  if (c == '\0')
    230 	    /* The wildcard(s) is/are the last element of the pattern.
    231 	       If the name is a file name and contains another slash
    232 	       this does mean it cannot match.  */
    233 	    return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
    234 		    ? FNM_NOMATCH : 0);
    235 	  else
    236 	    {
    237 	      const char *endp;
    238 
    239 	      endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
    240 
    241 	      if (c == '[')
    242 		{
    243 		  int flags2 = ((flags & FNM_FILE_NAME)
    244 				? flags : (flags & ~FNM_PERIOD));
    245 
    246 		  for (--p; n < endp; ++n)
    247 		    if (internal_fnmatch (p, n,
    248 					  (no_leading_period
    249 					   && (n == string
    250 					       || (n[-1] == '/'
    251 						   && (flags
    252 						       & FNM_FILE_NAME)))),
    253 					  flags2)
    254 			== 0)
    255 		      return 0;
    256 		}
    257 	      else if (c == '/' && (flags & FNM_FILE_NAME))
    258 		{
    259 		  while (*n != '\0' && *n != '/')
    260 		    ++n;
    261 		  if (*n == '/'
    262 		      && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
    263 					    flags) == 0))
    264 		    return 0;
    265 		}
    266 	      else
    267 		{
    268 		  int flags2 = ((flags & FNM_FILE_NAME)
    269 				? flags : (flags & ~FNM_PERIOD));
    270 
    271 		  if (c == '\\' && !(flags & FNM_NOESCAPE))
    272 		    c = *p;
    273 		  c = FOLD (c);
    274 		  for (--p; n < endp; ++n)
    275 		    if (FOLD ((unsigned char) *n) == c
    276 			&& (internal_fnmatch (p, n,
    277 					      (no_leading_period
    278 					       && (n == string
    279 						   || (n[-1] == '/'
    280 						       && (flags
    281 							   & FNM_FILE_NAME)))),
    282 					      flags2) == 0))
    283 		      return 0;
    284 		}
    285 	    }
    286 
    287 	  /* If we come here no match is possible with the wildcard.  */
    288 	  return FNM_NOMATCH;
    289 
    290 	case '[':
    291 	  {
    292 	    /* Nonzero if the sense of the character class is inverted.  */
    293 	    static int posixly_correct;
    294 	    register int not;
    295 	    char cold;
    296 
    297 	    if (posixly_correct == 0)
    298 	      posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
    299 
    300 	    if (*n == '\0')
    301 	      return FNM_NOMATCH;
    302 
    303 	    if (*n == '.' && no_leading_period && (n == string
    304 						   || (n[-1] == '/'
    305 						       && (flags
    306 							   & FNM_FILE_NAME))))
    307 	      return FNM_NOMATCH;
    308 
    309 	    if (*n == '/' && (flags & FNM_FILE_NAME))
    310 	      /* `/' cannot be matched.  */
    311 	      return FNM_NOMATCH;
    312 
    313 	    not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
    314 	    if (not)
    315 	      ++p;
    316 
    317 	    c = *p++;
    318 	    for (;;)
    319 	      {
    320 		unsigned char fn = FOLD ((unsigned char) *n);
    321 
    322 		if (!(flags & FNM_NOESCAPE) && c == '\\')
    323 		  {
    324 		    if (*p == '\0')
    325 		      return FNM_NOMATCH;
    326 		    c = FOLD ((unsigned char) *p);
    327 		    ++p;
    328 
    329 		    if (c == fn)
    330 		      goto matched;
    331 		  }
    332 		else if (c == '[' && *p == ':')
    333 		  {
    334 		    /* Leave room for the null.  */
    335 		    char str[CHAR_CLASS_MAX_LENGTH + 1];
    336 		    size_t c1 = 0;
    337 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
    338 		    wctype_t wt;
    339 # endif
    340 		    const char *startp = p;
    341 
    342 		    for (;;)
    343 		      {
    344 			if (c1 == CHAR_CLASS_MAX_LENGTH)
    345 			  /* The name is too long and therefore the pattern
    346 			     is ill-formed.  */
    347 			  return FNM_NOMATCH;
    348 
    349 			c = *++p;
    350 			if (c == ':' && p[1] == ']')
    351 			  {
    352 			    p += 2;
    353 			    break;
    354 			  }
    355 			if (c < 'a' || c >= 'z')
    356 			  {
    357 			    /* This cannot possibly be a character class name.
    358 			       Match it as a normal range.  */
    359 			    p = startp;
    360 			    c = '[';
    361 			    goto normal_bracket;
    362 			  }
    363 			str[c1++] = c;
    364 		      }
    365 		    str[c1] = '\0';
    366 
    367 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
    368 		    wt = IS_CHAR_CLASS (str);
    369 		    if (wt == 0)
    370 		      /* Invalid character class name.  */
    371 		      return FNM_NOMATCH;
    372 
    373 		    if (__iswctype (__btowc ((unsigned char) *n), wt))
    374 		      goto matched;
    375 # else
    376 		    if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
    377 			|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
    378 			|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
    379 			|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
    380 			|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
    381 			|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
    382 			|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
    383 			|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
    384 			|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
    385 			|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
    386 			|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
    387 			|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
    388 		      goto matched;
    389 # endif
    390 		  }
    391 		else if (c == '\0')
    392 		  /* [ (unterminated) loses.  */
    393 		  return FNM_NOMATCH;
    394 		else
    395 		  {
    396 		  normal_bracket:
    397 		    if (FOLD (c) == fn)
    398 		      goto matched;
    399 
    400 		    cold = c;
    401 		    c = *p++;
    402 
    403 		    if (c == '-' && *p != ']')
    404 		      {
    405 			/* It is a range.  */
    406 			unsigned char cend = *p++;
    407 			if (!(flags & FNM_NOESCAPE) && cend == '\\')
    408 			  cend = *p++;
    409 			if (cend == '\0')
    410 			  return FNM_NOMATCH;
    411 
    412 			if (cold <= fn && fn <= FOLD (cend))
    413 			  goto matched;
    414 
    415 			c = *p++;
    416 		      }
    417 		  }
    418 
    419 		if (c == ']')
    420 		  break;
    421 	      }
    422 
    423 	    if (!not)
    424 	      return FNM_NOMATCH;
    425 	    break;
    426 
    427 	  matched:
    428 	    /* Skip the rest of the [...] that already matched.  */
    429 	    while (c != ']')
    430 	      {
    431 		if (c == '\0')
    432 		  /* [... (unterminated) loses.  */
    433 		  return FNM_NOMATCH;
    434 
    435 		c = *p++;
    436 		if (!(flags & FNM_NOESCAPE) && c == '\\')
    437 		  {
    438 		    if (*p == '\0')
    439 		      return FNM_NOMATCH;
    440 		    /* XXX 1003.2d11 is unclear if this is right.  */
    441 		    ++p;
    442 		  }
    443 		else if (c == '[' && *p == ':')
    444 		  {
    445 		    do
    446 		      if (*++p == '\0')
    447 			return FNM_NOMATCH;
    448 		    while (*p != ':' || p[1] == ']');
    449 		    p += 2;
    450 		    c = *p;
    451 		  }
    452 	      }
    453 	    if (not)
    454 	      return FNM_NOMATCH;
    455 	  }
    456 	  break;
    457 
    458 	default:
    459 	  if (c != FOLD ((unsigned char) *n))
    460 	    return FNM_NOMATCH;
    461 	}
    462 
    463       ++n;
    464     }
    465 
    466   if (*n == '\0')
    467     return 0;
    468 
    469   if ((flags & FNM_LEADING_DIR) && *n == '/')
    470     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
    471     return 0;
    472 
    473   return FNM_NOMATCH;
    474 
    475 # undef FOLD
    476 }
    477 
    478 
    479 int
    480 fnmatch (pattern, string, flags)
    481      const char *pattern;
    482      const char *string;
    483      int flags;
    484 {
    485   return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
    486 }
    487 
    488 #endif	/* _LIBC or not __GNU_LIBRARY__.  */
    489