1
/* ========================================================================
2
* Copyright 1988-2006 University of Washington
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
11
* ========================================================================
15
* Program: IMAP Wildcard Matching Routines (case-independent)
17
* Author: Mark Crispin
18
* Networks and Distributed Computing
19
* Computing & Communications
20
* University of Washington
21
* Administration Building, AG-44
23
* Internet: MRC@CAC.Washington.EDU
26
* Last Edited: 30 August 2006
29
/* Wildcard pattern match
30
* Accepts: base string
33
* Returns: T if pattern matches base, else NIL
36
long pmatch_full (unsigned char *s,unsigned char *pat,unsigned char delim)
39
case '%': /* non-recursive */
40
/* % at end, OK if no inferiors */
41
if (!pat[1]) return (delim && strchr (s,delim)) ? NIL : T;
42
/* scan remainder of string until delimiter */
43
do if (pmatch_full (s,pat+1,delim)) return T;
44
while ((*s != delim) && *s++);
46
case '*': /* match 0 or more characters */
47
if (!pat[1]) return T; /* * at end, unconditional match */
48
/* scan remainder of string */
49
do if (pmatch_full (s,pat+1,delim)) return T;
52
case '\0': /* end of pattern */
53
return *s ? NIL : T; /* success if also end of base */
54
default: /* match this character */
55
return compare_uchar (*pat,*s) ? NIL : pmatch_full (s+1,pat+1,delim);
60
/* Directory pattern match
61
* Accepts: base string
64
* Returns: T if base is a matching directory of pattern, else NIL
67
long dmatch (unsigned char *s,unsigned char *pat,unsigned char delim)
70
case '%': /* non-recursive */
71
if (!*s) return T; /* end of base means have a subset match */
72
if (!*++pat) return NIL; /* % at end, no inferiors permitted */
73
/* scan remainder of string until delimiter */
74
do if (dmatch (s,pat,delim)) return T;
75
while ((*s != delim) && *s++);
76
if (*s && !s[1]) return T; /* ends with delimiter, must be subset */
77
return dmatch (s,pat,delim);/* do new scan */
78
case '*': /* match 0 or more characters */
79
return T; /* unconditional match */
80
case '\0': /* end of pattern */
82
default: /* match this character */
83
if (*s) return compare_uchar (*pat,*s) ? NIL : dmatch (s+1,pat+1,delim);
84
/* end of base, return if at delimiter */
85
else if (*pat == delim) return T;