Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Structured Directories Up: File Names Previous: Pathnames

23.1.2. Case Conventions

change_begin
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:

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



next up previous contents index
Next: Structured Directories Up: File Names Previous: Pathnames


AI.Repository@cs.cmu.edu