1 |
tim |
284 |
// Copyright (C) 1996 - 2002 Florian Schintke |
2 |
|
|
// |
3 |
|
|
// This is free software; you can redistribute it and/or modify it under |
4 |
|
|
// the terms of the GNU General Public License as published by the Free |
5 |
|
|
// Software Foundation; either version 2, or (at your option) any later |
6 |
|
|
// version. |
7 |
|
|
// |
8 |
|
|
// Thanks to the E.S.O. - ACS project that has done this C++ interface |
9 |
|
|
// to the wildcards pttern matching algorithm |
10 |
|
|
|
11 |
tim |
290 |
#include "wildcards.hpp" |
12 |
tim |
284 |
|
13 |
|
|
int |
14 |
|
|
Wildcard::wildcardfit(const char *wildcard, const char *test) |
15 |
|
|
{ |
16 |
|
|
int fit = 1; |
17 |
|
|
|
18 |
|
|
for (; ('\000' != *wildcard) && (1 == fit) && ('\000' != *test); wildcard++) |
19 |
|
|
{ |
20 |
|
|
switch (*wildcard) |
21 |
|
|
{ |
22 |
|
|
case '[': |
23 |
|
|
wildcard++; /* leave out the opening square bracket */ |
24 |
|
|
fit = set (&wildcard, &test); |
25 |
|
|
/* we don't need to decrement the wildcard as in case */ |
26 |
|
|
/* of asterisk because the closing ] is still there */ |
27 |
|
|
break; |
28 |
|
|
case '?': |
29 |
|
|
test++; |
30 |
|
|
break; |
31 |
|
|
case '*': |
32 |
|
|
fit = asterisk (&wildcard, &test); |
33 |
|
|
/* the asterisk was skipped by asterisk() but the loop will */ |
34 |
|
|
/* increment by itself. So we have to decrement */ |
35 |
|
|
wildcard--; |
36 |
|
|
break; |
37 |
|
|
default: |
38 |
|
|
fit = (int) (*wildcard == *test); |
39 |
|
|
test++; |
40 |
|
|
} |
41 |
|
|
} |
42 |
|
|
while ((*wildcard == '*') && (1 == fit)) |
43 |
|
|
/* here the teststring is empty otherwise you cannot */ |
44 |
|
|
/* leave the previous loop */ |
45 |
|
|
wildcard++; |
46 |
|
|
return (int) ((1 == fit) && ('\0' == *test) && ('\0' == *wildcard)); |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
int |
50 |
|
|
Wildcard::set(const char **wildcard, const char **test) |
51 |
|
|
{ |
52 |
|
|
int fit = 0; |
53 |
|
|
int negation = 0; |
54 |
|
|
int at_beginning = 1; |
55 |
|
|
|
56 |
|
|
if ('!' == **wildcard) |
57 |
|
|
{ |
58 |
|
|
negation = 1; |
59 |
|
|
(*wildcard)++; |
60 |
|
|
} |
61 |
|
|
while ((']' != **wildcard) || (1 == at_beginning)) |
62 |
|
|
{ |
63 |
|
|
if (0 == fit) |
64 |
|
|
{ |
65 |
|
|
if (('-' == **wildcard) |
66 |
|
|
&& ((*(*wildcard - 1)) < (*(*wildcard + 1))) |
67 |
|
|
&& (']' != *(*wildcard + 1)) |
68 |
|
|
&& (0 == at_beginning)) |
69 |
|
|
{ |
70 |
|
|
if (((**test) >= (*(*wildcard - 1))) |
71 |
|
|
&& ((**test) <= (*(*wildcard + 1)))) |
72 |
|
|
{ |
73 |
|
|
fit = 1; |
74 |
|
|
(*wildcard)++; |
75 |
|
|
} |
76 |
|
|
} |
77 |
|
|
else if ((**wildcard) == (**test)) |
78 |
|
|
{ |
79 |
|
|
fit = 1; |
80 |
|
|
} |
81 |
|
|
} |
82 |
|
|
(*wildcard)++; |
83 |
|
|
at_beginning = 0; |
84 |
|
|
} |
85 |
|
|
if (1 == negation) |
86 |
|
|
/* change from zero to one and vice versa */ |
87 |
|
|
fit = 1 - fit; |
88 |
|
|
if (1 == fit) |
89 |
|
|
(*test)++; |
90 |
|
|
|
91 |
|
|
return (fit); |
92 |
|
|
} |
93 |
|
|
|
94 |
|
|
int |
95 |
|
|
Wildcard::asterisk (const char **wildcard, const char **test) |
96 |
|
|
{ |
97 |
|
|
/* Warning: uses multiple returns */ |
98 |
|
|
int fit = 1; |
99 |
|
|
|
100 |
|
|
/* erase the leading asterisk */ |
101 |
|
|
(*wildcard)++; |
102 |
|
|
while (('\000' != (**test)) |
103 |
|
|
&& (('?' == **wildcard) |
104 |
|
|
|| ('*' == **wildcard))) |
105 |
|
|
{ |
106 |
|
|
if ('?' == **wildcard) |
107 |
|
|
(*test)++; |
108 |
|
|
(*wildcard)++; |
109 |
|
|
} |
110 |
|
|
/* Now it could be that test is empty and wildcard contains */ |
111 |
|
|
/* aterisks. Then we delete them to get a proper state */ |
112 |
|
|
while ('*' == (**wildcard)) |
113 |
|
|
(*wildcard)++; |
114 |
|
|
|
115 |
|
|
if (('\0' == (**test)) && ('\0' != (**wildcard))) |
116 |
|
|
return (fit = 0); |
117 |
|
|
if (('\0' == (**test)) && ('\0' == (**wildcard))) |
118 |
|
|
return (fit = 1); |
119 |
|
|
else |
120 |
|
|
{ |
121 |
|
|
/* Neither test nor wildcard are empty! */ |
122 |
|
|
/* the first character of wildcard isn't in [*?] */ |
123 |
|
|
if (0 == wildcardfit(*wildcard, (*test))) |
124 |
|
|
{ |
125 |
|
|
do |
126 |
|
|
{ |
127 |
|
|
(*test)++; |
128 |
|
|
/* skip as much characters as possible in the teststring */ |
129 |
|
|
/* stop if a character match occurs */ |
130 |
|
|
while (((**wildcard) != (**test)) |
131 |
|
|
&& ('[' != (**wildcard)) |
132 |
|
|
&& ('\0' != (**test))) |
133 |
|
|
(*test)++; |
134 |
|
|
} |
135 |
|
|
while ((('\0' != **test))? |
136 |
|
|
(0 == wildcardfit (*wildcard, (*test))) |
137 |
|
|
: (0 != (fit = 0))); |
138 |
|
|
} |
139 |
|
|
if (('\0' == **test) && ('\0' == **wildcard)) |
140 |
|
|
fit = 1; |
141 |
|
|
return (fit); |
142 |
|
|
} |
143 |
|
|
} |