0.pre7.20:
[sbcl.git] / src / code / filesys.lisp
index 5b115c3..145dae3 100644 (file)
 
 ;;; Call FUNCTION on matches.
 (defun %enumerate-matches (pathname verify-existence follow-links function)
-  (/show0 "entering %ENUMERATE-MATCHES")
+  (/noshow0 "entering %ENUMERATE-MATCHES")
   (when (pathname-type pathname)
     (unless (pathname-name pathname)
       (error "cannot supply a type without a name:~%  ~S" pathname)))
             (member (pathname-type pathname) '(nil :unspecific)))
     (error "cannot supply a version without a type:~%  ~S" pathname))
   (let ((directory (pathname-directory pathname)))
-    (/show0 "computed DIRECTORY")
+    (/noshow0 "computed DIRECTORY")
     (if directory
        (ecase (car directory)
          (:absolute
-          (/show0 "absolute directory")
+          (/noshow0 "absolute directory")
           (%enumerate-directories "/" (cdr directory) pathname
                                   verify-existence follow-links
                                   nil function))
          (:relative
-          (/show0 "relative directory")
+          (/noshow0 "relative directory")
           (%enumerate-directories "" (cdr directory) pathname
                                   verify-existence follow-links
                                   nil function)))
 ;;; Call FUNCTION on files.
 (defun %enumerate-files (directory pathname verify-existence function)
   (declare (simple-string directory))
-  (/show0 "entering %ENUMERATE-FILES")
+  (/noshow0 "entering %ENUMERATE-FILES")
   (let ((name (%pathname-name pathname))
        (type (%pathname-type pathname))
        (version (%pathname-version pathname)))
-    (/show0 "computed NAME, TYPE, and VERSION")
+    (/noshow0 "computed NAME, TYPE, and VERSION")
     (cond ((member name '(nil :unspecific))
-          (/show0 "UNSPECIFIC, more or less")
+          (/noshow0 "UNSPECIFIC, more or less")
           (when (or (not verify-existence)
                     (sb!unix:unix-file-kind directory))
             (funcall function directory)))
               (pattern-p type)
               (eq name :wild)
               (eq type :wild))
-          (/show0 "WILD, more or less")
+          (/noshow0 "WILD, more or less")
           ;; I IGNORE-ERRORS here just because the original CMU CL
           ;; code did. I think the intent is that it's not an error
           ;; to request matches to a wild pattern when no matches
                                       directory
                                       complete-filename))))))
          (t
-          (/show0 "default case")
+          (/noshow0 "default case")
           (let ((file (concatenate 'string directory name)))
-            (/show0 "computed basic FILE=..")
+            (/noshow0 "computed basic FILE=..")
             (/primitive-print file)
             (unless (or (null type) (eq type :unspecific))
-              (/show0 "tweaking FILE for more-or-less-:UNSPECIFIC case")
+              (/noshow0 "tweaking FILE for more-or-less-:UNSPECIFIC case")
               (setf file (concatenate 'string file "." type)))
             (unless (member version '(nil :newest :wild))
-              (/show0 "tweaking FILE for more-or-less-:WILD case")
+              (/noshow0 "tweaking FILE for more-or-less-:WILD case")
               (setf file (concatenate 'string file "."
                                       (quick-integer-to-string version))))
-            (/show0 "finished possibly tweaking FILE=..")
+            (/noshow0 "finished possibly tweaking FILE=..")
             (/primitive-print file)
             (when (or (not verify-existence)
                       (sb!unix:unix-file-kind file t))
-              (/show0 "calling FUNCTION on FILE")
+              (/noshow0 "calling FUNCTION on FILE")
               (funcall function file)))))))
 
-(/show0 "filesys.lisp 603")
+(/noshow0 "filesys.lisp 603")
 
 ;;; FIXME: Why do we need this?
 (defun quick-integer-to-string (n)
   #!+sb-doc
   "Return the pathname for the actual file described by PATHNAME.
   An error of type FILE-ERROR is signalled if no such file exists,
-  or the pathname is wild."
+  or the pathname is wild.
+
+  Under Unix, the TRUENAME of a broken symlink is considered to be
+  the name of the broken symlink itself."
   (if (wild-pathname-p pathname)
       (error 'simple-file-error
             :format-control "can't use a wild pathname here"
                              pathname
                              (sane-default-pathname-defaults)))
         (namestring (unix-namestring defaulted-pathname t)))
-    (when (and namestring (sb!unix:unix-file-kind namestring))
-      (let ((truename (sb!unix:unix-resolve-links namestring)))
-       (when truename
+    (when (and namestring (sb!unix:unix-file-kind namestring t))
+      (let ((trueishname (sb!unix:unix-resolve-links namestring)))
+       (when trueishname
          (let ((*ignore-wildcards* t))
-           (pathname (sb!unix:unix-simplify-pathname truename))))))))
+           (pathname (sb!unix:unix-simplify-pathname trueishname))))))))
 \f
 ;;;; miscellaneous other operations
 
 
 (defun file-author (file)
   #!+sb-doc
-  "Returns the file author as a string, or nil if the author cannot be
- determined. Signals an error of type file-error if file doesn't exist,
- or file is a wild pathname."
+  "Return the file author as a string, or nil if the author cannot be
+ determined. Signal an error of type FILE-ERROR if FILE doesn't exist,
+ or FILE is a wild pathname."
   (if (wild-pathname-p file)
       (error 'simple-file-error
             :pathname file
 
 (/show0 "filesys.lisp 800")
 
-(defun directory (pathname &key (all t) (check-for-subdirs t)
-                          (follow-links t))
+(defun directory (pathname &key)
   #!+sb-doc
-  "Returns a list of pathnames, one for each file that matches the given
-   pathname. Supplying :ALL as NIL causes this to ignore Unix dot files. This
-   never includes Unix dot and dot-dot in the result. If :FOLLOW-LINKS is NIL,
-   then symbolic links in the result are not expanded. This is not the
-   default because TRUENAME does follow links, and the result pathnames are
-   defined to be the TRUENAME of the pathname (the truename of a link may well
-   be in another directory.)"
-  (let ((results nil))
+  "Return a list of PATHNAMEs, each the TRUENAME of a file that matched the
+   given pathname. Note that the interaction between this ANSI-specified
+   TRUENAMEing and the semantics of the Unix filesystem (symbolic links..)
+   means this function can sometimes return files which don't have the same
+   directory as PATHNAME."
+  (let ((truenames nil))
     (enumerate-search-list
        (pathname (merge-pathnames pathname
                                   (make-pathname :name :wild
                                                  :type :wild
                                                  :version :wild)))
-      (enumerate-matches (name pathname)
-       (when (or all
-                 (let ((slash (position #\/ name :from-end t)))
-                   (or (null slash)
-                       (= (1+ slash) (length name))
-                       (char/= (schar name (1+ slash)) #\.))))
-         (push name results))))
-    (let ((*ignore-wildcards* t))
-      (mapcar (lambda (name)
-               (let ((name (if (and check-for-subdirs
-                                    (eq (sb!unix:unix-file-kind name)
-                                        :directory))
-                               (concatenate 'string name "/")
-                               name)))
-                 (if follow-links (truename name) (pathname name))))
-             (sort (delete-duplicates results :test #'string=) #'string<)))))
+      (enumerate-matches (match pathname)
+       (let ((*ignore-wildcards* t))
+         (push (truename (if (eq (sb!unix:unix-file-kind match) :directory)
+                             (concatenate 'string match "/")
+                             match))
+               truenames))))
+    ;; FIXME: The DELETE-DUPLICATES here requires quadratic time,
+    ;; which is unnecessarily slow. That might not be an issue,
+    ;; though, since the time constant for doing TRUENAME on every
+    ;; directory entry is likely to be (much) larger, and the cost of
+    ;; all those TRUENAMEs on a huge directory might even be quadratic
+    ;; in the directory size. Someone who cares about enormous
+    ;; directories might want to check this. -- WHN 2001-06-19
+    (sort (delete-duplicates truenames :test #'string= :key #'pathname-name)
+         #'string< :key #'pathname-name)))
 \f
 ;;;; translating Unix uid's
 ;;;;