File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / win32 / fnmatch.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:34:34 2012 UTC (12 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_3elwix, v5_4_29p0, v5_4_29, v5_4_20p0, v5_4_20, v5_4_17p0, v5_4_17, HEAD
php 5.4.3+patches

    1: /*
    2:  * Copyright (c) 1989, 1993, 1994
    3:  *	The Regents of the University of California.  All rights reserved.
    4:  *
    5:  * This code is derived from software contributed to Berkeley by
    6:  * Guido van Rossum.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions
   10:  * are met:
   11:  * 1. Redistributions of source code must retain the above copyright
   12:  *    notice, this list of conditions and the following disclaimer.
   13:  * 2. Redistributions in binary form must reproduce the above copyright
   14:  *    notice, this list of conditions and the following disclaimer in the
   15:  *    documentation and/or other materials provided with the distribution.
   16:  * 3. All advertising materials mentioning features or use of this software
   17:  *    must display the following acknowledgement:
   18:  *	This product includes software developed by the University of
   19:  *	California, Berkeley and its contributors.
   20:  * 4. Neither the name of the University nor the names of its contributors
   21:  *    may be used to endorse or promote products derived from this software
   22:  *    without specific prior written permission.
   23:  *
   24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34:  * SUCH DAMAGE.
   35:  *
   36:  * From FreeBSD fnmatch.c 1.11
   37:  * $Id: fnmatch.c,v 1.1.1.2 2012/05/29 12:34:34 misho Exp $
   38:  */
   39: 
   40: #if defined(LIBC_SCCS) && !defined(lint)
   41: static char sccsid[] = "@(#)fnmatch.c	8.2 (Berkeley) 4/16/94";
   42: #endif /* LIBC_SCCS and not lint */
   43: 
   44: /*
   45:  * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
   46:  * Compares a filename or pathname to a pattern.
   47:  */
   48: 
   49: #include <ctype.h>
   50: #include <string.h>
   51: #include <stdio.h>
   52: 
   53: #include "fnmatch.h"
   54: 
   55: #define	EOS	'\0'
   56: 
   57: static const char *rangematch(const char *, char, int);
   58: 
   59: PHPAPI int fnmatch(const char *pattern, const char *string, int flags)
   60: {
   61: 	const char *stringstart;
   62: 	char c, test;
   63: 
   64: 	for (stringstart = string;;)
   65: 		switch (c = *pattern++) {
   66: 		case EOS:
   67: 			if ((flags & FNM_LEADING_DIR) && *string == '/')
   68: 				return (0);
   69: 			return (*string == EOS ? 0 : FNM_NOMATCH);
   70: 		case '?':
   71: 			if (*string == EOS)
   72: 				return (FNM_NOMATCH);
   73: 			if (*string == '/' && (flags & FNM_PATHNAME))
   74: 				return (FNM_NOMATCH);
   75: 			if (*string == '.' && (flags & FNM_PERIOD) &&
   76: 			    (string == stringstart ||
   77: 			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
   78: 				return (FNM_NOMATCH);
   79: 			++string;
   80: 			break;
   81: 		case '*':
   82: 			c = *pattern;
   83: 			/* Collapse multiple stars. */
   84: 			while (c == '*')
   85: 				c = *++pattern;
   86: 
   87: 			if (*string == '.' && (flags & FNM_PERIOD) &&
   88: 			    (string == stringstart ||
   89: 			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
   90: 				return (FNM_NOMATCH);
   91: 
   92: 			/* Optimize for pattern with * at end or before /. */
   93: 			if (c == EOS)
   94: 				if (flags & FNM_PATHNAME)
   95: 					return ((flags & FNM_LEADING_DIR) ||
   96: 					    strchr(string, '/') == NULL ?
   97: 					    0 : FNM_NOMATCH);
   98: 				else
   99: 					return (0);
  100: 			else if (c == '/' && flags & FNM_PATHNAME) {
  101: 				if ((string = strchr(string, '/')) == NULL)
  102: 					return (FNM_NOMATCH);
  103: 				break;
  104: 			}
  105: 
  106: 			/* General case, use recursion. */
  107: 			while ((test = *string) != EOS) {
  108: 				if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
  109: 					return (0);
  110: 				if (test == '/' && flags & FNM_PATHNAME)
  111: 					break;
  112: 				++string;
  113: 			}
  114: 			return (FNM_NOMATCH);
  115: 		case '[':
  116: 			if (*string == EOS)
  117: 				return (FNM_NOMATCH);
  118: 			if (*string == '/' && flags & FNM_PATHNAME)
  119: 				return (FNM_NOMATCH);
  120: 			if ((pattern =
  121: 			    rangematch(pattern, *string, flags)) == NULL)
  122: 				return (FNM_NOMATCH);
  123: 			++string;
  124: 			break;
  125: 		case '\\':
  126: 			if (!(flags & FNM_NOESCAPE)) {
  127: 				if ((c = *pattern++) == EOS) {
  128: 					c = '\\';
  129: 					--pattern;
  130: 				}
  131: 			}
  132: 			/* FALLTHROUGH */
  133: 		default:
  134: 			if (c == *string)
  135: 				;
  136: 			else if ((flags & FNM_CASEFOLD) &&
  137: 				 (tolower((unsigned char)c) ==
  138: 				  tolower((unsigned char)*string)))
  139: 				;
  140: 			else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
  141: 			     (c == '/' && string != stringstart ||
  142: 			     string == stringstart+1 && *stringstart == '/') )
  143: 				return (0);
  144: 			else
  145: 				return (FNM_NOMATCH);
  146: 			string++;
  147: 			break;
  148: 		}
  149: 	/* NOTREACHED */
  150: }
  151: 
  152: static const char *
  153: rangematch(const char *pattern, char test, int flags)
  154: {
  155: 	int negate, ok;
  156: 	char c, c2;
  157: 
  158: 	/*
  159: 	 * A bracket expression starting with an unquoted circumflex
  160: 	 * character produces unspecified results (IEEE 1003.2-1992,
  161: 	 * 3.13.2).  This implementation treats it like '!', for
  162: 	 * consistency with the regular expression syntax.
  163: 	 * J.T. Conklin (conklin@ngai.kaleida.com)
  164: 	 */
  165: 	if ( (negate = (*pattern == '!' || *pattern == '^')) )
  166: 		++pattern;
  167: 
  168: 	if (flags & FNM_CASEFOLD)
  169: 		test = tolower((unsigned char)test);
  170: 
  171: 	for (ok = 0; (c = *pattern++) != ']';) {
  172: 		if (c == '\\' && !(flags & FNM_NOESCAPE))
  173: 			c = *pattern++;
  174: 		if (c == EOS)
  175: 			return (NULL);
  176: 
  177: 		if (flags & FNM_CASEFOLD)
  178: 			c = tolower((unsigned char)c);
  179: 
  180: 		if (*pattern == '-'
  181: 		    && (c2 = *(pattern+1)) != EOS && c2 != ']') {
  182: 			pattern += 2;
  183: 			if (c2 == '\\' && !(flags & FNM_NOESCAPE))
  184: 				c2 = *pattern++;
  185: 			if (c2 == EOS)
  186: 				return (NULL);
  187: 
  188: 			if (flags & FNM_CASEFOLD)
  189: 				c2 = tolower((unsigned char)c2);
  190: 
  191: 			if ((unsigned char)c <= (unsigned char)test &&
  192: 			    (unsigned char)test <= (unsigned char)c2)
  193: 				ok = 1;
  194: 		} else if (c == test)
  195: 			ok = 1;
  196: 	}
  197: 	return (ok == negate ? NULL : pattern);
  198: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>