r7795: add directory-tree and probe-directory functions
authorKevin M. Rosenberg <kevin@rosenberg.net>
Wed, 10 Sep 2003 05:44:47 +0000 (05:44 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Wed, 10 Sep 2003 05:44:47 +0000 (05:44 +0000)
io.lisp

diff --git a/io.lisp b/io.lisp
index 7fbf186753e9f2ba731357bf66bdf60e0cd448c1..68a6bc23cd9a8ab956d6f19ebc3db815d0870f61 100644 (file)
--- a/io.lisp
+++ b/io.lisp
   (when (probe-file #p"/dev/null")
     (open-device-stream #p"/dev/null" :output))  
   )
+
+(defun un-unspecific (value)
+  "Convert :UNSPECIFIC to NIL."
+  (if (eq value :unspecific) nil value))
+
+(defun canonicalize-directory-name (filename)
+  (flet ((un-unspecific (value)
+          (if (eq value :unspecific) nil value)))
+    (let* ((path (pathname filename))
+          (name (un-unspecific (pathname-name path)))
+          (type (un-unspecific (pathname-type path)))
+          (new-dir
+           (cond ((and name type) (list (concatenate 'string name "." type)))
+                 (name (list name))
+                 (type (list type))
+                 (t nil))))
+      (if new-dir
+         (make-pathname
+          :directory (append (un-unspecific (pathname-directory path))
+                             new-dir)
+                   :name nil :type nil :version nil :defaults path)
+         path))))
+  
+(defun probe-directory (filename)
+  (let ((path (canonicalize-directory-name filename)))
+    #+allegro (excl:probe-directory path)
+    #+clisp (values
+            (ignore-errors
+              (#+lisp=cl ext:probe-directory #-lisp=cl lisp:probe-directory
+                         path)))
+    #+(or cmu scl) (eq :directory (unix:unix-file-kind (namestring path)))
+    #+lispworks (lw:file-directory-p path)
+    #+sbcl (eq :directory (sb-unix:unix-file-kind (namestring path)))
+    #-(or allegro clisp cmu lispworks sbcl scl)
+    (probe-file path)))
+
+(defun directory-tree (filename)
+  "Returns a tree of pathnames for sub-directories of a directory"
+  (let* ((root (canonicalize-directory-name filename))
+        (subdirs (loop for path in (directory
+                                    (make-pathname :name :wild
+                                                   :type :wild
+                                                   :defaults root))
+                       when (probe-directory path)
+                       collect (canonicalize-directory-name path))))
+    (when (find nil subdirs)
+      (error "~A" subdirs))
+    (when (null root)
+      (error "~A" root))
+    (if subdirs
+       (cons root (mapcar #'directory-tree subdirs))
+       (if (probe-directory root)
+           (list root)
+           (error "root not directory ~A" root)))))
+
+