Agreed. If we claim that a directory is a pathname 'without" a filename, then the three ways (so far) for a filename to be missing are for it to be `nil`, the empty string or :unspecific, Here's another crack at it and a sort-of test
(defun directory-pathname-p (pathname) "A directory-pathname is a pathname _without_ a filename. The three ways that the filename components can be missing are for it to be `nil`, `:unspecific` or the empty string." ;; a rather ugly implementation of the docstring (let ((null-components (list nil :unspecific ""))) (flet ((check-one (x) (not (null (member (pathname-name pathname) null-components :test 'equal))))) (and (check-one (pathname-name pathname)) (check-one (pathname-type pathname))))))
#+(or) ;;test (every (lambda (p) (directory-pathname-p p)) (list (make-pathname :name "." :type nil :directory '(:absolute "tmp")) (make-pathname :name "." :type "" :directory '(:absolute "tmp")) (make-pathname :name nil :type "" :directory '(:absolute "tmp")) (make-pathname :name "" :directory '(:absolute "tmp")) (make-pathname :type :unspecific :directory '(:absolute "tmp")) (make-pathname :name :unspecific :directory '(:absolute "tmp")) (make-pathname :name :unspecific :directory '(:absolute "tmp")) ))
On Jul 13, 2009, at 1:57 PM, Richard M Kreuter wrote:
Gary King writes:
OK, I /have/ misdiagnosed this. The logic seems actually busted in directory-pathname-p. The problem is that, at least on allegro, you can get a valid directory pathname whose name component is neither NIL, nor :unspecific, but "" (the empty string).
Ugh,
(member (pathname-name pathname) (list nil "" :unspecific) :test 'equal)
A source of the problem are pathnames that arise from things like this:
(make-pathname :name "" :directory '(:absolute "tmp"))
#p"/tmp/"
(pathname-name *)
""
Added a call to namestring seems to be another way to canonical things so I think this will also work and feels (to me) a bit more portable:
(defun directory-pathname-p (pathname) (let ((pathname (namestring pathname))) (and (member (pathname-name pathname) (list nil :unspecific)) (member (pathname-type pathname) (list nil :unspecific)))))
I see two problems:
(1) If the the host component of *DEFAULT-PATHNAME-DEFAULTS* is different than the host component of PATHNAME, the parse might fail or come out wrong.
(2) Pathnames with "" for the name component don't have namestrings under SBCL. (IIUC, the intent there is to try to have namestring parsing and unparsing be non-lossy.)
I think it might do just as well to say that "" for the name counts the same as NIL or :UNSPECIFIC for DIRECTORY-PATHNAME-P, unless somebody knows of implementations that don't work that way.
-- RmK
-- Gary Warren King, metabang.com Cell: (413) 559 8738 Fax: (206) 338-4052 gwkkwg on Skype * garethsan on AIM * gwking on twitter