rev |
line source |
yuuji@0
|
1 /* ========================================================================
|
yuuji@0
|
2 * Copyright 1988-2006 University of Washington
|
yuuji@0
|
3 *
|
yuuji@0
|
4 * Licensed under the Apache License, Version 2.0 (the "License");
|
yuuji@0
|
5 * you may not use this file except in compliance with the License.
|
yuuji@0
|
6 * You may obtain a copy of the License at
|
yuuji@0
|
7 *
|
yuuji@0
|
8 * http://www.apache.org/licenses/LICENSE-2.0
|
yuuji@0
|
9 *
|
yuuji@0
|
10 *
|
yuuji@0
|
11 * ========================================================================
|
yuuji@0
|
12 */
|
yuuji@0
|
13
|
yuuji@0
|
14 /*
|
yuuji@0
|
15 * Program: IMAP Wildcard Matching Routines (case-dependent)
|
yuuji@0
|
16 *
|
yuuji@0
|
17 * Author: Mark Crispin
|
yuuji@0
|
18 * Networks and Distributed Computing
|
yuuji@0
|
19 * Computing & Communications
|
yuuji@0
|
20 * University of Washington
|
yuuji@0
|
21 * Administration Building, AG-44
|
yuuji@0
|
22 * Seattle, WA 98195
|
yuuji@0
|
23 * Internet: MRC@CAC.Washington.EDU
|
yuuji@0
|
24 *
|
yuuji@0
|
25 * Date: 15 June 2000
|
yuuji@0
|
26 * Last Edited: 30 August 2006
|
yuuji@0
|
27 */
|
yuuji@0
|
28
|
yuuji@0
|
29 /* Wildcard pattern match
|
yuuji@0
|
30 * Accepts: base string
|
yuuji@0
|
31 * pattern string
|
yuuji@0
|
32 * delimiter character
|
yuuji@0
|
33 * Returns: T if pattern matches base, else NIL
|
yuuji@0
|
34 */
|
yuuji@0
|
35
|
yuuji@0
|
36 long pmatch_full (unsigned char *s,unsigned char *pat,unsigned char delim)
|
yuuji@0
|
37 {
|
yuuji@0
|
38 switch (*pat) {
|
yuuji@0
|
39 case '%': /* non-recursive */
|
yuuji@0
|
40 /* % at end, OK if no inferiors */
|
yuuji@0
|
41 if (!pat[1]) return (delim && strchr (s,delim)) ? NIL : T;
|
yuuji@0
|
42 /* scan remainder of string until delimiter */
|
yuuji@0
|
43 do if (pmatch_full (s,pat+1,delim)) return T;
|
yuuji@0
|
44 while ((*s != delim) && *s++);
|
yuuji@0
|
45 break;
|
yuuji@0
|
46 case '*': /* match 0 or more characters */
|
yuuji@0
|
47 if (!pat[1]) return T; /* * at end, unconditional match */
|
yuuji@0
|
48 /* scan remainder of string */
|
yuuji@0
|
49 do if (pmatch_full (s,pat+1,delim)) return T;
|
yuuji@0
|
50 while (*s++);
|
yuuji@0
|
51 break;
|
yuuji@0
|
52 case '\0': /* end of pattern */
|
yuuji@0
|
53 return *s ? NIL : T; /* success if also end of base */
|
yuuji@0
|
54 default: /* match this character */
|
yuuji@0
|
55 return (*pat == *s) ? pmatch_full (s+1,pat+1,delim) : NIL;
|
yuuji@0
|
56 }
|
yuuji@0
|
57 return NIL;
|
yuuji@0
|
58 }
|
yuuji@0
|
59
|
yuuji@0
|
60 /* Directory pattern match
|
yuuji@0
|
61 * Accepts: base string
|
yuuji@0
|
62 * pattern string
|
yuuji@0
|
63 * delimiter character
|
yuuji@0
|
64 * Returns: T if base is a matching directory of pattern, else NIL
|
yuuji@0
|
65 */
|
yuuji@0
|
66
|
yuuji@0
|
67 long dmatch (unsigned char *s,unsigned char *pat,unsigned char delim)
|
yuuji@0
|
68 {
|
yuuji@0
|
69 switch (*pat) {
|
yuuji@0
|
70 case '%': /* non-recursive */
|
yuuji@0
|
71 if (!*s) return T; /* end of base means have a subset match */
|
yuuji@0
|
72 if (!*++pat) return NIL; /* % at end, no inferiors permitted */
|
yuuji@0
|
73 /* scan remainder of string until delimiter */
|
yuuji@0
|
74 do if (dmatch (s,pat,delim)) return T;
|
yuuji@0
|
75 while ((*s != delim) && *s++);
|
yuuji@0
|
76 if (*s && !s[1]) return T; /* ends with delimiter, must be subset */
|
yuuji@0
|
77 return dmatch (s,pat,delim);/* do new scan */
|
yuuji@0
|
78 case '*': /* match 0 or more characters */
|
yuuji@0
|
79 return T; /* unconditional match */
|
yuuji@0
|
80 case '\0': /* end of pattern */
|
yuuji@0
|
81 break;
|
yuuji@0
|
82 default: /* match this character */
|
yuuji@0
|
83 if (*s) return (*pat == *s) ? dmatch (s+1,pat+1,delim) : NIL;
|
yuuji@0
|
84 /* end of base, return if at delimiter */
|
yuuji@0
|
85 else if (*pat == delim) return T;
|
yuuji@0
|
86 break;
|
yuuji@0
|
87 }
|
yuuji@0
|
88 return NIL;
|
yuuji@0
|
89 }
|