Home | History | Annotate | Line # | Download | only in libiberty
fnmatch.c revision 1.1.1.1.42.2
      1  1.1.1.1.42.2  martin /* Copyright (C) 1991-2018 Free Software Foundation, Inc.
      2           1.1     mrg 
      3           1.1     mrg NOTE: This source is derived from an old version taken from the GNU C
      4           1.1     mrg Library (glibc).
      5           1.1     mrg 
      6           1.1     mrg This program is free software; you can redistribute it and/or modify it
      7           1.1     mrg under the terms of the GNU General Public License as published by the
      8           1.1     mrg Free Software Foundation; either version 2, or (at your option) any
      9           1.1     mrg later version.
     10           1.1     mrg 
     11           1.1     mrg This program is distributed in the hope that it will be useful,
     12           1.1     mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     13           1.1     mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14           1.1     mrg GNU General Public License for more details.
     15           1.1     mrg 
     16           1.1     mrg You should have received a copy of the GNU General Public License
     17           1.1     mrg along with this program; if not, write to the Free Software
     18           1.1     mrg Foundation, 51 Franklin Street - Fifth Floor,
     19           1.1     mrg Boston, MA 02110-1301, USA.  */
     20           1.1     mrg 
     21           1.1     mrg #ifdef HAVE_CONFIG_H
     22           1.1     mrg #if defined (CONFIG_BROKETS)
     23           1.1     mrg /* We use <config.h> instead of "config.h" so that a compilation
     24           1.1     mrg    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
     25           1.1     mrg    (which it would do because it found this file in $srcdir).  */
     26           1.1     mrg #include <config.h>
     27           1.1     mrg #else
     28           1.1     mrg #include "config.h"
     29           1.1     mrg #endif
     30           1.1     mrg #endif
     31           1.1     mrg 
     32           1.1     mrg 
     33           1.1     mrg #ifndef _GNU_SOURCE
     34           1.1     mrg #define _GNU_SOURCE
     35           1.1     mrg #endif
     36           1.1     mrg 
     37           1.1     mrg /* This code to undef const added in libiberty.  */
     38           1.1     mrg #ifndef __STDC__
     39           1.1     mrg /* This is a separate conditional since some stdc systems
     40           1.1     mrg    reject `defined (const)'.  */
     41           1.1     mrg #ifndef const
     42           1.1     mrg #define const
     43           1.1     mrg #endif
     44           1.1     mrg #endif
     45           1.1     mrg 
     46           1.1     mrg #include <errno.h>
     47           1.1     mrg #include <fnmatch.h>
     48           1.1     mrg #include <safe-ctype.h>
     49           1.1     mrg 
     50           1.1     mrg /* Comment out all this code if we are using the GNU C Library, and are not
     51           1.1     mrg    actually compiling the library itself.  This code is part of the GNU C
     52           1.1     mrg    Library, but also included in many other GNU distributions.  Compiling
     53           1.1     mrg    and linking in this code is a waste when using the GNU C library
     54           1.1     mrg    (especially if it is a shared library).  Rather than having every GNU
     55           1.1     mrg    program understand `configure --with-gnu-libc' and omit the object files,
     56           1.1     mrg    it is simpler to just do this in the source for each such file.  */
     57           1.1     mrg 
     58           1.1     mrg #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
     59           1.1     mrg 
     60           1.1     mrg 
     61           1.1     mrg #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
     62           1.1     mrg extern int errno;
     63           1.1     mrg #endif
     64           1.1     mrg 
     65           1.1     mrg /* Match STRING against the filename pattern PATTERN, returning zero if
     66           1.1     mrg    it matches, nonzero if not.  */
     67           1.1     mrg int
     68           1.1     mrg fnmatch (const char *pattern, const char *string, int flags)
     69           1.1     mrg {
     70           1.1     mrg   register const char *p = pattern, *n = string;
     71           1.1     mrg   register unsigned char c;
     72           1.1     mrg 
     73           1.1     mrg #define FOLD(c)	((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c))
     74           1.1     mrg 
     75           1.1     mrg   while ((c = *p++) != '\0')
     76           1.1     mrg     {
     77           1.1     mrg       c = FOLD (c);
     78           1.1     mrg 
     79           1.1     mrg       switch (c)
     80           1.1     mrg 	{
     81           1.1     mrg 	case '?':
     82           1.1     mrg 	  if (*n == '\0')
     83           1.1     mrg 	    return FNM_NOMATCH;
     84           1.1     mrg 	  else if ((flags & FNM_FILE_NAME) && *n == '/')
     85           1.1     mrg 	    return FNM_NOMATCH;
     86           1.1     mrg 	  else if ((flags & FNM_PERIOD) && *n == '.' &&
     87           1.1     mrg 		   (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
     88           1.1     mrg 	    return FNM_NOMATCH;
     89           1.1     mrg 	  break;
     90           1.1     mrg 
     91           1.1     mrg 	case '\\':
     92           1.1     mrg 	  if (!(flags & FNM_NOESCAPE))
     93           1.1     mrg 	    {
     94           1.1     mrg 	      c = *p++;
     95           1.1     mrg 	      c = FOLD (c);
     96           1.1     mrg 	    }
     97           1.1     mrg 	  if (FOLD ((unsigned char)*n) != c)
     98           1.1     mrg 	    return FNM_NOMATCH;
     99           1.1     mrg 	  break;
    100           1.1     mrg 
    101           1.1     mrg 	case '*':
    102           1.1     mrg 	  if ((flags & FNM_PERIOD) && *n == '.' &&
    103           1.1     mrg 	      (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
    104           1.1     mrg 	    return FNM_NOMATCH;
    105           1.1     mrg 
    106           1.1     mrg 	  for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
    107           1.1     mrg 	    if (((flags & FNM_FILE_NAME) && *n == '/') ||
    108           1.1     mrg 		(c == '?' && *n == '\0'))
    109           1.1     mrg 	      return FNM_NOMATCH;
    110           1.1     mrg 
    111           1.1     mrg 	  if (c == '\0')
    112           1.1     mrg 	    return 0;
    113           1.1     mrg 
    114           1.1     mrg 	  {
    115           1.1     mrg 	    unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
    116           1.1     mrg 	    c1 = FOLD (c1);
    117           1.1     mrg 	    for (--p; *n != '\0'; ++n)
    118           1.1     mrg 	      if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
    119           1.1     mrg 		  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
    120           1.1     mrg 		return 0;
    121           1.1     mrg 	    return FNM_NOMATCH;
    122           1.1     mrg 	  }
    123           1.1     mrg 
    124           1.1     mrg 	case '[':
    125           1.1     mrg 	  {
    126           1.1     mrg 	    /* Nonzero if the sense of the character class is inverted.  */
    127           1.1     mrg 	    register int negate;
    128           1.1     mrg 
    129           1.1     mrg 	    if (*n == '\0')
    130           1.1     mrg 	      return FNM_NOMATCH;
    131           1.1     mrg 
    132           1.1     mrg 	    if ((flags & FNM_PERIOD) && *n == '.' &&
    133           1.1     mrg 		(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
    134           1.1     mrg 	      return FNM_NOMATCH;
    135           1.1     mrg 
    136           1.1     mrg 	    negate = (*p == '!' || *p == '^');
    137           1.1     mrg 	    if (negate)
    138           1.1     mrg 	      ++p;
    139           1.1     mrg 
    140           1.1     mrg 	    c = *p++;
    141           1.1     mrg 	    for (;;)
    142           1.1     mrg 	      {
    143           1.1     mrg 		register unsigned char cstart = c, cend = c;
    144           1.1     mrg 
    145           1.1     mrg 		if (!(flags & FNM_NOESCAPE) && c == '\\')
    146           1.1     mrg 		  cstart = cend = *p++;
    147           1.1     mrg 
    148           1.1     mrg 		cstart = cend = FOLD (cstart);
    149           1.1     mrg 
    150           1.1     mrg 		if (c == '\0')
    151           1.1     mrg 		  /* [ (unterminated) loses.  */
    152           1.1     mrg 		  return FNM_NOMATCH;
    153           1.1     mrg 
    154           1.1     mrg 		c = *p++;
    155           1.1     mrg 		c = FOLD (c);
    156           1.1     mrg 
    157           1.1     mrg 		if ((flags & FNM_FILE_NAME) && c == '/')
    158           1.1     mrg 		  /* [/] can never match.  */
    159           1.1     mrg 		  return FNM_NOMATCH;
    160           1.1     mrg 
    161           1.1     mrg 		if (c == '-' && *p != ']')
    162           1.1     mrg 		  {
    163           1.1     mrg 		    cend = *p++;
    164           1.1     mrg 		    if (!(flags & FNM_NOESCAPE) && cend == '\\')
    165           1.1     mrg 		      cend = *p++;
    166           1.1     mrg 		    if (cend == '\0')
    167           1.1     mrg 		      return FNM_NOMATCH;
    168           1.1     mrg 		    cend = FOLD (cend);
    169           1.1     mrg 
    170           1.1     mrg 		    c = *p++;
    171           1.1     mrg 		  }
    172           1.1     mrg 
    173           1.1     mrg 		if (FOLD ((unsigned char)*n) >= cstart
    174           1.1     mrg 		    && FOLD ((unsigned char)*n) <= cend)
    175           1.1     mrg 		  goto matched;
    176           1.1     mrg 
    177           1.1     mrg 		if (c == ']')
    178           1.1     mrg 		  break;
    179           1.1     mrg 	      }
    180           1.1     mrg 	    if (!negate)
    181           1.1     mrg 	      return FNM_NOMATCH;
    182           1.1     mrg 	    break;
    183           1.1     mrg 
    184           1.1     mrg 	  matched:;
    185           1.1     mrg 	    /* Skip the rest of the [...] that already matched.  */
    186           1.1     mrg 	    while (c != ']')
    187           1.1     mrg 	      {
    188           1.1     mrg 		if (c == '\0')
    189           1.1     mrg 		  /* [... (unterminated) loses.  */
    190           1.1     mrg 		  return FNM_NOMATCH;
    191           1.1     mrg 
    192           1.1     mrg 		c = *p++;
    193           1.1     mrg 		if (!(flags & FNM_NOESCAPE) && c == '\\')
    194           1.1     mrg 		  /* XXX 1003.2d11 is unclear if this is right.  */
    195           1.1     mrg 		  ++p;
    196           1.1     mrg 	      }
    197           1.1     mrg 	    if (negate)
    198           1.1     mrg 	      return FNM_NOMATCH;
    199           1.1     mrg 	  }
    200           1.1     mrg 	  break;
    201           1.1     mrg 
    202           1.1     mrg 	default:
    203           1.1     mrg 	  if (c != FOLD ((unsigned char)*n))
    204           1.1     mrg 	    return FNM_NOMATCH;
    205           1.1     mrg 	}
    206           1.1     mrg 
    207           1.1     mrg       ++n;
    208           1.1     mrg     }
    209           1.1     mrg 
    210           1.1     mrg   if (*n == '\0')
    211           1.1     mrg     return 0;
    212           1.1     mrg 
    213           1.1     mrg   if ((flags & FNM_LEADING_DIR) && *n == '/')
    214           1.1     mrg     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
    215           1.1     mrg     return 0;
    216           1.1     mrg 
    217           1.1     mrg   return FNM_NOMATCH;
    218           1.1     mrg }
    219           1.1     mrg 
    220           1.1     mrg #endif	/* _LIBC or not __GNU_LIBRARY__.  */
    221