Copyright (C) 1994, Digital Equipment Corp.
M3DirFindFile provides a file finder for a search path
specified as a list of directories (an M3PathElemList.T).
INTERFACEM3DirFindFile ; IMPORT OSError, Rd; IMPORT M3Extension, M3FindFile, M3PathElem, M3PathElemList; FROM M3FindFile IMPORT Failed; TYPE Finder <: FinderPublic; FinderPublic = M3FindFile.T OBJECT METHODS init(exts: M3Extension.TSet; dirs: M3PathElemList.T; oldFinder: Finder := NIL; errorHandler: ErrorHandler := NIL ): Finder RAISES {OSError.E}; dirOf(name: TEXT; ext: M3Extension.T ): M3PathElem.T RAISES {Failed}; dirs(): M3PathElemList.T; iterate(): Iter; setProperty(name: TEXT; ext: M3Extension.T; value: REFANY) RAISES {Failed}; getProperty(name: TEXT; ext: M3Extension.T ): REFANY RAISES {Failed}; merge(f1, f2: Finder): Finder; END; ErrorHandler = OBJECT METHODS callback(dir: M3PathElem.T; ec: OSError.Code): BOOLEAN; END; TFinder <: TFinderPublic; TFinderPublic = Finder OBJECT METHODS init( exts: M3Extension.TSet; rd: Rd.T; oldFinder: Finder := NIL): Finder RAISES {OSError.E}; END; TYPE Iter <: IterPublic; IterPublic = OBJECT METHODS next(VAR (*out*) unitName: TEXT; VAR (*out*) ext: M3Extension.T; VAR (*out*) dir: M3PathElem.T): BOOLEAN; close(); END; END M3DirFindFile.
NEW(Finder).init(...) returns a finder object for the given list
of directories. The find method of the returned finder object will
look for the file corresponding to the name and extension in each of
the directories in the list. The search is ordered so if there are two
file names in different directories which match a given name and
extension the file name earliest on the directory list will be
returned. If oldFinder # NIL, it is used to propagate information
from directories marked as {\it read-only} to the new finder. If an
error occurs reading any of the directories, then if errorHandler = NIL
OSError.E will be raised. If errorHandler # NIL,
errorHandler.callback(dir, ec) will be called, where dir represents
the directory element that could not be opened and ec represents
the code that would have been passed with the OSError.E exception.
Processing continues if a result of TRUE is returned from the
callback, or aborts otherwise with a result of NIL from Init.
The exts method returns the value of exts passed to init. The
dirOf method returns the directory, as an Elem, of the pathname
returned by the find method. The dirs method returns the list of
directories that were returned by the internal call of Read when the
finder was created.
The iterate method returns an iterator on the files associated with
the finder. The next method will return FALSE if the iteration is
exhausted, else it returns TRUE and sets the VAR parameters to the
unit name, extension and directory of the next file, respectively.
The setProperty method associates value with file defined by the
pair name,ext, raising M3FindFile.Failed if no such file exists.
Any existing value is overwritten. The getProperty returns the value
associated with name,ext, or NIL if no such value has been
associated.
NEW(T).merge(f1, f2) merges f1, with f2, and returns the finder.
Viewing a finder as defining a set of pairs, name, ext, the new
finder is defined by the union of f1 and f2. Where the finders
overlap, the information from f1 is taken. It is legal for f2 to
be NIL, in which case the result is a copy of self.
The effect of altering the directories given in the path list while
the find object is in use is undefined (e.g. the implementation of
Find may build a cache which may become out of date). Create a new
finder if the directory list or the contents of the directory may have
changed.
A TFinder is very like a Finder, except that the list of directory
names and the set of filenames in those directories is explicitly
encoded on the reader rd passed to NEW(TFinder).init, according to
the following syntax:
TSpec = { Dir {File} } .
Dir = @Pathname .
File = Filename .