8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sendmail / libsm / match.c
blob944f30bc64b2d692c81ebcaef54441fb8498083a
1 /*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
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.
9 */
11 #pragma ident "%Z%%M% %I% %E% SMI"
13 #include <sm/gen.h>
14 SM_RCSID("@(#)$Id: match.c,v 1.8 2001/03/02 19:57:08 ca Exp $")
16 #include <sm/string.h>
19 ** SM_MATCH -- Match a character string against a glob pattern.
21 ** Parameters:
22 ** str -- string.
23 ** par -- pattern to find in str.
25 ** Returns:
26 ** true on match, false on non-match.
28 ** A pattern consists of normal characters, which match themselves,
29 ** and meta-sequences. A * matches any sequence of characters.
30 ** A ? matches any single character. A [ introduces a character class.
31 ** A ] marks the end of a character class; if the ] is missing then
32 ** the [ matches itself rather than introducing a character class.
33 ** A character class matches any of the characters between the brackets.
34 ** The range of characters from X to Y inclusive is written X-Y.
35 ** If the first character after the [ is ! then the character class is
36 ** complemented.
38 ** To include a ] in a character class, make it the first character
39 ** listed (after the !, if any). To include a -, make it the first
40 ** character listed (after the !, if any) or the last character.
41 ** It is impossible for a ] to be the final character in a range.
42 ** For glob patterns that literally match "*", "?" or "[",
43 ** use [*], [?] or [[].
46 bool
47 sm_match(str, pat)
48 const char *str;
49 const char *pat;
51 bool ccnot, ccmatch, ccfirst;
52 const char *ccstart;
53 char c, c2;
55 for (;;)
57 switch (*pat)
59 case '\0':
60 return *str == '\0';
61 case '?':
62 if (*str == '\0')
63 return false;
64 ++pat;
65 ++str;
66 continue;
67 case '*':
68 ++pat;
69 if (*pat == '\0')
71 /* optimize case of trailing '*' */
72 return true;
74 for (;;)
76 if (sm_match(pat, str))
77 return true;
78 if (*str == '\0')
79 return false;
80 ++str;
82 /* NOTREACHED */
83 case '[':
84 ccstart = pat++;
85 ccnot = false;
86 if (*pat == '!')
88 ccnot = true;
89 ++pat;
91 ccmatch = false;
92 ccfirst = true;
93 for (;;)
95 if (*pat == '\0')
97 pat = ccstart;
98 goto defl;
100 if (*pat == ']' && !ccfirst)
101 break;
102 c = *pat++;
103 ccfirst = false;
104 if (*pat == '-' && pat[1] != ']')
106 ++pat;
107 if (*pat == '\0')
109 pat = ccstart;
110 goto defl;
112 c2 = *pat++;
113 if (*str >= c && *str <= c2)
114 ccmatch = true;
116 else
118 if (*str == c)
119 ccmatch = true;
122 if (ccmatch ^ ccnot)
124 ++pat;
125 ++str;
127 else
128 return false;
129 continue;
130 default:
131 defl:
132 if (*pat != *str)
133 return false;
134 ++pat;
135 ++str;
136 continue;