Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Opening and Closing Up: File Names Previous: Discussion of Logical

23.1.6. Pathname Functions

These functions are what programs use to parse and default file names that have been typed in or otherwise supplied by the user.

old_change_begin
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.
old_change_end

change_begin
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

change_end

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.

change_begin
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.
change_end


[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"

change_begin
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.
change_end


[Function]
parse-namestring thing &optional host defaults &key :start :end :junk-allowed

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

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

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

change_begin
See chapter 14 for a discussion of :start and :end arguments.
change_end

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

old_change_begin
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.
old_change_end

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

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.

change_begin
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.
change_end


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

old_change_begin

[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.
old_change_end

change_begin
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.
change_end


[Function]
pathnamep object

This predicate is true if object is a pathname, and otherwise is false.

(pathnamep x) == (typep x 'pathname)

old_change_begin

[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.
old_change_end

change_begin
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.
change_end


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

change_begin
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.
change_end

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.

change_begin
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.
change_end


[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 up previous contents index
Next: Opening and Closing Up: File Names Previous: Discussion of Logical


AI.Repository@cs.cmu.edu