Annotation of src/lib/libc/gen/fnmatch.c, Revision 1.1.1.2
1.1 cgd 1: /*
1.1.1.2 ! cgd 2: * Copyright (c) 1989, 1993, 1994
! 3: * The Regents of the University of California. All rights reserved.
1.1 cgd 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:
37: #if defined(LIBC_SCCS) && !defined(lint)
1.1.1.2 ! cgd 38: static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
1.1 cgd 39: #endif /* LIBC_SCCS and not lint */
40:
41: /*
1.1.1.2 ! cgd 42: * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
1.1 cgd 43: * Compares a filename or pathname to a pattern.
44: */
45:
1.1.1.2 ! cgd 46: #include <fnmatch.h>
1.1 cgd 47: #include <string.h>
48:
49: #define EOS '\0'
50:
1.1.1.2 ! cgd 51: static const char *rangematch __P((const char *, int, int));
1.1 cgd 52:
1.1.1.2 ! cgd 53: int
1.1 cgd 54: fnmatch(pattern, string, flags)
1.1.1.2 ! cgd 55: const char *pattern, *string;
1.1 cgd 56: int flags;
57: {
1.1.1.2 ! cgd 58: const char *stringstart;
! 59: char c, test;
1.1 cgd 60:
1.1.1.2 ! cgd 61: for (stringstart = string;;)
1.1 cgd 62: switch (c = *pattern++) {
63: case EOS:
1.1.1.2 ! cgd 64: return (*string == EOS ? 0 : FNM_NOMATCH);
1.1 cgd 65: case '?':
1.1.1.2 ! cgd 66: if (*string == EOS)
! 67: return (FNM_NOMATCH);
! 68: if (*string == '/' && (flags & FNM_PATHNAME))
! 69: return (FNM_NOMATCH);
! 70: if (*string == '.' && (flags & FNM_PERIOD) &&
! 71: (string == stringstart ||
! 72: ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
! 73: return (FNM_NOMATCH);
! 74: ++string;
1.1 cgd 75: break;
76: case '*':
77: c = *pattern;
1.1.1.2 ! cgd 78: /* Collapse multiple stars. */
1.1 cgd 79: while (c == '*')
80: c = *++pattern;
81:
1.1.1.2 ! cgd 82: if (*string == '.' && (flags & FNM_PERIOD) &&
! 83: (string == stringstart ||
! 84: ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
! 85: return (FNM_NOMATCH);
! 86:
! 87: /* Optimize for pattern with * at end or before /. */
1.1 cgd 88: if (c == EOS)
89: if (flags & FNM_PATHNAME)
1.1.1.2 ! cgd 90: return (strchr(string, '/') == NULL ?
! 91: 0 : FNM_NOMATCH);
1.1 cgd 92: else
1.1.1.2 ! cgd 93: return (0);
1.1 cgd 94: else if (c == '/' && flags & FNM_PATHNAME) {
1.1.1.2 ! cgd 95: if ((string = strchr(string, '/')) == NULL)
! 96: return (FNM_NOMATCH);
1.1 cgd 97: break;
98: }
99:
1.1.1.2 ! cgd 100: /* General case, use recursion. */
1.1 cgd 101: while ((test = *string) != EOS) {
1.1.1.2 ! cgd 102: if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
! 103: return (0);
1.1 cgd 104: if (test == '/' && flags & FNM_PATHNAME)
105: break;
106: ++string;
107: }
1.1.1.2 ! cgd 108: return (FNM_NOMATCH);
1.1 cgd 109: case '[':
1.1.1.2 ! cgd 110: if (*string == EOS)
! 111: return (FNM_NOMATCH);
! 112: if (*string == '/' && flags & FNM_PATHNAME)
! 113: return (FNM_NOMATCH);
! 114: if ((pattern =
! 115: rangematch(pattern, *string, flags)) == NULL)
! 116: return (FNM_NOMATCH);
! 117: ++string;
1.1 cgd 118: break;
119: case '\\':
1.1.1.2 ! cgd 120: if (!(flags & FNM_NOESCAPE)) {
1.1 cgd 121: if ((c = *pattern++) == EOS) {
122: c = '\\';
123: --pattern;
124: }
125: }
126: /* FALLTHROUGH */
127: default:
128: if (c != *string++)
1.1.1.2 ! cgd 129: return (FNM_NOMATCH);
1.1 cgd 130: break;
131: }
1.1.1.2 ! cgd 132: /* NOTREACHED */
! 133: }
! 134:
! 135: static const char *
! 136: rangematch(pattern, test, flags)
! 137: const char *pattern;
! 138: int test, flags;
! 139: {
! 140: int negate, ok;
! 141: char c, c2;
! 142:
! 143: /*
! 144: * A bracket expression starting with an unquoted circumflex
! 145: * character produces unspecified results (IEEE 1003.2-1992,
! 146: * 3.13.2). This implementation treats it like '!', for
! 147: * consistency with the regular expression syntax.
! 148: * J.T. Conklin (conklin@ngai.kaleida.com)
! 149: */
! 150: if (negate = (*pattern == '!' || *pattern == '^'))
! 151: ++pattern;
! 152:
! 153: for (ok = 0; (c = *pattern++) != ']';) {
! 154: if (c == '\\' && !(flags & FNM_NOESCAPE))
! 155: c = *pattern++;
! 156: if (c == EOS)
! 157: return (NULL);
! 158: if (*pattern == '-'
! 159: && (c2 = *(pattern+1)) != EOS && c2 != ']') {
! 160: pattern += 2;
! 161: if (c2 == '\\' && !(flags & FNM_NOESCAPE))
! 162: c2 = *pattern++;
! 163: if (c2 == EOS)
! 164: return (NULL);
! 165: if (c <= test && test <= c2)
! 166: ok = 1;
! 167: } else if (c == test)
! 168: ok = 1;
! 169: }
! 170: return (ok == negate ? NULL : pattern);
1.1 cgd 171: }
CVSweb <webmaster@jp.NetBSD.org>