Moved DejaVue fonts to contrib. They are only needed by applications
[AROS-Contrib.git] / dopus / Library / wildcard.c
blob36183b64b4b1c58ca692356d80282fbf0e9ed2a4
1 /*
3 Directory Opus 4
4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 All users of Directory Opus 4 (including versions distributed
22 under the GPL) are entitled to upgrade to the latest version of
23 Directory Opus version 5 at a reduced price. Please see
24 http://www.gpsoft.com.au for more information.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
31 #define PROTO_DOPUS_H
32 #include "dopuslib.h"
33 //#include <proto/dos.h>
35 /*#define upper(c) ((c>='a' && c<='z')?(c-32):c)
37 struct MatchData {
38 unsigned char *str,*pat;
39 int levels,cas,flags;
43 int DoMatchPattern(register unsigned char *pat __asm("a0"), register unsigned char *str __asm("a1"), register int cas __asm("d0"));
44 void DoParsePattern(register unsigned char *pat __asm("a0"), register unsigned char *patbuf __asm("a1"), register int cas __asm("d0"));
45 //extern int WildMatch(struct MatchData *),findendor(struct MatchData *,int);
46 //extern struct DOpusBase *DOpusBase;
48 void /*__saveds*/ LParsePattern(register unsigned char *pat __asm("a0"),register unsigned char *patbuf __asm("a1"))
50 //D(bug("LParsePattern()\n");Delay(50));
51 DoParsePattern(pat,patbuf,0);
54 void /*__saveds*/ LParsePatternI(register unsigned char *pat __asm("a0"),register unsigned char *patbuf __asm("a1"))
56 //D(bug("LParsePatternI()\n");Delay(50));
57 DoParsePattern(pat,patbuf,1);
60 int /*__saveds*/ LMatchPattern(register unsigned char *pat __asm("a0"), register unsigned char *str __asm("a1"))
62 //D(bug("LMatchPattern()\n");Delay(50));
63 return DoMatchPattern(pat,str,0);
65 int /*__saveds*/ LMatchPatternI(register unsigned char *pat __asm("a0"), register unsigned char *str __asm("a1"))
67 //D(bug("LMatchPatternI()\n");Delay(50));
68 return DoMatchPattern(pat,str,1);
71 int __saveds DoMatchPattern(register unsigned char *pat __asm("a0"), register unsigned char *str __asm("a1"), register int cas __asm("d0"))
73 // if (DOSBase->dl_lib.lib_Version>35) {
74 int suc,old;
76 old=DOSBase->dl_Root->rn_Flags&RNF_WILDSTAR;
77 DOSBase->dl_Root->rn_Flags|=RNF_WILDSTAR;
78 suc = (cas ? MatchPatternNoCase(pat,str) : MatchPattern(pat,str));
79 if (!old) DOSBase->dl_Root->rn_Flags&=~RNF_WILDSTAR;
80 return(suc);
83 else {
84 struct MatchData mdata;
86 mdata.str=str;
87 mdata.pat=pat;
88 mdata.levels=mdata.flags=0;
89 mdata.cas=cas;
90 return(WildMatch(&mdata));
95 void __saveds DoParsePattern(register unsigned char *pat __asm("a0"), register unsigned char *patbuf __asm("a1"), register int cas __asm("d0"))
97 // if (DOSBase->dl_lib.lib_Version>35) {
98 int len,old;
100 old=DOSBase->dl_Root->rn_Flags&RNF_WILDSTAR;
101 DOSBase->dl_Root->rn_Flags|=RNF_WILDSTAR;
102 len=(strlen(pat)*2)+2;
104 (cas?ParsePatternNoCase(pat,patbuf,len):ParsePattern(pat,patbuf,len));
106 if (cas) ParsePatternNoCase(pat,patbuf,len);
107 else ParsePattern(pat,patbuf,len);
108 if (!old) DOSBase->dl_Root->rn_Flags&=~RNF_WILDSTAR;
111 else {
112 int or=0,class=0,rep=0;
114 while (*pat) {
115 switch (*pat) {
116 case '*':
117 if (rep) {
118 *patbuf++=P_REPEND;
119 rep=0;
121 *patbuf++=P_ANY;
122 break;
123 case '?':
124 if (rep) {
125 *patbuf++=P_REPEND;
126 rep=0;
128 *patbuf++=P_SINGLE;
129 break;
130 case '(':
131 if (rep) rep=0;
132 *patbuf++=P_ORSTART;
133 ++or;
134 break;
135 case '|':
136 if (rep) rep=0;
137 if (or) *patbuf++=P_ORNEXT;
138 else *patbuf++='|';
139 break;
140 case ')':
141 if (rep) {
142 *patbuf++=P_REPEND;
143 rep=0;
145 if (or) {
146 *patbuf++=P_OREND;
147 --or;
149 else *patbuf++=')';
150 break;
151 case '~':
152 if (rep) {
153 *patbuf++=P_REPEND;
154 rep=0;
156 *patbuf++=P_NOT;
157 break;
158 case '[':
159 if (class) *patbuf++='[';
160 else {
161 *patbuf++=P_CLASS;
162 class=1;
164 break;
165 case ']':
166 if (class) {
167 *patbuf++=P_CLASS;
168 class=0;
170 else *patbuf++=']';
171 if (rep) {
172 *patbuf++=P_REPEND;
173 rep=0;
175 break;
176 case '#':
177 if (*(pat+1)=='?' || *(pat+1)=='*') {
178 *patbuf++=P_ANY;
179 ++pat;
181 else {
182 *patbuf++=P_REPBEG;
183 rep=1;
185 break;
186 case '%':
187 break;
188 case '\'':
189 ++pat;
190 default:
191 *patbuf++=(cas)?upper(*pat):*pat;
192 if (rep && !class) {
193 *patbuf++=P_REPEND;
194 rep=0;
196 break;
198 ++pat;
200 *patbuf=0;
205 WildMatch(mdata)
206 struct MatchData *mdata;
208 int last,match,not=0,lnot,other=0,wild=0;
209 unsigned char ch,*str,mc,*pat=NULL;
211 if (!(mdata->flags&2)) {
212 for (last=0;;last++) {
213 if (mdata->pat[last]>0x7f) {
214 if (mdata->pat[last]!=P_ANY && mdata->pat[last]!=P_NOT &&
215 mdata->pat[last]!=P_SINGLE) other=1;
216 wild=1;
218 else if (!mdata->pat[last]) {
219 if (wild) break;
220 if (mdata->cas) return((LStrCmpI((char *)mdata->pat,(char *)mdata->str)==0));
221 return((strcmp((char *)mdata->pat,(char *)mdata->str)==0));
224 if (!other) {
225 match=1; lnot=0;
226 FOREVER {
227 if (*(mdata->pat)==P_NOT) {
228 if (!(*++mdata->pat)) break;
229 not=1-not; lnot=0;
231 else if (*(mdata->pat)==P_ANY) {
232 if (!(*++mdata->pat)) {
233 if (not) match=1-match;
234 return(match);
236 pat=mdata->pat; match=lnot=1;
238 else if (*(mdata->pat)==P_SINGLE) {
239 ++mdata->str;
240 match=1;
241 if (!(*++mdata->pat)) {
242 if (*mdata->str && pat) {
243 mdata->pat=pat;
244 continue;
246 break;
249 else {
250 mc=mdata->cas?upper(*(mdata->str)):*(mdata->str);
251 if (*mdata->str) ++mdata->str;
252 if (*(mdata->pat)!=mc) {
253 match=0;
254 if (!lnot) break;
255 if (pat && *(mdata->str)) {
256 mdata->pat=pat;
257 if (*(mdata->str-1)==*pat) --mdata->str;
259 else if (!(*++mdata->pat)) break;
261 else {
262 match=1;
263 if (!(*++mdata->pat)) {
264 if (*mdata->str && pat) {
265 mdata->pat=pat;
266 continue;
268 break;
273 if (match && !(*(mdata->str))) return(1-not);
274 return(not);
276 mdata->flags|=2;
279 for (;*(mdata->pat);mdata->pat++) {
280 doswitch:
281 switch (*(mdata->pat)) {
282 case P_NOT:
283 not=1-not;
284 continue;
285 case P_REPBEG:
286 ++mdata->pat;
287 mc=mdata->cas?upper(*(mdata->str)):*(mdata->str);
288 if ((ch=*(mdata->pat))==P_CLASS) {
289 for (last=256,match=0;*(++mdata->pat) && *(mdata->pat)!=P_CLASS;last=*(mdata->pat)) {
290 if (((*mdata->pat)=='-')?(mc<=*(++mdata->pat) &&
291 mc>=last):(mc==*(mdata->pat))) {
292 match=1; ch=*(mdata->pat);
295 if (!match) continue;
297 else if (ch>0x7f) goto doswitch;
298 if (mdata->cas) ch=upper(ch);
299 while (mc==ch) ++mdata->str;
300 case P_REPEND:
301 continue;
302 case P_SINGLE:
303 if (!(*(mdata->str))) return(not);
304 ++mdata->str;
305 continue;
306 case P_ORSTART:
307 str=mdata->str; match=0;
308 FOREVER {
309 ++mdata->pat; mdata->str=str;
310 ++mdata->levels;
311 if (WildMatch(mdata)) {
312 --mdata->levels;
313 match=1;
314 break;
316 --mdata->levels;
317 findendor(mdata,1);
318 if (*(mdata->pat)!=P_ORNEXT) break;
320 if (!match) {
321 if (!mdata->levels) return(not);
322 return(0);
324 findendor(mdata,0);
325 continue;
326 case P_ORNEXT:
327 case P_OREND:
328 if (mdata->levels) {
329 --mdata->pat;
330 return(1);
332 continue;
333 case P_ANY:
334 match=1;
335 if (*(++mdata->pat)) {
336 pat=mdata->pat;
337 while (!WildMatch(mdata)) {
338 if (!(*(++mdata->str))) {
339 match=0;
340 break;
342 mdata->pat=pat;
345 if (not) return(1-match);
346 return(match);
347 case P_CLASS:
348 pat=mdata->pat;
349 if (*(mdata->pat+1)=='~' || *(mdata->pat+1)=='^') {
350 lnot=1;
351 ++mdata->pat;
353 else lnot=0;
354 mc=mdata->cas?upper(*(mdata->str)):*(mdata->str);
355 for (last=256,match=0;*(++mdata->pat) && *(mdata->pat)!=P_CLASS;last=*(mdata->pat))
356 if (((*mdata->pat)=='-')?(mc<=*(++mdata->pat) &&
357 mc>=last):(mc==*(mdata->pat))) match=1-lnot;
358 if (match==not) {
359 mdata->pat=pat;
360 return(0);
362 ++mdata->str;
363 continue;
364 default:
365 mc=mdata->cas?upper(*(mdata->str)):*(mdata->str);
366 if (mc!=*(mdata->pat)) return(not);
367 ++mdata->str;
368 continue;
371 if (!(*(mdata->str))) return(1-not);
372 return(not);
375 findendor(mdata,a)
376 struct MatchData *mdata;
377 int a;
379 int lev=1;
381 if (*(mdata->pat)==P_OREND) ++mdata->pat;
382 while (*(mdata->pat)) {
383 if (*(mdata->pat)==P_ORNEXT && a && lev==1) return(0);
384 if (*(mdata->pat)==P_ORSTART) ++lev;
385 else if (*(mdata->pat)==P_OREND) {
386 --lev;
387 if (lev==0) return(0);
389 ++mdata->pat;