2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
5 Desc: Support functions for MatchFirst/MatchNext/MatchEnd
9 /****************************************************************************************/
11 #include <exec/memory.h>
13 #include <dos/dosextens.h>
14 #include <dos/dosasl.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
18 #include "dos_intern.h"
19 #include <aros/debug.h>
23 /****************************************************************************************/
25 #define COMPTYPE_NORMAL 1
26 #define COMPTYPE_PATTERN 2
27 #define COMPTYPE_UNKNOWN 3
29 /****************************************************************************************/
31 struct AChain
*Match_AllocAChain(LONG extrasize
, struct DosLibrary
*DOSBase
)
33 return AllocVec(sizeof(struct AChain
) + extrasize
, MEMF_PUBLIC
| MEMF_CLEAR
);
36 /****************************************************************************************/
38 void Match_FreeAChain(struct AChain
*ac
, struct DosLibrary
*DOSBase
)
43 /****************************************************************************************/
45 static void RemoveTrailingSlash(STRPTR s
)
51 if ((s
[len
- 1] == '/') &&
52 ((s
[len
- 2] != '/') && (s
[len
- 2] != ':')))
59 /**************************************************************************
61 The job of Match_BuildAChainList is to split the pattern string passed to
62 MatchFirst into path components. Most imporant rules (as found out after
63 hours of testing on Amiga):
65 - Each path component containing a pattern string is put into a single
67 - If there are several successive path components *without* pattern then
68 this are merged into one single AChain.
69 - No matter what: the last path component always gets into its own single
72 Examples: [<???>] is one AChain
75 pictures/#? [pictures} [#?]
77 work:pictures [work:} [pictures]
78 work:pictures/#? [work:pictures] [#?]
79 work:pictures/aros [work:pictures] [aros]
80 work:pictures/aros/games [work:pictures/aros] [games]
81 work:#?/aros/games [work:] [#?] [aros] [games}
82 work:#?/#?/aros/games/quake [work:} [#?] [#?] [aros/games] [quake]
84 **************************************************************************/
86 LONG
Match_BuildAChainList(CONST_STRPTR pattern
, struct AnchorPath
*ap
,
87 struct AChain
**retac
, struct DosLibrary
*DOSBase
)
89 struct AChain
*baseac
= 0, *prevac
= 0, *ac
;
90 STRPTR patterncopy
= 0;
91 STRPTR patternstart
, patternend
, patternpos
;
93 WORD comptype
= COMPTYPE_UNKNOWN
;
100 len
= strlen(pattern
);
102 patterncopy
= AllocVec(len
+ 1, MEMF_PUBLIC
);
105 error
= ERROR_NO_FREE_STORE
;
109 strcpy(patterncopy
, pattern
);
111 RemoveTrailingSlash(patterncopy
);
113 patternstart
= patterncopy
;
115 patternpos
= strchr(patterncopy
, ':');
118 comptype
= COMPTYPE_UNKNOWN
;
119 patternpos
= patternstart
;
120 patternend
= patternstart
;
124 comptype
= COMPTYPE_NORMAL
;
125 patternend
= patternpos
++;
136 if (comptype
== COMPTYPE_UNKNOWN
)
138 comptype
= COMPTYPE_NORMAL
;
139 patternend
= patternpos
;
141 else if (comptype
== COMPTYPE_NORMAL
)
143 patternend
= patternpos
;
146 if (comptype
== COMPTYPE_PATTERN
)
148 patternend
= patternpos
;
154 if (comptype
== COMPTYPE_UNKNOWN
)
156 comptype
= COMPTYPE_NORMAL
;
157 patternend
= patternpos
;
160 if (comptype
== COMPTYPE_NORMAL
)
165 patternend
= patternpos
;
168 else if ((c
== '#') ||
179 if (comptype
== COMPTYPE_NORMAL
)
183 comptype
= COMPTYPE_PATTERN
;
190 len
= (LONG
)(patternend
- patternstart
+ 2);
191 if (comptype
== COMPTYPE_PATTERN
) len
= len
* 2 + 2;
193 ac
= Match_AllocAChain(len
, DOSBase
);
196 error
= ERROR_NO_FREE_STORE
;
200 if (comptype
== COMPTYPE_NORMAL
)
202 if (*patternend
== '\0')
204 strcpy(ac
->an_String
, patternstart
);
207 patternend
[1] = '\0';
208 strcpy(ac
->an_String
, patternstart
);
212 } /* if (comptype == COMPTYPE_NORMAL) */
215 if (*patternend
== '\0')
217 i
= ParsePatternNoCase(patternstart
, ac
->an_String
, len
);
220 /* It is not a pattern, although we guessed it was one.
221 Do the strcpy, otherwise we have uppercase stuff in
222 ac->an_String because of ParsePatternNOCASE() */
223 strcpy(ac
->an_String
, patternstart
);
229 patternend
[1] = '\0';
230 i
= ParsePatternNoCase(patternstart
, ac
->an_String
, len
);
233 /* It is not a pattern, although we guessed it was one.
234 Do the strcpy, otherwise we have uppercase stuff in
235 ac->an_String because of ParsePatternNOCASE() */
236 strcpy(ac
->an_String
, patternstart
);
243 error
= ERROR_BAD_TEMPLATE
;
244 Match_FreeAChain(ac
, DOSBase
);ac
= 0;
250 ac
->an_Flags
|= DDF_PatternBit
;
251 ap
->ap_Flags
|= APF_ITSWILD
;
254 } /* if (comptype == COMPTYPE_NORMAL) else ... */
256 RemoveTrailingSlash(ac
->an_String
);
264 prevac
->an_Child
= ac
;
265 ac
->an_Parent
= prevac
;
270 patternpos
= patternend
;
271 comptype
= COMPTYPE_UNKNOWN
;
272 patternstart
= patternend
= patternpos
+ 1;
275 } while (*patternpos
++ != '\0');
278 if (patterncopy
) FreeVec(patterncopy
);
282 #if MATCHFUNCS_NO_DUPLOCK
284 * No DupLock() here, because then we would have to UnLock it in
285 * MatchEnd and we would not know any valid lock to which we could
286 * CurrentDir after, because we must make sure there is a valid
287 * CurrentDir after MatchEnd.
290 baseac
->an_Lock
= CurrentDir(0);
291 CurrentDir(baseac
->an_Lock
);
298 ap
->ap_Flags
|= APF_NOMEMERR
;
302 #define nextac prevac /* to not have to add another variable */
307 nextac
= ac
->an_Child
;
308 Match_FreeAChain(ac
, DOSBase
);
316 /******************************************************************************/
318 LONG
Match_MakeResult(struct AnchorPath
*ap
, struct DosLibrary
*DOSBase
)
323 ap
->ap_Info
= ap
->ap_Current
->an_Info
;
330 for(ac
= ap
->ap_Base
; (ac
&& !error
); ac
= ac
->an_Child
)
332 if (!AddPart(ap
->ap_Buf
,
333 ((ac
->an_Flags
& DDF_PatternBit
) ? ac
->an_Info
.fib_FileName
: ac
->an_String
),
344 ap
->ap_Info
= ap
->ap_Current
->an_Info
;
348 if (NameFromLock(ap
->ap_Current
->an_Lock
, ap
->ap_Buf
, ap
->ap_Strlen
))
350 if (!AddPart(ap
->ap_Buf
, ap
->ap_Current
->an_Info
.fib_FileName
, ap
->ap_Strlen
))
363 /******************************************************************************/