s/qmail
4.3.21
Next generation secure email transport
Loading...
Searching...
No Matches
4.3
sqmail-4.3.21
src
wildmat.c
Go to the documentation of this file.
1
/*** wildmat.c.orig Wed Dec 3 11:46:31 1997 */
2
/* $Revision: 1.1 $
3
**
4
** Do shell-style pattern matching for ?, \, [], and * characters.
5
** Might not be robust in face of malformed patterns; e.g., "foo[a-"
6
** could cause a segmentation violation. It is 8bit clean.
7
**
8
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
9
** Rich $alz is now <rsalz@osf.org>.
10
** April, 1991: Replaced mutually-recursive calls with in-line code
11
** for the star character.
12
**
13
** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
14
** This can greatly speed up failing wildcard patterns. For example:
15
** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
16
** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
17
** text 2: -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
18
** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without
19
** the ABORT code, it takes 22310 calls to fail. Ugh. The following
20
** explanation is from Lars:
21
** The precondition that must be fulfilled is that DoMatch will consume
22
** at least one character in text. This is true if *p is neither '*' nor
23
** '\0'.) The last return has ABORT instead of FALSE to avoid quadratic
24
** behaviour in cases like pattern "*a*b*c*d" with text "abcxxxxx". With
25
** FALSE, each star-loop has to run to the end of the text; with ABORT
26
** only the last one does.
27
**
28
** Once the control of one instance of DoMatch enters the star-loop, that
29
** instance will return either TRUE or ABORT, and any calling instance
30
** will therefore return immediately after (without calling recursively
31
** again). In effect, only one star-loop is ever active. It would be
32
** possible to modify the code to maintain this context explicitly,
33
** eliminating all recursive calls at the cost of some complication and
34
** loss of clarity (and the ABORT stuff seems to be unclear enough by
35
** itself). I think it would be unwise to try to get this into a
36
** released version unless you have a good test data base to try it out
37
** on.
38
*/
39
40
#define TRUE 1
41
#define FALSE 0
42
#define ABORT -1
43
44
/* What character marks an inverted character class? */
45
#define NEGATE_CLASS '^'
46
/* Is "*" a common pattern? */
47
#define OPTIMIZE_JUST_STAR
48
/* Do tar(1) matching rules, which ignore a trailing slash? */
49
#undef MATCH_TAR_PATTERN
50
51
/*
52
** Match text and p, return TRUE, FALSE, or ABORT.
53
*/
54
static
int
DoMatch(
register
char
*
text
,
register
char
*
p
)
55
{
56
register
int
last
;
57
register
int
matched;
58
register
int
reverse;
59
60
for
(; *
p
;
text
++,
p
++) {
61
if
(*
text
==
'\0'
&& *
p
!=
'*'
)
62
return
ABORT
;
63
switch
(*
p
) {
64
case
'\\'
:
/* Literal match with following character. */
65
p
++;
66
case
'?'
:
/* Match anything. */
67
continue
;
68
case
'*'
:
/* Consecutive stars act just like one. */
69
while
(*++
p
==
'*'
)
70
continue
;
71
if
(*
p
==
'\0'
)
return
TRUE
;
/* Trailing star matches everything. */
72
while
(*
text
)
73
if
((matched = DoMatch(
text
++,
p
)) !=
FALSE
)
return
matched;
74
return
ABORT
;
75
case
'['
:
76
reverse =
p
[1] ==
NEGATE_CLASS
?
TRUE
:
FALSE
;
77
if
(reverse)
p
++;
/* Inverted character class. */
78
matched =
FALSE
;
79
if
(
p
[1] ==
']'
||
p
[1] ==
'-'
)
80
if
(*++
p
== *
text
) matched =
TRUE
;
81
for
(
last
= *
p
; *++
p
&& *
p
!=
']'
;
last
= *
p
)
/* This next line requires a good C compiler. */
82
if
(*
p
==
'-'
&&
p
[1] !=
']'
? *
text <= *++p && *text >
=
last
: *
text
== *
p
)
83
matched =
TRUE
;
84
if
(matched == reverse)
return
FALSE
;
85
continue
;
86
default
:
/* FALLTHROUGH */
87
if
(*
text
!= *
p
)
return
FALSE
;
88
continue
;
89
}
90
}
91
92
#ifdef MATCH_TAR_PATTERN
93
if
(*
text
==
'/'
)
94
return
TRUE
;
95
#endif
/* MATCH_TAR_ATTERN */
96
return
*
text
==
'\0'
;
97
}
98
99
/*
100
** User-level routine. Returns TRUE or FALSE.
101
*/
102
int
wildmat
(
char
*
text
,
char
*
p
)
103
{
104
#ifdef OPTIMIZE_JUST_STAR
105
if
(
p
[0] ==
'*'
&&
p
[1] ==
'\0'
)
106
return
TRUE
;
107
#endif
/* OPTIMIZE_JUST_STAR */
108
return
DoMatch(
text
,
p
) ==
TRUE
;
109
}
p
void p(char *, char *, int, int, int)
Definition
install.c:49
text
stralloc text
Definition
maildirwatch.c:21
last
int last
Definition
qmail-pop3d.c:128
TRUE
#define TRUE
Definition
srs2.h:23
FALSE
#define FALSE
Definition
srs2.h:25
NEGATE_CLASS
#define NEGATE_CLASS
Definition
wildmat.c:45
wildmat
int wildmat(char *text, char *p)
Definition
wildmat.c:102
ABORT
#define ABORT
Definition
wildmat.c:42
Generated on
for s/qmail by
1.14.0