Identifier search

pathfinder provides an interface to finding files in a search path. During a path-find of a search term, each directory in the search path is traversed in order. A matcher is called once for each directory, returning the best match. Optionally, the match must also pass a pathfinder test -- for example, be a regular file -- and if it fails, the matcher can continue looking for matches. The first match that also passes the test is returned.

You can additionally find all shadowed matches with path-find-all. In this case, all successful matches in every directory in the search path are returned.

The entire directory contents (names only) are cached when a directory is read for the first time. File stat data is cached as needed; for example, testing that a filename is a regular file is done once, and only after it has been matched. It is possible to clear the caches to pick up any changes to the filesystem.

Find the best (first) match for PATHNAME using pathfinder PF, and returns the absolute pathname if a match occurs or #f if not.

PATHNAME may be a filename such as "bar", which is looked for in each search path, or a relative path such as "foo/bar", in which "bar" is looked for in subdirectory "foo" under each search path. It can also be an absolute path; in this case, it is considered relative to the pathfinder root, confining the search to a single directory in the search path. If the resulting directory is not in or under the search path, #f is returned.

MATCHER is an optional pathfinder matcher which indicates the matching method; if #f or not present, the matcher assocated with the pathfinder object is used.

TEST is an optional pathfinder test which performs an additional test before admitting the file. If #f or not present, the test associated with the pathfinder object is used.

Like path-find-all, this finds all shadowed matches for PATHNAME, performing a fold over the results. INIT is the initial seed and FUNC is called with arguments (X XS) where X is the current absolute pathname and XS is the accumulated seed.

Note: filtering the results on file type, size etc. is usually better done with pathfinder tests.

Construct a pathfinder object with search path PATHS. PATHS is a list of absolute or relative pathnames; if relative, they are relative to the pathfinder ROOT.

Keyword ROOT specifies the root of this pathfinder and defaults to the current directory. ROOT specifies both the base for relative PATHS, and the base for absolute search terms (see path-find). ROOT itself can be absolute or relative; if relative, it is relative to the current directory at the time the object is created.

Keyword MATCHER specifies a pathfinder matcher for this object, and defaults to (pathfinder-default-matcher), usually the exact filename matcher pf:exact. This becomes the default matcher for this pathfinder object, and can be overridden later in path-find.

Keyword TEST specifies a pathfinder test for this object, and defaults to (pathfinder-default-test), usually pf:regular-file?. This becomes the default test for this pathfinder object, and can be overridden later in path-find. To avoid filtering, use the test pf:any?.

A matcher object suitable for passing to path-find or path-find-all. For each directory, this matcher checks that the current search term exactly matches a filename that is present under the directory.

Create a matcher object suitable for passing to path-find or path-find-all. For each directory, this matcher tries each extension in the EXTS list in order, by appending it to the current search term. If the extension was already present in the search term, it is not appended again.

The extensions in the EXTS list should include the dot, meaning ".exe" not "exe". It is legal to include a dot in the extension itself. The empty string "" is allowed as well, meaning the search term itself will be tried without any extension.

An example in which we search only one path, the Chicken repository path, with several extensions.

Create a matcher object suitable for passing to path-find or path-find-all. For each directory, this matches any files that match the current search term and additionally have zero or more of the extensions in the EXTS list. Furthermore, these results are returned sorted by extension priority, where the priority is higher for extensions earlier in the list. This behavior is like that of the Hike library for Ruby.

The extensions in the EXTS list should include the dot at the beginning, meaning ".exe" not "exe". It is not legal to use the empty string, nor to have a dot within the extension.

It is possible to define custom pathfinder tests, useful if you want to test a file is executable or non-zero size or recent mtime and so on. Tests are two-argument procedures (DIRENT FILENAME) which return a boolean value indicating whether to accept the file that is currently being examined. The following helpers are useful.

Return the stat vector for FILENAME in DIRENT. If the stat fails (for example, if the file has gone missing since the dirent was populated) then #f is returned. Stat vectors are cached upon first access and subsequent stats are returned from cache.

Using PF's stat cache, stat absolute PATHNAME and return its stat vector (as in posix's file-stat). For example, this could be used on the filenames returned by path-find-all in order to filter them further.

Note that this returns #f for a file in any directory which has not yet been traversed during a search operation.

Symlinks will trick the pathfinder into caching duplicate copies, as entries are keyed to full path and directories are not traversed individually to canonicalize the path. Symlinks may also cause lookups to escape the root.

It is not possible to disable the directory or stat caches.

It is not possible to simulate, for example, bash's PATH lookup mechanism exactly because directory contents are cached when the search path is traversed for the first time.

Due to a bug in Chicken on Windows, search paths referring to the drive root (like C:\) have their drive letter deleted, so they refer to the current drive. This is fixed in git revision 658955c8 (Chicken 4.7.1 or 4.7.0.1-st).