@node Pathnames
@comment  node-name,  next,  previous,  up
@chapter Pathnames

@cindex Pathnames

@menu
* Lisp Pathnames::
* Native Filenames::
@end menu

@node Lisp Pathnames
@comment  node-name,  next,  previous,  up
@section Lisp Pathnames

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

@c FIXME: as a matter of ANSI conformance, we are required to document
@c implementation-defined stuff, which for pathnames (chapter 19 of CLtS)
@c includes:
@c
@c * Otherwise, the parsing of thing is implementation-defined.
@c   (PARSE-NAMESTRING)
@c
@c * If thing contains an explicit host name and no explicit device name,
@c   then it is implementation-defined whether parse-namestring will supply
@c   the standard default device for that host as the device component of
@c   the resulting pathname.  (PARSE-NAMESTRING)
@c
@c * The specific nature of the search is implementation-defined.
@c   (LOAD-LOGICAL-PATHNAME-TRANSLATIONS)
@c
@c * Any additional elements are implementation-defined.
@c   (LOGICAL-PATHNAME-TRANSLATIONS)
@c
@c * The matching rules are implementation-defined but should be consistent
@c   with directory.  (PATHNAME-MATCH-P)
@c
@c * Any such additional translations are implementation-defined.
@c   (TRANSLATE-LOGICAL-PATHNAMES)
@c
@c * ...or an implementation-defined portion of a component...
@c   (TRANSLATE-PATHNAME)
@c
@c * The portion of source that is copied into the resulting pathname is
@c   implementation-defined.  (TRANSLATE-PATHNAME)
@c
@c * During the copying of a portion of source into the resulting
@c   pathname, additional implementation-defined translations of case or
@c   file naming conventions might occur.  (TRANSLATE-PATHNAME)
@c
@c * In general, the syntax of namestrings involves the use of
@c   implementation-defined conventions.  (19.1.1)
@c
@c * The nature of the mapping between structure imposed by pathnames and
@c   the structure, if any, that is used by the underlying file system is
@c   implementation-defined.  (19.1.2)
@c
@c * The mapping of the pathname components into the concepts peculiar to
@c   each file system is implementation-defined.  (19.1.2)
@c
@c * Whether separator characters are permitted as part of a string in a
@c   pathname component is implementation-defined;  (19.2.2.1.1)
@c
@c * Whether a value of :unspecific is permitted for any component on any
@c   given file system accessible to the implementation is
@c   implementation-defined.  (19.2.2.2.3)
@c
@c * Other symbols and integers have implementation-defined meaning.
@c   (19.2.2.4.6)

@subsection Home Directory Specifiers

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

@code{:home} is represented in namestrings by @code{~/} and
@code{(:home "username"} by @code{~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 @code{native-namestring}, which is used
by the implementation to translate pathnames before passing them on to
operating system specific routines.

Using @code{(:home "user")} form on Windows signals an error.

@subsection The SYS Logical Pathname Host

@cindex Logical pathnames
@cindex Pathnames, logical
@findex @cl{logical-pathname-translations}
@findex @setf{@cl{logical-pathname-translations}}

@c * The existence and meaning of SYS: logical pathnames is
@c   implementation-defined.  (19.3.1.1.1)

The logical pathname host named by @code{"SYS"} exists in SBCL.  Its
@code{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
@code{"SYS:SRC;**;*.*.*"}, and the contributed modules' source files
match @code{"SYS:CONTRIB;**;*.*.*"}.

@include fun-sb-ext-set-sbcl-source-location.texinfo

@node Native Filenames
@comment  node-name,  next,  previous,  up
@section 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: @code{parse-native-namestring} and @code{native-pathname}
return the closest equivalent Lisp pathname to a given string
(appropriate for the Operating System), while @code{native-namestring}
converts a non-wild pathname designator to the equivalent native
namestring, if possible.  Some Lisp pathname concepts (such as the
@code{:back} directory component) have no direct equivalents in most
Operating Systems; the behaviour of @code{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 @code{equal}.

@include fun-sb-ext-parse-native-namestring.texinfo
@include fun-sb-ext-native-pathname.texinfo
@include fun-sb-ext-native-namestring.texinfo

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,
@code{parse-native-namestring} accepts the keyword argument
@code{as-directory} to force a filename to parse as a directory, and
@code{native-namestring} accepts the keyword argument @code{as-file}
to force a pathname to unparse as a file.  For example,

@lisp
; 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/")) @result{} #P"/tmp/"
(pathname-name *p*) @result{} NIL
(pathname-directory *p*) @result{} (:ABSOLUTE "tmp")
(native-namestring *p*) @result{} "/tmp/"

(setf *p* (parse-native-namestring "/tmp")) @result{} #P"/tmp"
(pathname-name *p*) @result{} "tmp"
(pathname-directory *p*) @result{} (:ABSOLUTE)
(native-namestring *p*) @result{} "/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)) @result{} #P"/tmp/"
(pathname-name *p*) @result{} NIL
(pathname-directory *p*) @result{} (: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/")) @result{} #P"/tmp/"
(native-namestring *p* :as-file t) @result{} "/tmp"
@end lisp
