[osicat-cvs] CVS update: src/osicat.lisp

Nikodemus Siivola nsiivola at common-lisp.net
Sun Apr 25 12:11:32 UTC 2004


Update of /project/osicat/cvsroot/src
In directory common-lisp.net:/tmp/cvs-serv17487

Modified Files:
	osicat.lisp 
Log Message:
* Rewrote WITH-DIRECTORY-ITERATOR in CALL-WITH... style.
Date: Sun Apr 25 08:11:32 2004
Author: nsiivola

Index: src/osicat.lisp
diff -u src/osicat.lisp:1.22 src/osicat.lisp:1.23
--- src/osicat.lisp:1.22	Sun Apr 25 07:16:25 2004
+++ src/osicat.lisp	Sun Apr 25 08:11:31 2004
@@ -142,52 +142,58 @@
 entries, one by one. Both files and directories are returned, except
 '.' and '..'. The order of entries is not guaranteed. The entries are
 returned as relative pathnames against the designated
-directory. Entries that are symbolic links are not resolved. Once all
-entries have been returned, further invocations of (iterator) will all
-return NIL.
+directory. Entries that are symbolic links are not resolved, but links
+that point to directories are interpreted as directory
+designators. Once all entries have been returned, further invocations
+of (iterator) will all return NIL.
 
 The value returned is the value of the last form evaluated in
 body. Signals an error if pathspec is wild or does not designate a directory."
-  (with-unique-names (dp dir cdir old-dir one-iter)
-    `(let ((,dir (normpath ,pathspec t))
-	   (,old-dir (current-directory)))
-       (with-c-file (,cdir ,dir :directory t)
-	 (let (,dp)
-	   (unwind-protect
-		(labels ((,one-iter ()
-			   (let ((entry (readdir ,dp)))
-			     (if (null-pointer-p entry)
-				 nil
-				 (let* ((cname (osicat-dirent-name entry))
-					(name (convert-from-cstring cname)))
-				   (declare (type simple-string name))
-				   (cond 
-				     ((member name '("." "..") :test #'string=)
-				      (,one-iter))
-				     ((eq :directory (c-file-kind cname t))
-				      (make-pathname
-				       :directory `(:relative ,name)))
-				     (t
-				      (let ((dotpos (position #\. name :from-end t)))
-					(if (and dotpos (plusp dotpos))
-					    (make-pathname
-					     :name (subseq name 0 dotpos)
-					     :type (subseq name (1+ dotpos)))
-					    (make-pathname
-					     :name name))))))))))
-		  (macrolet ((,iterator () 
-			       `(,',one-iter)))
-		    (setf ,dp (opendir ,cdir))
-		    (when (null-pointer-p ,dp)
-		      (error "Error opening directory ~S." ,dir))
-		    (let ((*default-pathname-defaults* ,dir))
-		      (setf (current-directory) ,dir)
-		      , at body)))
-	     (when ,dp
-	       (if (zerop (closedir ,dp))
-		   nil
-		   (error "Error closing directory ~S." ,dir)))
-	     (setf (current-directory) ,old-dir)))))))
+  (with-unique-names (one-iter)
+    `(call-with-directory-iterator ,pathspec
+      (lambda (,one-iter)
+	(macrolet ((,iterator () 
+		     `(funcall ,',one-iter)))
+	  , at body)))))
+
+(defun call-with-directory-iterator (pathspec fun)
+  (let ((dir (normpath pathspec t))
+	(old-dir (current-directory)))
+    (with-c-file (cdir dir :directory t)
+      (let (dp)
+	(unwind-protect
+	     (labels ((one-iter ()
+			(let ((entry (readdir dp)))
+			  (if (null-pointer-p entry)
+			      nil
+			      (let* ((cname (osicat-dirent-name entry))
+				     (name (convert-from-cstring cname)))
+				(declare (type simple-string name))
+				(cond 
+				  ((member name '("." "..") :test #'string=)
+				      (one-iter))
+				  ((eq :directory (c-file-kind cname t))
+				   (make-pathname
+				    :directory `(:relative ,name)))
+				  (t
+				   (let ((dotpos (position #\. name :from-end t)))
+				     (if (and dotpos (plusp dotpos))
+					 (make-pathname
+					  :name (subseq name 0 dotpos)
+					  :type (subseq name (1+ dotpos)))
+					 (make-pathname
+					  :name name))))))))))
+	       (setf dp (opendir cdir))
+	       (when (null-pointer-p dp)
+		 (error "Error opening directory ~S." dir))
+	       (let ((*default-pathname-defaults* dir))
+		 (setf (current-directory) dir)
+		 (funcall fun #'one-iter)))
+	  (when dp
+	    (if (zerop (closedir dp))
+		nil
+		(error "Error closing directory ~S." dir)))
+	  (setf (current-directory) old-dir))))))
 
 (defun mapdir (function pathspec)
   "function MAPDIR function pathspec => list





More information about the Osicat-cvs mailing list