At least on 19d this doesn't work:
* (namestring "...")
This is due to the fact that PARSE-NAMESTRING returns something that
LISP::UNPARSE-UNIX-FILE doesn't like:
* (describe (parse-namestring "..."))
#P(:NAME "...") is a structure of type PATHNAME.
HOST: #<LISP::UNIX-HOST>.
DEVICE: NIL.
DIRECTORY: NIL.
NAME: "...".
TYPE: NIL.
VERSION: NIL.
To mend the error I'd propose something like this:
diff -c -r1.103 filesys.lisp
*** filesys.lisp 4 Aug 2007 23:54:37 -0000 1.103
--- filesys.lisp 5 Sep 2007 15:30:04 -0000
***************
*** 336,346 ****
;; nil.
(setf pieces (append pieces (list (cons tail-start
tail-end))))
(values nil nil nil))
((not (find-if-not #'(lambda (c)
(char= c #\.))
namestr :start tail-start :end tail-end))
! ;; Got a bunch of dots. Make it a file of the same name,
and type nil.
! (values (subseq namestr tail-start tail-end) nil nil))
(t
(extract-name-type-and-version namestr tail-start
tail-end)))))
;; PVE: Make sure there are no illegal characters in the name
--- 336,350 ----
;; nil.
(setf pieces (append pieces (list (cons tail-start
tail-end))))
(values nil nil nil))
+ ((string= namestr "." :start1 tail-start :end1 tail-end)
+ ;; "." is a directory as well.
+ (setf pieces (append pieces (list (cons tail-start
tail-end))))
+ (values nil nil nil))
((not (find-if-not #'(lambda (c)
(char= c #\.))
namestr :start tail-start :end tail-end))
! ;; Got a bunch of dots. Make it a file of the same name,
and type the empty string.
! (values (subseq namestr tail-start (1- tail-end)) "" nil))
(t
(extract-name-type-and-version namestr tail-start
tail-end)))))
;; PVE: Make sure there are no illegal characters in the name
***************
*** 507,513 ****
(find #\. name :start 1))
;; A single leading dot is ok.
(error "Cannot specify a dot in a pathname name without a pathname
type: ~S" name))
! (when (or (string= ".." name)
(string= "." name))
(error "Invalid value for a pathname name: ~S" name)))
(strings (unparse-unix-piece name)))
--- 511,518 ----
(find #\. name :start 1))
;; A single leading dot is ok.
(error "Cannot specify a dot in a pathname name without a pathname
type: ~S" name))
! (when (or (and (string= ".." name)
! (not type-supplied))
(string= "." name))
(error "Invalid value for a pathname name: ~S" name)))
(strings (unparse-unix-piece name)))
*** pathname.lisp 08 Nov 2005 18:12:29 +0100 1.84
--- pathname.lisp 05 Sep 2007 17:53:58 +0200
***************
*** 784,790 ****
(check-component-validity d :directory))
(cdr dir))
(when (and (stringp name)
! (or (string= name "..") (string= name ".")))
(warn "Silly argument for a unix PATHNAME-NAME: ~S" name)))
;; More sanity checking
--- 784,792 ----
(check-component-validity d :directory))
(cdr dir))
(when (and (stringp name)
! (or (and (string= name "..")
! (not type))
! (string= name ".")))
(warn "Silly argument for a unix PATHNAME-NAME: ~S" name)))
;; More sanity checking
The patch does two things:
- it parses "..." into a name=".." and type="" as it already did for
namestrings like "foo."
- it accepts (make-pathname :name ".." :type "") as consequence of #1
Side note.
SBCL doesn't seem to suffer from this problem, but it looks like that
code might be quite different as it doesn't even try to handle "."
and ".." specially, unless they are followed by a "/". Considering
that Unix allows things like "cat .", maybe SBCL's approach is the
one closer to the Unix philosophy.
--
walter pelissero
http://www.pelissero.de