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