File and directory paths are specified as strings. Since the syntax for pathnames can vary across platforms (e.g., under Unix, directories are separated by ``/'' while the Mac uses ``:''), MzScheme provides tools for portably constructing and deconstructing pathnames.
Most MzScheme primitives that take pathnames perform an expansion on the pathname before using it. (Procedures that build pathnames or merely check the form of a pathname do not perform this expansion.) Under Unix and BeOS, a user directory specification using ``~'' is expanded. Under MacOS, file and folder aliases are resolved to real pathnames. Under Windows, multiple slashes are converted to single slashes (except at the beginning of a shared folder name), and a slash is inserted after the colon in a drive specification (if it is missing). In a Windows pathname, slash and backslash are always equivalent (and can be mixed together in the same pathname).
A pathname string cannot contain a null character (#\nul). When a string containing a null character is provided as a pathname to any procedure except absolute-path?, relative-path?, complete-path?, or normal-case-path, the exn:i/o:filesystem exception is raised.
The pathname utilities are:
Each sub-path and base-path can optionally end in a directory separator. If the last sub-path ends in a separator, it is included in the resulting pathname.
Under MacOS, if a sub-path argument does not begin with a colon, one is added automatically. This means that sub-path arguments are never interpreted as absolute paths under MacOS. For other platforms, if an absolute path is provided for any sub-path, then the exn:i/o:filesystem exception is raised. On all platforms, if base-path or sub-path is an illegal path string (e.g., it contains a null character), the exn:i/o:filesystem exception is raised.
The build-path procedure builds a pathname without checking the validity of the path or accessing the filesystem.
The following examples assume that the current directory is /home/joeuser for Unix examples and My Disk:Joe's Files for MacOS examples.
(define p1 (build-path (current-directory) "src" "scheme"))
; Unix: p1 => "/home/joeuser/src/scheme"
; MacOS: p1 => "My Disk:Joe's Files:src:scheme"
(define p2 (build-path 'up 'up "docs" "MzScheme"))
; Unix: p2 => "../../docs/MzScheme"
; MacOS: p2 => ":::docs:MzScheme"
(build-path p2 p1)
; Unix: raises exn:i/o:filesystem:path because p1 is absolute
; MacOS: => ":::docs:MzScheme:My Disk:Joe's Files:src:scheme"
(build-path p1 p2)
; Unix: => "/home/joeuser/src/scheme/../../docs/MzScheme"
; MacOS: => "My Disk:Joe's Files:src:scheme:::docs:MzScheme"
If related-sub-path is not #f, then it must be a relative path string, and the pathname found for program-sub-path must be such that the file or directory related-sub-path exists in the same directory as the executable. The result is then the full path for the found related-sub-path, instead of the path for the executable.
This procedure is used by MzScheme (as a stand-alone executable) to find the standard library collection directory (see Chapter 15). In this case, program is the name used to start MzScheme and related is "collects". The related-sub-path argument is used because, under Unix and BeOS, program-sub-path may involve to a sequence of soft links; in this case, related-sub-path determines which link in the chain is relevant.
If program-sub-path has a directory path, exists as a file or link to a file, and related-sub-path is not #f, find-executable-path determines whether related-sub-path exists relative to the directory of program-sub-path. If so, the complete path for program-sub-path is returned. Otherwise, if program-sub-path is a link to another file path, the destination directory of the link is checked for related-sub-path. Further links are inspected until related-sub-path is found or the end of the chain of links is reached.
If program-sub-path is a pathless name, find-executable-path gets the value of the PATH environment variable; if this environment variable is defined, find-executable-path tries each path in PATH as a prefix for program-sub-path using the search algorithm described above for path-containing program-sub-paths. If the PATH environment variable is not defined, program-sub-path is prefixed with the current directory and used in the search algorithm above. (Under Windows, the current directory is always implicitly the first item in PATH, so find-executable-path checks the current directory first under Windows.)
Under Windows, the user's home directory is the one specified by the HOMEDRIVE and HOMEPATH environment variables. If those environment variables are not defined, or if the indicated directory does not exist, the directory containing the MzScheme executable is used as the home directory. Under MacOS, the user's ``home directory'' is the preferences directory.