Common Lisp the Language, 2nd Edition
Next: Opening and Closing
Up: File Names
Previous: Discussion of
Logical
These functions are what programs use to parse and default file names that have been typed in or otherwise supplied by the user.
Any argument called pathname in this book may actually be a
pathname, a string or symbol, or a stream. Any argument called
defaults may likewise be a pathname, a string or symbol, or a
stream.
X3J13 voted in March 1988 (PATHNAME-SYMBOL) to change the language so
that a symbol is never allowed as a pathname argument. More
specifically, the following functions are changed to disallow a symbol
as a pathname argument:
pathname pathname-device namestring
truename pathname-directory file-namestring
parse-namestring pathname-name directory-namestring
merge-pathnames pathname-type host-namestring
pathname-host pathname-version enough-namestring
(The function require
was also changed by this vote but
was deleted from the language by a vote in January 1989
(REQUIRE-PATHNAME-DEFAULTS) .) Furthermore, the vote reaffirmed that
the following functions do not accept symbols as file,
filename, or pathname arguments:
open rename-file file-write-date
with-open-file delete-file file-author
load probe-file directory
compile-file
In older implementations of Lisp that did not have strings, for
example MacLisp, symbols were the only means for specifying pathnames.
This was convenient only because the file systems of the time allowed
only uppercase letters in file names. Typing (load 'foo)
caused the function load
to receive the symbol
FOO
(with uppercase letters because of the way symbols are
parsed) and therefore to load the file named FOO
. Now that
many file systems, most notably UNIX, support case-sensitive file names,
the use of symbols is less convenient and more error-prone.
X3J13 voted in March 1988 (PATHNAME-STREAM) to specify that a
stream may be used as a pathname
, file
, or
filename
argument only if it was created by use of
open
or with-open-file
, or if it is a synonym
stream whose symbol is bound to a stream that may be used as a
pathname.
If such a stream is used as a pathname, it is as if the
pathname
function were applied to the stream and the
resulting pathname used in place of the stream. This represents the name
used to open the file. This may be, but is not required to be, the
actual name of the file.
It is an error to attempt to obtain a pathname from a stream created by any of the following:
make-two-way-stream make-string-input-stream
make-echo-stream make-string-output-stream
make-broadcast-stream with-input-from-string
make-concatenated-stream with-output-to-string
In the examples, it is assumed that the host named CMUC
runs the TOPS-20 operating system, and therefore uses TOPS-20 file
system syntax; furthermore, an explicit host name is indicated by
following the host name with a double colon. Remember, however, that
namestring syntax is implementation-dependent, and this syntax is used
here purely for the sake of examples.
[Function]
pathname
pathname
The pathname
function converts its argument to be a
pathname. The argument may be a pathname, a string or symbol, or a
stream; the result is always a pathname.
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) .
X3J13 voted in January 1989 (CLOSED-STREAM-OPERATIONS) to specify
that pathname
is unaffected by whether its argument, if a
stream, is open or closed. X3J13 further commented that because some
implementations cannot provide the ``true name’’ of a file until the
file is closed, in such an implementation pathname
might,
in principle, return a different (perhaps more specific) file name after
the stream is closed. However, such behavior is prohibited;
pathname
must return the same pathname after a stream is
closed as it would have while the stream was open. See
truename
.
[Function]
truename
pathname
The truename
function endeavors to discover the ``true
name’’ of the file associated with the pathname within the file
system. If the pathname is an open stream already associated
with a file in the file system, that file is used. The ``true name’’ is
returned as a pathname. An error is signaled if an appropriate file
cannot be located within the file system for the given
pathname.
The truename
function may be used to account for any
file name translations performed by the file system, for example.
For example, suppose that DOC:
is a TOPS-20 logical
device name that is translated by the TOPS-20 file system to be
PS:<DOCUMENTATION>
.
(setq file (open "CMUC::DOC:DUMPER.HLP"))
(namestring (pathname file)) => "CMUC::DOC:DUMPER.HLP"
(namestring (truename file))
=> "CMUC::PS:<DOCUMENTATION>DUMPER.HLP.13"
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) .
X3J13 voted in January 1989 (CLOSED-STREAM-OPERATIONS) to specify
that truename
may be applied to a stream whether the stream
is open or closed. X3J13 further commented that because some
implementations cannot provide the ``true name’’ of a file until the
file is closed, in principle it would be possible in such an
implementation for truename
to return a different file name
after the stream is closed. Such behavior is permitted; in this respect
truename
differs from pathname
.
X3J13 voted in June 1989 (PATHNAME-WILD) to clarify that
truename
accepts only non-wild pathnames; an error is
signaled if wild-pathname-p
would be true of the
pathname argument.
X3J13 voted in June 1989 (PATHNAME-LOGICAL) to require
truename
to accept logical pathnames (see section 23.1.5). However,
truename
never returns a logical pathname.
[Function]
parse-namestring
thing
&optional
host
defaults
&key :start :end :junk-allowed
This turns thing into a pathname. The thing is usually
a string (that is, a namestring), but it may be a symbol (in which case
the print name is used) or a pathname or stream (in which case no
parsing is needed, but an error check may be made for matching
hosts).
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) . The thing argument may not be a
symbol.
X3J13 voted in June 1989 (PATHNAME-LOGICAL) to require
parse-namestring
to accept logical pathname namestrings
(see section 23.1.5).
This function does not, in general, do defaulting of
pathname components, even though it has an argument named
defaults; it only does parsing. The host and
defaults arguments are present because in some implementations
it may be that a namestring can only be parsed with reference to a
particular file name syntax of several available in the implementation.
If host is non-nil
, it must be a host name that
could appear in the host component of a pathname, or nil
;
if host is nil
then the host name is extracted
from the default pathname in defaults and used to determine the
syntax convention. The defaults argument defaults to the value
of *default-pathname-defaults*
.
For a string (or symbol) argument, parse-namestring
parses a file name within it in the range delimited by the
:start
and :end
arguments (which are integer
indices into string, defaulting to the beginning and end of the
string).
See chapter 14 for a discussion of
:start
and :end
arguments.
If :junk-allowed
is not nil
, then the first
value returned is the pathname parsed, or nil
if no
syntactically correct pathname was seen.
If :junk-allowed
is nil
(the default), then
the entire substring is scanned. The returned value is the pathname
parsed. An error is signaled if the substring does not consist entirely
of the representation of a pathname, possibly surrounded on either side
by whitespace characters if that is appropriate to the cultural
conventions of the implementation.
In either case, the second value is the index into the string of the
delimiter that terminated the parse, or the index beyond the substring
if the parse terminated at the end of the substring (as will always be
the case if :junk-allowed
is false).
If thing is not a string or symbol, then start (which defaults to zero in any case) is always returned as the second value.
Parsing an empty string always succeeds, producing a pathname with
all components (except the host) equal to nil
.
Note that if host is specified and not nil
, and
thing contains a manifest host name, an error is signaled if
the hosts do not match.
If thing contains an explicit host name and no explicit
device name, then it might be appropriate, depending on the
implementation environment, for parse-namestring
to supply
the standard default device for that host as the device component of the
resulting pathname.
[Function]
merge-pathnames
pathname
&optional
defaults
default-version
This is the function that most programs should call to process a file
name supplied by the user. It fills in unspecified components of
pathname from the defaults, and returns a new
pathname. The pathname and defaults arguments may each
be a pathname, stream, string, or symbol. The result is always a
pathname.
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) .
X3J13 voted in June 1989 (PATHNAME-LOGICAL) to require
merge-namestrings
to recognize a logical pathname
namestring as its first argument if its second argument is a logical
pathname (see section 23.1.5).
X3J13 voted in January 1989 (CLOSED-STREAM-OPERATIONS) to specify
that merge-pathname
is unaffected by whether the first
argument, if a stream, is open or closed. If the first argument is a
stream, merge-pathname
behaves as if the function
pathname
were applied to the stream and the resulting
pathname used instead.
X3J13 voted in June 1989 (PATHNAME-COMPONENT-CASE) to require
merge-pathnames
to map customary case in argument pathnames
to the customary case in returned pathnames (see section 23.1.2).
defaults defaults to the value of
*default-pathname-defaults*
.
default-version defaults to :newest
.
Here is an example of the use of merge-pathnames
:
(merge-pathnames "CMUC::FORMAT"
"CMUC::PS:<LISPIO>.FASL")
=> a pathname object that re-expressed as a namestring would be
"CMUC::PS:<LISPIO>FORMAT.FASL.0"
Defaulting of pathname components is done by filling in components taken from another pathname. This is especially useful for cases such as a program that has an input file and an output file, and asks the user for the name of both, letting the unsupplied components of one name default from the other. Unspecified components of the output pathname will come from the input pathname, except that the type should default not to the type of the input but to the appropriate default type for output from this program.
The pathname merging operation takes as input a given pathname, a
defaults pathname, and a default version, and returns a new pathname.
Basically, the missing components in the given pathname are filled in
from the defaults pathname, except that if no version is specified the
default version is used. The default version is usually
:newest
; if no version is specified the newest version in
existence should be used. The default version can be nil
,
to preserve the information that it was missing in the input
pathname.
If the given pathname explicitly specifies a host and does not supply a device, then if the host component of the defaults matches the host component of the given pathname, then the device is taken from the defaults; otherwise the device will be the default file device for that host. Next, if the given pathname does not specify a host, device, directory, name, or type, each such component is copied from the defaults. The merging rules for the version are more complicated and depend on whether the pathname specifies a name. If the pathname doesn’t specify a name, then the version, if not provided, will come from the defaults, just like the other components. However, if the pathname does specify a name, then the version is not affected by the defaults. The reason is that the version ``belongs to’’ some other file name and is unlikely to have anything to do with the new one. Finally, if this process leaves the version missing, the default version is used.
The net effect is that if the user supplies just a name, then the host, device, directory, and type will come from the defaults, but the version will come from the default version argument to the merging operation. If the user supplies nothing, or just a directory, the name, type, and version will come over from the defaults together. If the host’s file name syntax provides a way to input a version without a name or type, the user can let the name and type default but supply a version different from the one in the defaults.
X3J13 voted in June 1989 (PATHNAME-SYNTAX-ERROR-TIME) to agree to
disagree: merge-pathname
might or might not perform
plausibility checking on its arguments to ensure that the resulting
pathname can be converted a valid namestring. User beware: this could
cause portability problems.
For example, suppose that host LOSER
constrains file
types to be three characters or fewer but host CMUC
does
not. Then "LOSER::FORMAT"
is a valid namestring and
"CMUC::PS:<LISPIO>.FASL"
is a valid namestring,
but
(merge-pathnames "LOSER::FORMAT" "CMUC::PS:<LISPIO>.FASL")
might signal an error in some implementations because the
hypothetical result would be a pathname equivalent to the namestring
"LOSER::FORMAT.FASL"
which is illegal because the file type
FASL
has more than three characters. In other
implementations merge-pathname
might return a pathname but
that pathname might cause namestring
to signal an
error.
[Variable]
*default-pathname-defaults*
This is the default pathname-defaults pathname; if any pathname primitive that needs a set of defaults is not given one, it uses this one. As a general rule, however, each program should have its own pathname defaults rather than using this one.
[Function]
make-pathname &key :host :device :directory :name :type :version :defaults
Given some components, make-pathname
constructs and
returns a pathname. After the components specified explicitly by the
:host
, :device
, :directory
,
:name
, :type
, and :version
arguments are filled in, the merging rules used by
merge-pathnames
are used to fill in any missing components
from the defaults specified by the :defaults
argument. The
default value of the :defaults
argument is a pathname whose
host component is the same as the host component of the value of
*default-pathname-defaults*
, and whose other components are
all nil
.
Whenever a pathname is constructed, whether by
make-pathname
or some other function, the components may be
canonicalized if appropriate. For example, if a file system is
insensitive to case, then alphabetic characters may be forced to be all
uppercase or all lowercase by the implementation.
The following example assumes the use of UNIX syntax and
conventions.
(make-pathname :host "technodrome"
:directory '(:absolute "usr" "krang")
:name "shredder")
=> #P"technodrome:/usr/krang/shredder"
X3J13 voted in June 1989 (PATHNAME-COMPONENT-CASE) to add a new
keyword argument :case
to make-pathname
. The
new argument description is therefore as follows:
[Function]
make-pathname &key :host :device :directory :name :type :version :defaults :case
See section 23.1.2 for a
description of the :case
argument.
X3J13 voted in June 1989 (PATHNAME-SYNTAX-ERROR-TIME) to agree to
disagree: make-pathname
might or might not check on its
arguments to ensure that the resulting pathname can be converted to a
valid namestring. If make-pathname
does not check its
arguments and signal an error in problematical cases,
namestring
yet might or might not signal an error when
given the resulting pathname. User beware: this could cause portability
problems.
[Function]
pathnamep
object
This predicate is true if object is a pathname, and otherwise is false.
(pathnamep x) == (typep x 'pathname)
[Function]
pathname-host
pathname
pathname-device
pathname
pathname-directory
pathname
pathname-name
pathname
pathname-type
pathname
pathname-version
pathname
These return the components of the argument pathname, which
may be a pathname, string or symbol, or stream. The returned values can
be strings, special symbols, or some other object in the case of
structured components. The type will always be a string or a symbol. The
version will always be a number or a symbol.
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) .
X3J13 voted in January 1989 (CLOSED-STREAM-OPERATIONS) to specify
that these operations are unaffected by whether the first argument, if a
stream, is open or closed. If the first argument is a stream, each
operation behaves as if the function pathname
were applied
to the stream and the resulting pathname used instead.
X3J13 voted in June 1989 (PATHNAME-COMPONENT-CASE) to add a keyword
argument :case
to all of the pathname accessor functions
except pathname-version
. The new argument descriptions are
therefore as follows:
[Function]
pathname-host
pathname
&key :case
pathname-device pathname &key :case
pathname-directory pathname &key :case
pathname-name pathname &key :case
pathname-type pathname &key :case
pathname-version pathname
See section 23.1.2 for a
description of the :case
argument.
X3J13 voted in June 1989 (PATHNAME-SUBDIRECTORY-LIST) to specify
that pathname-directory
always returns nil
,
:unspecific
, or a list-never a string, never
:wild
(see section 23.1.3). If a list is
returned, it is not guaranteed to be freshly consed; the consequences of
modifying this list are undefined.
[Function]
namestring
pathname
file-namestring
pathname
directory-namestring
pathname
host-namestring
pathname
enough-namestring
pathname
&optional
defaults
The pathname argument may be a pathname, a string or symbol, or a stream that is or was open to a file. The name represented by pathname is returned as a namelist in canonical form.
If pathname is a stream, the name returned represents the
name used to open the file, which may not be the
actual name of the file (see truename
).
X3J13 voted in March 1988 not to permit symbols as pathnames
(PATHNAME-SYMBOL) and to specify exactly which streams may be used as
pathnames (PATHNAME-STREAM) .
X3J13 voted in January 1989 (CLOSED-STREAM-OPERATIONS) to specify
that these operations are unaffected by whether the first argument, if a
stream, is open or closed. If the first argument is a stream, each
operation behaves as if the function pathname
were applied
to the stream and the resulting pathname used instead.
namestring
returns the full form of the
pathname as a string. file-namestring
returns a
string representing just the name, type, and
version components of the pathname; the result of
directory-namestring
represents just the
directory-name portion; and host-namestring
returns a string for just the host-name portion. Note that a
valid namestring cannot necessarily be constructed simply by
concatenating some of the three shorter strings in some order.
enough-namestring
takes another argument,
defaults. It returns an abbreviated namestring that is just
sufficient to identify the file named by pathname when
considered relative to the defaults (which defaults to the
value of *default-pathname-defaults*
). That is, it is
required that
(merge-pathnames (enough-namestring pathname defaults) defaults) ==
(merge-pathnames (parse-namestring pathname nil defaults) defaults)
in all cases; and the result of enough-namestring
is,
roughly speaking, the shortest reasonable string that will still satisfy
this criterion.
X3J13 voted in June 1989 (PATHNAME-SYNTAX-ERROR-TIME) to agree to
disagree: make-pathname
and merge-pathnames
might or might not be able to produce pathnames that cannot be converted
to valid namestrings. User beware: this could cause portability
problems.
[Function]
user-homedir-pathname &optional
host
Returns a pathname for the user’s ``home directory’’ on
host. The host argument defaults in some appropriate
implementation-dependent manner. The concept of ``home directory’’ is
itself somewhat implementation-dependent, but from the point of view of
Common Lisp it is the directory where the user keeps personal files such
as initialization files and mail. If it is impossible to determine this
information, then nil
is returned instead of a pathname;
however, user-homedir-pathname
never returns
nil
if the host argument is not specified. This
function returns a pathname without any name, type, or version component
(those components are all nil
).
Next: Opening and Closing
Up: File Names
Previous: Discussion of
Logical
AI.Repository@cs.cmu.edu