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-dependent)
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 (*pat
== *s
) ? pmatch_full (s
+1,pat
+1,delim
) : NIL
;
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 (*pat
== *s
) ? dmatch (s
+1,pat
+1,delim
) : NIL
;
84 /* end of base, return if at delimiter */
85 else if (*pat
== delim
) return T
;