When creating a logical pathname with make-pathname, :case :common, the pathname components are downcased.
I would argue that the customary case for logical pathnames is upper case, since:
19.3.1.1.7 Lowercase Letters in a Logical Pathname Namestring
When parsing words and wildcard-words, lowercase letters are translated to uppercase.
I'd expect (string= (pathname-name (make-pathname :host "TEST" :name "FILE" :type "DATA" :case :common))
(pathname-name #P"TEST:FILE.DATA"))
and of course (string= "FILE" (pathname-name #P"TEST:FILE.DATA"))
and similarly for the other pathname components.
[pjb@kuiper :0.0 ~]$ clisp -norc -ansi
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ `+' / I 8 8 8 8 8 8
\ `-+-' / 8 8 8 ooooo 8oooo
`-__|__-' 8 8 8 8 8
| 8 o 8 8 o 8 8
------+------ ooooo 8oooooo ooo8ooo ooooo 8
Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010
Type :h and hit Enter for context help.
[1]> (setf (logical-pathname-translations "TEST") nil)
NIL
[2]> (setf (logical-pathname-translations "TEST") (quote ((#P"TEST:**;*.*" "/tmp/**/*.*")
(#P"TEST:**;*" "/tmp/**/*"))))
((#P"TEST:**;*.*" "/tmp/**/*.*") (#P"TEST:**;*" "/tmp/**/*"))
[3]> (pathname-name (make-pathname :host "TEST" :name "FILE" :type "DATA" :case :common))
"file"
[4]> (pathname-name #P"TEST:FILE.DATA")
"FILE"
[5]>
The behaviour of :case :common is specified in CLHS section 19.2.2.1.2.2
http://www.lispworks.com/documentation/HyperSpec/Body/19_bbabb.htm
For clisp, the "filesystem's customary case" is lowercase, both on Unix and on Windows.
The section you cite, 19.3.1.1.7, doesn't apply for two reasons:
1) It applies only to logical pathnames. But
(make-pathname :host "TEST" :name "FILE" :type "DATA" :case :common)
yields an ordinary pathname in clisp. If you want a logical pathname, use the LOGICAL-PATHNAME function.
2) It applies to the parsing of namestrings for logical pathnames
that contain lowercase letters.
In your example (make-pathname :host "TEST" :name "FILE" :type "DATA" :case :common)
all of these are upper case, therefore the contents of 19.3.1.1.7 doesn't apply.
- I agree, I was wrong, 19.3.1.1.7 doesn't apply.
- make-pathname creates a logical pathname when the :host parameter is
a logical host, in clisp, as in any conforming implementation.
- I was also wrong with:
(pathname-name (make-pathname :host "TEST" :name "FILE" :type "DATA" :case :common))
it should indeed return "file"; this is correctly implemented in clisp.
- but the other form, (pathname-name #P"TEST:FILE.DATA") should return
"file", not "FILE", because by default the :case parameter of
pathname-name is :local, and "19.2.2.1.2.2 Common Case in Pathname
Components" mentions that round trip should be information
preserving (including case for local pathnames).
Actually there are other problems. In an implementation where the
customary case is lower case, the pathname accessors cannot return the
same case with and without :case :common, but this is what clisp does:
CL-USER> (print-pathname (make-pathname :host "LOGICAL" :device :unspecific :directory '(:absolute "DIR" "SUBDIR") :name "NAME" :type "DATA" :version nil :case :common))
LOGICAL-PATHNAME #P"LOGICAL:dir;subdir;name.data"
-------------------- :case :local (default)
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "dir" "subdir")
Name : "name"
Type : "data"
Version : NIL
-------------------- :case :common
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "dir" "subdir")
Name : "name"
Type : "data"
Version : NIL
--------------------
#P"LOGICAL:dir;subdir;name.data"
CL-USER> (print-pathname #P"LOGICAL:dir;subdir;name.data")
LOGICAL-PATHNAME #P"LOGICAL:DIR;SUBDIR;NAME.DATA"
-------------------- :case :local (default)
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "DIR" "SUBDIR")
Name : "NAME"
Type : "DATA"
Version : NIL
-------------------- :case :common
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "DIR" "SUBDIR")
Name : "NAME"
Type : "DATA"
Version : NIL
--------------------
#P"LOGICAL:DIR;SUBDIR;NAME.DATA"
CL-USER> (print-pathname #P"LOGICAL:DIR;SUBDIR;NAME.DATA")
LOGICAL-PATHNAME #P"LOGICAL:DIR;SUBDIR;NAME.DATA"
-------------------- :case :local (default)
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "DIR" "SUBDIR")
Name : "NAME"
Type : "DATA"
Version : NIL
-------------------- :case :common
Host : "LOGICAL"
Device : :UNSPECIFIC
Directory : (:ABSOLUTE "DIR" "SUBDIR")
Name : "NAME"
Type : "DATA"
Version : NIL
--------------------
#P"LOGICAL:DIR;SUBDIR;NAME.DATA"
There is also the problem that the result of:
(make-pathname :host "LOGICAL" :device :unspecific :directory '(:absolute "DIR" "SUBDIR") :name "NAME" :type "DATA" :version nil :case :common)
is printed as #P"LOGICAL:dir;subdir;name.data".
It should be printed using the logical pathname syntax, that is, in
upper case, because:
1- it is a logical pathname,
2- its printed form should be readable as the 'same' logical pathname,
that is, a pathname with the same components,
3- #P gives the string to parse-namestring, without addionnal
argument, therefore :host is nil, and in this case, for the string
to be parsed as a logical pathname, it needs to have the logical
pathname syntax, which takes only upper case letters.
4- when reading back this lowercase form, we don't read the same
pathname as originally returned by the make-pathname form.
I forgot the definition of print-pathname:
(defun print-pathname (pathname)
(format t "~%~A ~S~%" (type-of pathname) pathname)
(format t "-------------------- :case :local (default)~%")
(format t "~&~{~{~@(~9A~) : ~S~&~}~}"
(mapcar (lambda (name field) (list name (funcall field pathname)))
'(host device directory name type version)
'(pathname-host pathname-device pathname-directory
pathname-name pathname-type pathname-version)))
(format t "-------------------- :case :common~%")
(format t "~&~{~{~@(~9A~) : ~S~&~}~}"
(mapcar (lambda (name field arguments) (list name (apply field pathname arguments)))
'(host device directory name type version)
'(pathname-host pathname-device pathname-directory
pathname-name pathname-type pathname-version)
'((:case :common) (:case :common) (:case :common)
(:case :common) (:case :common) ())))
(format t "-------------------- ~%")
pathname)