Next: Files Up: Filesystem Utilities Previous: Filesystem Utilities

## Pathnames

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:

- `(build-path base-path sub-path )` creates an pathname given a base pathname and any number of sub-pathname extensions. If base-path is an absolute pathname, the result is an absolute pathname; if base is a relative pathname, the result is a relative pathname. Each sub-path must be either a relative pathname, a directory name, the symbol `'up` (indicating the relative parent directory), or the symbol `'same` (indicating the relative current directory). Under Windows, if base-path is a drive specification (with or without a trailing slash) the first sub-path can be an absolute (driveless) path. The last sub-path can be a filename.

  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"

- `(absolute-path? path)` returns `#t` if path is an absolute pathname, `#f` otherwise. If path is not a legal pathname string (e.g., it contains a null character), `#f` is returned. This procedure does not access the filesystem.
- `(relative-path? path)` returns `#t` if path is a relative pathname, `#f` otherwise. If path is not a legal pathname string (e.g., it contains a null character), `#f` is returned. This procedure does not access the filesystem.
- `(complete-path? path)` returns `#t` if path is a completely determined pathname (not relative to a directory or drive), `#f` otherwise. Note that under Windows, an absolute path can omit the drive specification, in which case the path is neither relative nor complete. If path is not a legal pathname string (e.g., it contains a null character), `#f` is returned. This procedure does not access the filesystem.
- `(path->complete-path path [base-path])` returns path as a complete path. If path is already a complete path, it is returned as the result. Otherwise, path is resolved with respect to the complete path base-path. If base-path is omitted, path is resolved with respect to the current directory. If base-path is provided and it is not a complete path, the `exn:i/o:filesystem` exception is raised. This procedure does not access the filesystem.
- `(resolve-path path)` expands path and returns a pathname that references the same file or directory as path. Under Unix or BeOS, if path is a soft link to another pathname, then the referenced pathname is returned (this may be a relative pathname with respect to the directory owningpath) otherwise path is returned (after expansion).
- `(expand-path path)` returns the expanded version of path (as described at the beginning of this section). The filesystem might be accessed, but the source or expanded pathname might be a non-existent path.
- `(simplify-path path)` eliminates up-directory (``..'' in Unix, BeOS, and Windows) and same-directory (``.'') indicators in path. If no indicators are in path, then path is returned. Otherwise, a complete path is returned; if path is relative, it is resolved with respect to the current directory. Up-directory indicators are dropped when they refer to the parent of a root directory. The filesystem might be accessed, but the source or expanded pathname might be a non-existent path. If path cannot be simplified due to a cycle of links, the `exn:i/o:filesystem` exception is raised (but a successfully simplified path may still involve a cycle of links if the cycle did not inhibit the simplification).
- `(normal-case-path string)` returns string with normalized case letters. Under Unix and BeOS, this procedure always returns the input path. Under Windows and MacOS, the resulting string uses only lowercase letters. Under Windows, all forward slashes (``/'') are converted to backward slashes (``\''), and trailing spaces are removed. This procedure does not access the filesystem or guarantee that the output string is a legal pathname (i.e., string and the result may contain a null character).
- `(split-path path)` deconstructs path into a smaller pathname and an immediate directory or file name. Three values are returned (see Chapter 2):
  - base is either
    - a string pathname,
    - `'relative` if path is an immediate relative directory or filename, or
    - `#f` if path is a root directory.
  - name is either
    - a string directory name,
    - a string file name,
    - `'up` if the last part of path specifies the parent directory of the preceding path (e.g., ``..'' under Unix), or
    - `'same` if the last part of path specifies the same directory as the preceding path (e.g., ``.'' under Unix).
  - must-be-dir? is `#t` if path explicitly specifies a directory (e.g., with a trailing separator), `#f` otherwise. Note that must-be-dir? does not specify whether name is actually a directory or not, but whether path syntactically specified a directory.
  If base is `#f`, then name cannot be `'up` or `'same`. All strings returned for base and name are newly allocated. This procedure does not access the filesystem.
- `(find-executable-path program-sub-path related-sub-path)` finds a pathname for the executable program-sub-path, returning `#f` if the pathname cannot be found.

  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.)

- `(find-system-path kind-symbol)` returns a machine-specific path for a standard type of path specified by kind-symbol, which must be one of the following:
  - `'home-dir` -- the current user's home directory. (See below for information on the user's home directory in Windows and MacOS.)
  - `'pref-dir` -- the standard directory for storing the current user's preferences. Under Unix, Windows, and BeOS, this is the user's home directory. (See below for information on the user's home directory in Windows.)
  - `'temp-dir` -- the standard directory for storing temporary files. Under Unix, Windows, and BeOS, this is the directory specified by the `TMPDIR` environment variable, if it is defined.
  - `'init-dir` -- the directory containing the initialization file used by stand-alone MzScheme application. It is the same as the current user's home directory. (See below for information on the user's home directory in Windows and MacOS.)
  - `'init-file` -- the file loaded at start-up by the stand-alone MzScheme application. The directory part of the path is the same path as returned for `'init-dir`. The file name is platform-specific:
    - Unix and BeOS: `.mzschemerc`
    - Windows and MacOS: `mzschemerc.ss`

  - `'sys-dir` -- the directory containing the operating system for Windows or MacOS. Under Unix and BeOS, the result is `"/etc"`.
  - `'exec-file` -- the pathname of the MzScheme executable as provided by the operating system for the current invocation. Under MacOS, in the stand-alone MzScheme (or MrEd) application, it is always a complete path. In the stand-alone MzScheme application, this path is also bound initially to `program`.

  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.

- `(path-list-string->path-list string default-path-list)` parses a string containing a list of paths, and returns a list of path strings. Under Unix and BeOS, paths in a path list are separated by a colon (``:''); under Windows and MacOS, paths are separated by a semi-colon (``;''). Whenever the path list contains an empty path, the list default-path-list is spliced into the returned list of paths. Parts of string that do not form a valid path are not included in the returned list. (The content of the list default-path-list is not inspected.)

Next: Files Up: Filesystem Utilities Previous: Filesystem Utilities