Common Lisp the Language, 2nd Edition
Next: Structured Directories
Up: File Names
Previous: Pathnames
Issues of alphabetic case in pathnames are a major source of problems.
In some file systems, the customary case is lowercase, in some
uppercase, in some mixed. Some file systems are case-sensitive (that is,
they treat FOO
and foo
as different file
names) and others are not.
There are two kinds of pathname case portability problems: moving programs from one Common Lisp to another, and moving pathname component values from one file system to another. The solution to the first problem is the requirement that all Common Lisp implementations that support a particular file system must use compatible representations for pathname component values. The solution to the second problem is the use of a common representation for the least-common-denominator pathname component values that exist on all interesting file systems.
Requiring a common representation directly conflicts with the desire among programmers that use only one file system to work with the local conventions and to ignore issues of porting to other file systems. The common representation cannot be the same as local (varying) conventions.
X3J13 voted in June 1989 (PATHNAME-COMPONENT-CASE) to add a keyword
argument :case
to each of the functions
make-pathname
, pathname-host
,
pathname-device
, pathname-directory
,
pathname-name
, and pathname-type
. The possible
values for the argument are :common
and
:local
. The default is :local
.
The value :local
means that strings given to
make-pathname
or returned by any of the pathname component
accessors follow the local file system’s conventions for alphabetic
case. Strings given to make-pathname
will be used exactly
as written if the file system supports both cases. If the file system
supports only one case, the strings will be translated to that case.
The value :common
means that strings given to
make-pathname
or returned by any of the pathname component
accessors follow this common convention:
Uppercase is used as the common case for no better reason than consistency with Lisp symbols. The second and third points allow translation from local representation to common and back to be information-preserving. (Note that translation from common to local representation and back may or may not be information-preserving, depending on the nature of the local representation.)
Namestrings always use :local
file system case
conventions.
Finally, merge-pathnames
and
translate-pathname
map customary case in the input
pathnames into customary case in the output pathname.
Examples of possible use of this convention:
^V
; for a
TOPS-20-based file system, a Common Lisp implementation should use
identical representations for common and local.equal
.Here are some examples of this behavior. Assume that the host
T
runs TOPS-20, U
runs UNIX, V
runs VAX/VMS, and M
runs the Macintosh operating
system.
;;; Returns two values: the PATHNAME-NAME from a namestring
;;; in :COMMON and :LOCAL representations (in that order).
(defun pathname-example (name)
(let ((path (parse-namestring name))))
(values (pathname-name path :case :common)
(pathname-name path :case :local))))
=> "FOO" and ¯"FOO" ;Common Local
(pathname-example "T:<ME>FOO.LISP") => "FOO" and "FOO"
(pathname-example "T:<ME>foo.LISP") => "FOO" and "FOO"
(pathname-example "T:<ME>^Vf^Vo^Vo.LISP") => "foo" and "foo"
(pathname-example "T:<ME>TeX.LISP") => "TEX" and "TEX"
(pathname-example "T:<ME>T^VeX.LISP") => "TeX" and "TeX"
(pathname-example "U:/me/FOO.lisp") => "foo" and "FOO"
(pathname-example "U:/me/foo.lisp") => "FOO" and "foo"
(pathname-example "U:/me/TeX.lisp") => "TeX" and "TeX"
(pathname-example "V:[me]FOO.LISP") => "FOO" and "FOO"
(pathname-example "V:[me]foo.LISP") => "FOO" and "FOO"
(pathname-example "V:[me]TeX.LISP") => "TEX" and "TEX"
(pathname-example "M:FOO.LISP") => "foo" and "FOO"
(pathname-example "M:foo.LISP") => "FOO" and "foo"
(pathname-example "M:TeX.LISP") => "TeX" and "TeX"
The following example illustrates the creation of new pathnames. The name is converted from common representation to local because namestrings always use local conventions.
(defun make-pathname-example (h n)
(namestring (make-pathname :host h :name n :case :common))
(make-pathname-example "T" "FOO") => "T:FOO"
(make-pathname-example "T" "foo") => "T:^Vf^Vo^Vo"
(make-pathname-example "T" "TeX") => "T:T^VeX"
(make-pathname-example "U" "FOO") => "U:foo"
(make-pathname-example "U" "foo") => "U:FOO"
(make-pathname-example "U" "TeX") => "U:TeX"
(make-pathname-example "V" "FOO") => "V:FOO"
(make-pathname-example "V" "foo") => "V:FOO"
(make-pathname-example "V" "TeX") => "V:TeX"
(make-pathname-example "M" "FOO") => "M:foo"
(make-pathname-example "M" "foo") => "M:FOO"
(make-pathname-example "M" "TeX") => "M:TeX"
A big advantage of this set of conventions is that one can, for
example, call make-pathname
with :type "LISP"
and :case :common
, and the result will appear in a
namestring as .LISP
or .lisp
, whichever is
appropriate.
Next: Structured Directories
Up: File Names
Previous: Pathnames
AI.Repository@cs.cmu.edu