|
|
1.1 root 1: /*
2: * Copyright (c) 1989 The Regents of the University of California.
3: * 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 are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #if defined(LIBC_SCCS) && !defined(lint)
24: static char sccsid[] = "@(#)fnmatch.c 5.3 (Berkeley) 6/23/90";
25: #endif /* LIBC_SCCS and not lint */
26:
27: /*
28: * Function fnmatch() as proposed in Posix 1003.2 B.6 (rev. 9).
29: * Compares a filename or pathname to a pattern.
30: */
31:
32: #include <unistd.h>
33: #include <string.h>
34:
35: #define EOS '\0'
36:
37: static char *
38: rangematch(pattern, test)
39: register char *pattern, test;
40: {
41: register char c, c2;
42: int negate, ok;
43:
44: if (negate = (*pattern == '!'))
45: ++pattern;
46:
47: /*
48: * TO DO: quoting
49: */
50:
51: for (ok = 0; (c = *pattern++) != ']';) {
52: if (c == EOS)
53: return(NULL); /* illegal pattern */
54: if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {
55: if (c <= test && test <= c2)
56: ok = 1;
57: pattern += 2;
58: }
59: else if (c == test)
60: ok = 1;
61: }
62: return(ok == negate ? NULL : pattern);
63: }
64:
65: fnmatch(pattern, string, flags)
66: register char *pattern, *string;
67: int flags;
68: {
69: register char c;
70: char test, *rangematch();
71:
72: for (;;)
73: switch (c = *pattern++) {
74: case EOS:
75: return(*string == EOS);
76: case '?':
77: if ((test = *string++) == EOS ||
78: test == '/' && flags & FNM_PATHNAME)
79: return(0);
80: break;
81: case '*':
82: c = *pattern;
83: /* collapse multiple stars */
84: while (c == '*')
85: c = *++pattern;
86:
87: /* optimize for pattern with * at end or before / */
88: if (c == EOS)
89: if (flags & FNM_PATHNAME)
90: return(!index(string, '/'));
91: else
92: return(1);
93: else if (c == '/' && flags & FNM_PATHNAME) {
94: if ((string = index(string, '/')) == NULL)
95: return(0);
96: break;
97: }
98:
99: /* general case, use recursion */
100: while ((test = *string) != EOS) {
101: if (fnmatch(pattern, string, flags))
102: return(1);
103: if (test == '/' && flags & FNM_PATHNAME)
104: break;
105: ++string;
106: }
107: return(0);
108: case '[':
109: if ((test = *string++) == EOS ||
110: test == '/' && flags & FNM_PATHNAME)
111: return(0);
112: if ((pattern = rangematch(pattern, test)) == NULL)
113: return(0);
114: break;
115: case '\\':
116: if (flags & FNM_QUOTE) {
117: if ((c = *pattern++) == EOS) {
118: c = '\\';
119: --pattern;
120: }
121: if (c != *string++)
122: return(0);
123: break;
124: }
125: /* FALLTHROUGH */
126: default:
127: if (c != *string++)
128: return(0);
129: break;
130: }
131: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.