The release 2.0 dos.library introduced several other functions for directory scanning: LONG MatchFirst(UBYTE *mypattern, struct AnchorPath *myanchorpath); LONG MatchNext(struct AnchorPath *myanchorpath); VOID MatchEnd(struct AnchorPath *myanchorpath); When using these functions, an application first calls MatchFirst(), which performs some initialization (like calling ParsePattern() on the pattern matching string, mypattern) and finds the first directory entry that matches the directory entry mypattern. This pattern is relative to the current directory. An application must use the the MatchNext() call to find subsequent matching directory entries. After the application is done looking for matches or the application encounters an error, it must call MatchEnd() to release internal buffers. Before using these functions, you need to set up an AnchorPath structure. This structure must be initialized by MatchFirst() and passed to MatchNext() and MatchEnd() so they can keep track of the directory scan. An application must not make any changes to this structure while in the middle of a directory scan (before calling MatchEnd()). This AnchorPath structure must be longword aligned and is defined in <dos/dosasl.h> as follows: struct AnchorPath { struct AChain *ap_Base; /* Pointer to the first anchor */ #define ap_First ap_Base /* Compatibility synonym. Don't use */ struct AChain *ap_Last; /* Pointer to the last anchor */ #define ap_Current ap_Last /* Compatiblity synomym. Don't use */ LONG ap_BreakBits; /* Bit flags to stop scanning */ LONG ap_FoundBreak; /* Bits flags which caused the stop */ BYTE ap_Flags; /* Behaviour flags */ BYTE ap_Reserved; /* Reserved for now */ WORD ap_Strlen; /* Buffer size for path name */ /* This used to be ap_Length */ #define ap_Length ap_Flags /* Compatibility for LONGWORD ap_Length */ /* Don't use */ struct FileInfoBlock ap_Info; /* FileInfoBlock for matched entry */ UBYTE ap_Buf[1]; /* Application allocated buffer for full */ /* path name*/ }; If your application does not need a full path name to matching directory entries, it should initialize the ap_Strlen field to zero. In this case, your application can get what it needs from the AnchorPath's ap_Info field. It can also get a lock on the directory from ap_Current->an_Lock field. If your application needs the full path name of matching directory entries, it must allocate a buffer at the end of the AnchorPath structure and put the size of the buffer, in bytes, into ap_Strlen. The ap_BreakBits field allows the user to abort a directory scan in progress. The bits in this field correspond to the SIGBREAKF_ bits defined in <dos/dos.h>. If the corresponding bit is set in ap_BreakBits, MatchFirst() or MatchNext() will stop a scan in progress if one of those signals occurs. If this occurs, the bit of the signal that caused the break will be set in ap_FoundBreak. With this information alone it is possible to perform simple file pattern matching. As previously mentioned, the first match must be found with MatchFirst(). If MatchFirst() (or MatchNext()) cannot find a match or it encounters an error, it returns an error number, otherwise it returns a zero (which is unusual for a dos.library function). If MatchFirst() does not encounter any problems, the application should look for subsequent matches by calling MatchNext(). The application should call MatchNext() until it returns an AmigaDOS error value. MatchNext() accepts a pointer to the AnchorPath structure initialized by MatchFirst(). Normally, the error that MatchNext() returns is ERROR_NO_MORE_ENTRIES, indicating that there are no more directory entries that match mypattern. MatchEnd() is used to release any resources that were allocated in the scanning process. Due to a number of bugs in the V36 implementation, these functions should only be used as of V37. ListPattern.c is a simple example of using MatchFirst()/MatchNext(). For more complex matching, the ap_Flags field can be used to define the behavior of MatchFirst() and MatchNext(). Currently, there are several flags defined: APF_ITSWILD APF_DODIR APF_DIDDIR APF_NOMEMERR APF_DirChanged APF_FollowHLinks The APF_ITSWILD flag will be set if a wildcard was present in the pattern after the call to MatchFirst(). It will be used to instruct MatchNext() but your application can check it too and perform an action depending on its status. The APF_DODIR flag instructs MatchFirst/Next() to enter a directory if it encounters one. This flag can be set and reset on an individual basis. Once MatchNext() is finished processing a directory, it will set the APF_DIDDIR bit and will change the AnchorPath's directory back to the parent directory. APF_NOMEMERR indicates that MatchFirst/Next() encountered a fatal out of memory error. Processing the directory should be aborted and an error returned to the user. The APF_DirChanged flag indicates that MatchNext() noticed that directory lock has changed since the previous MatchNext() call. The APF_FollowHLinks flag tells MatchFirst/MatchNext() to follow hard link directories if the APF_DODIR bit is set. This feature is in place to avoid confusing applications that do not know anything about hard links. Most existing versions of the 2.0 include file <dos/dosasl.h> mention two other flags, APF_DOWILD and APF_DODOT. These are not currently in use by the system. The DirComp.c example is a more complex example of using MatchFirst()/Next(). It takes a path, which may include wildcards, and compares the directory entries it finds with those in the target directory. If the user specifies the DATE keyword, DirComp will also compare the datestamps. The ALL keyword tells DirComp to do a recursive scan. For deeply nested directories the BUFFER keyword can enlarge the buffer that DirComp uses from its standard 256 bytes up to 4096 bytes (calling it the ``Joanne'' keyword might be more appropriate).