Pathnames
*********

Lisp Pathnames
==============

There are many aspects of ANSI Common Lisp's pathname support which are implementation-defined and so need documentation.

Home Directory Specifiers
-------------------------

SBCL accepts the keyword :home and a list of the form (:home "username") as a directory component immediately following :absolute.

:home is represented in namestrings by ~/ and (:home "username" by ~username/ at the start of the namestring. Tilde-characters elsewhere in namestrings represent themselves.

Home directory specifiers are resolved to home directory of the current or specified user by native-namestring, which is used by the implementation to translate pathnames before passing them on to operating system specific routines.

Using (:home "user") form on Windows signals an error.

The SYS Logical Pathname Host
-----------------------------

The logical pathname host named by "SYS" exists in SBCL.  Its logical-pathname-translations may be set by the site or the user applicable to point to the locations of the system's sources; in particular, the core system's source files match the logical pathname "SYS:SRC;**;*.*.*", and the contributed modules' source files match "SYS:CONTRIB;**;*.*.*".

Native Filenames
================

In some circumstances, what is wanted is a Lisp pathname object which corresponds to a string produced by the Operating System.  In this case, some of the default parsing rules are inappropriate: most filesystems do not have a native understanding of wild pathnames; such functionality is often provided by shells above the OS, often in mutually-incompatible ways.

To allow the user to deal with this, the following functions are provided: parse-native-namestring and native-pathname return the closest equivalent Lisp pathname to a given string (appropriate for the Operating System), while native-namestring converts a non-wild pathname designator to the equivalent native namestring, if possible.  Some Lisp pathname concepts (such as the :back directory component) have no direct equivalents in most Operating Systems; the behaviour of native-namestring is unspecified if an inappropriate pathname designator is passed to it. Additionally, note that conversion from pathname to native filename and back to pathname should not be expected to preserve equivalence under equal.

     [file fun-sb-ext-parse-native-namestring.texinfo not included]
     [file fun-sb-ext-native-pathname.texinfo not included]
     [file fun-sb-ext-native-namestring.texinfo not included]

Because some file systems permit the names of directories to be expressed in multiple ways, it is occasionally necessary to parse a native file name ``as a directory name'' or to produce a native file name that names a directory ``as a file''.  For these cases, parse-native-namestring accepts the keyword argument as-directory to force a filename to parse as a directory, and native-namestring accepts the keyword argument as-file to force a pathname to unparse as a file.  For example,

     ; On Unix, the directory "/tmp/" can be denoted by "/tmp/" or "/tmp".
     ; Under the default rules for native filenames, these parse and
     ; unparse differently.
     (defvar *p*)
     (setf *p* (parse-native-namestring "/tmp/")) => #P"/tmp/"
     (pathname-name *p*) => NIL
     (pathname-directory *p*) => (:ABSOLUTE "tmp")
     (native-namestring *p*) => "/tmp/"

     (setf *p* (parse-native-namestring "/tmp")) => #P"/tmp"
     (pathname-name *p*) => "tmp"
     (pathname-directory *p*) => (:ABSOLUTE)
     (native-namestring *p*) => "/tmp"

     ; A non-NIL AS-DIRECTORY argument to PARSE-NATIVE-NAMESTRING forces
     ; both the second string to parse the way the first does.
     (setf *p* (parse-native-namestring "/tmp"
                                        nil *default-pathname-defaults*
                                        :as-directory t)) => #P"/tmp/"
     (pathname-name *p*) => NIL
     (pathname-directory *p*) => (:ABSOLUTE "tmp")

     ; A non-NIL AS-FILE argument to NATIVE-NAMESTRING forces the pathname
     ; parsed from the first string to unparse as the second string.
     (setf *p* (parse-native-namestring "/tmp/")) => #P"/tmp/"
     (native-namestring *p* :as-file t) => "/tmp"