Home | History | Annotate | Line # | Download | only in libiberty
      1  1.1.1.9  mrg /* Copyright (C) 1991-2024 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