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