1 | /* |
---|
2 | * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. |
---|
3 | * All rights reserved. |
---|
4 | * |
---|
5 | * By using this file, you agree to the terms and conditions set |
---|
6 | * forth in the LICENSE file which can be found at the top level of |
---|
7 | * the sendmail distribution. |
---|
8 | * |
---|
9 | */ |
---|
10 | |
---|
11 | #include <sm/gen.h> |
---|
12 | SM_RCSID("@(#)$Id: match.c,v 1.1.1.1 2003-04-08 15:06:04 zacheiss Exp $") |
---|
13 | |
---|
14 | #include <sm/string.h> |
---|
15 | |
---|
16 | /* |
---|
17 | ** SM_MATCH -- Match a character string against a glob pattern. |
---|
18 | ** |
---|
19 | ** Parameters: |
---|
20 | ** str -- string. |
---|
21 | ** par -- pattern to find in str. |
---|
22 | ** |
---|
23 | ** Returns: |
---|
24 | ** true on match, false on non-match. |
---|
25 | ** |
---|
26 | ** A pattern consists of normal characters, which match themselves, |
---|
27 | ** and meta-sequences. A * matches any sequence of characters. |
---|
28 | ** A ? matches any single character. A [ introduces a character class. |
---|
29 | ** A ] marks the end of a character class; if the ] is missing then |
---|
30 | ** the [ matches itself rather than introducing a character class. |
---|
31 | ** A character class matches any of the characters between the brackets. |
---|
32 | ** The range of characters from X to Y inclusive is written X-Y. |
---|
33 | ** If the first character after the [ is ! then the character class is |
---|
34 | ** complemented. |
---|
35 | ** |
---|
36 | ** To include a ] in a character class, make it the first character |
---|
37 | ** listed (after the !, if any). To include a -, make it the first |
---|
38 | ** character listed (after the !, if any) or the last character. |
---|
39 | ** It is impossible for a ] to be the final character in a range. |
---|
40 | ** For glob patterns that literally match "*", "?" or "[", |
---|
41 | ** use [*], [?] or [[]. |
---|
42 | */ |
---|
43 | |
---|
44 | bool |
---|
45 | sm_match(str, pat) |
---|
46 | const char *str; |
---|
47 | const char *pat; |
---|
48 | { |
---|
49 | bool ccnot, ccmatch, ccfirst; |
---|
50 | const char *ccstart; |
---|
51 | char c, c2; |
---|
52 | |
---|
53 | for (;;) |
---|
54 | { |
---|
55 | switch (*pat) |
---|
56 | { |
---|
57 | case '\0': |
---|
58 | return *str == '\0'; |
---|
59 | case '?': |
---|
60 | if (*str == '\0') |
---|
61 | return false; |
---|
62 | ++pat; |
---|
63 | ++str; |
---|
64 | continue; |
---|
65 | case '*': |
---|
66 | ++pat; |
---|
67 | if (*pat == '\0') |
---|
68 | { |
---|
69 | /* optimize case of trailing '*' */ |
---|
70 | return true; |
---|
71 | } |
---|
72 | for (;;) |
---|
73 | { |
---|
74 | if (sm_match(pat, str)) |
---|
75 | return true; |
---|
76 | if (*str == '\0') |
---|
77 | return false; |
---|
78 | ++str; |
---|
79 | } |
---|
80 | /* NOTREACHED */ |
---|
81 | case '[': |
---|
82 | ccstart = pat++; |
---|
83 | ccnot = false; |
---|
84 | if (*pat == '!') |
---|
85 | { |
---|
86 | ccnot = true; |
---|
87 | ++pat; |
---|
88 | } |
---|
89 | ccmatch = false; |
---|
90 | ccfirst = true; |
---|
91 | for (;;) |
---|
92 | { |
---|
93 | if (*pat == '\0') |
---|
94 | { |
---|
95 | pat = ccstart; |
---|
96 | goto defl; |
---|
97 | } |
---|
98 | if (*pat == ']' && !ccfirst) |
---|
99 | break; |
---|
100 | c = *pat++; |
---|
101 | ccfirst = false; |
---|
102 | if (*pat == '-' && pat[1] != ']') |
---|
103 | { |
---|
104 | ++pat; |
---|
105 | if (*pat == '\0') |
---|
106 | { |
---|
107 | pat = ccstart; |
---|
108 | goto defl; |
---|
109 | } |
---|
110 | c2 = *pat++; |
---|
111 | if (*str >= c && *str <= c2) |
---|
112 | ccmatch = true; |
---|
113 | } |
---|
114 | else |
---|
115 | { |
---|
116 | if (*str == c) |
---|
117 | ccmatch = true; |
---|
118 | } |
---|
119 | } |
---|
120 | if (ccmatch ^ ccnot) |
---|
121 | { |
---|
122 | ++pat; |
---|
123 | ++str; |
---|
124 | } |
---|
125 | else |
---|
126 | return false; |
---|
127 | continue; |
---|
128 | default: |
---|
129 | defl: |
---|
130 | if (*pat != *str) |
---|
131 | return false; |
---|
132 | ++pat; |
---|
133 | ++str; |
---|
134 | continue; |
---|
135 | } |
---|
136 | } |
---|
137 | } |
---|