Path: blob/main/crypto/heimdal/lib/roken/fnmatch.c
39507 views
/* $NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $ */12/*3* Copyright (c) 1989, 1993, 19944* The Regents of the University of California. All rights reserved.5*6* This code is derived from software contributed to Berkeley by7* Guido van Rossum.8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12* 1. Redistributions of source code must retain the above copyright13* notice, this list of conditions and the following disclaimer.14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17* 3. Neither the name of the University nor the names of its contributors18* may be used to endorse or promote products derived from this software19* without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND22* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE23* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE24* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE25* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL26* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS27* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)28* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT29* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY30* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/3334#if defined(LIBC_SCCS) && !defined(lint)35#if 036static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";37#else38static char rcsid[] = "$NetBSD: fnmatch.c,v 1.11 1995/02/27 03:43:06 cgd Exp $";39#endif40#endif /* LIBC_SCCS and not lint */4142/*43* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.44* Compares a filename or pathname to a pattern.45*/4647#ifdef HAVE_CONFIG_H48#include <config.h>49#endif5051#include <roken.h>5253#include <fnmatch.h>54#include <string.h>5556#define EOS '\0'5758static const char *rangematch (const char *, int, int);5960ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL61rk_fnmatch(const char *pattern, const char *string, int flags)62{63const char *stringstart;64char c, test;6566for (stringstart = string;;)67switch (c = *pattern++) {68case EOS:69return (*string == EOS ? 0 : FNM_NOMATCH);70case '?':71if (*string == EOS)72return (FNM_NOMATCH);73if (*string == '/' && (flags & FNM_PATHNAME))74return (FNM_NOMATCH);75if (*string == '.' && (flags & FNM_PERIOD) &&76(string == stringstart ||77((flags & FNM_PATHNAME) && *(string - 1) == '/')))78return (FNM_NOMATCH);79++string;80break;81case '*':82c = *pattern;83/* Collapse multiple stars. */84while (c == '*')85c = *++pattern;8687if (*string == '.' && (flags & FNM_PERIOD) &&88(string == stringstart ||89((flags & FNM_PATHNAME) && *(string - 1) == '/')))90return (FNM_NOMATCH);9192/* Optimize for pattern with * at end or before /. */93if (c == EOS)94if (flags & FNM_PATHNAME)95return (strchr(string, '/') == NULL ?960 : FNM_NOMATCH);97else98return (0);99else if (c == '/' && flags & FNM_PATHNAME) {100if ((string = strchr(string, '/')) == NULL)101return (FNM_NOMATCH);102break;103}104105/* General case, use recursion. */106while ((test = *string) != EOS) {107if (!rk_fnmatch(pattern, string, flags & ~FNM_PERIOD))108return (0);109if (test == '/' && flags & FNM_PATHNAME)110break;111++string;112}113return (FNM_NOMATCH);114case '[':115if (*string == EOS)116return (FNM_NOMATCH);117if (*string == '/' && flags & FNM_PATHNAME)118return (FNM_NOMATCH);119if ((pattern =120rangematch(pattern, *string, flags)) == NULL)121return (FNM_NOMATCH);122++string;123break;124case '\\':125if (!(flags & FNM_NOESCAPE)) {126if ((c = *pattern++) == EOS) {127c = '\\';128--pattern;129}130}131/* FALLTHROUGH */132default:133if (c != *string++)134return (FNM_NOMATCH);135break;136}137/* NOTREACHED */138}139140static const char *141rangematch(const char *pattern, int test, int flags)142{143int negate, ok;144char c, c2;145146/*147* A bracket expression starting with an unquoted circumflex148* character produces unspecified results (IEEE 1003.2-1992,149* 3.13.2). This implementation treats it like '!', for150* consistency with the regular expression syntax.151* J.T. Conklin ([email protected])152*/153if (negate = (*pattern == '!' || *pattern == '^'))154++pattern;155156for (ok = 0; (c = *pattern++) != ']';) {157if (c == '\\' && !(flags & FNM_NOESCAPE))158c = *pattern++;159if (c == EOS)160return (NULL);161if (*pattern == '-'162&& (c2 = *(pattern+1)) != EOS && c2 != ']') {163pattern += 2;164if (c2 == '\\' && !(flags & FNM_NOESCAPE))165c2 = *pattern++;166if (c2 == EOS)167return (NULL);168if (c <= test && test <= c2)169ok = 1;170} else if (c == test)171ok = 1;172}173return (ok == negate ? NULL : pattern);174}175176177