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

Reply via email to