source: trunk/third/sendmail/libsm/match.c @ 19204

Revision 19204, 2.8 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
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>
12SM_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
44bool
45sm_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}
Note: See TracBrowser for help on using the repository browser.