comparison lisp/emacs-lisp/shadow.el @ 19982:199256234202

(shadows-compare-text-p): Add. (shadow-same-file-or-nonexistent): Add. (find-emacs-lisp-shadows): Use directory-file-name.
author Karl Heuer <kwzh@gnu.org>
date Thu, 25 Sep 1997 01:33:26 +0000
parents 04175c55c49b
children db005054f15d
comparison
equal deleted inserted replaced
19981:1d135b4edfcb 19982:199256234202
51 ;; Thanks to Francesco Potorti` <pot@cnuce.cnr.it> for suggestions, 51 ;; Thanks to Francesco Potorti` <pot@cnuce.cnr.it> for suggestions,
52 ;; rewritings & speedups. 52 ;; rewritings & speedups.
53 53
54 ;;; Code: 54 ;;; Code:
55 55
56 (defvar shadows-compare-text-p nil
57 "*If non-nil, then shadowing files are reported only if their text differs.
58 This is slower, but filters out some innocuous shadowing.")
59
56 (defun find-emacs-lisp-shadows (&optional path) 60 (defun find-emacs-lisp-shadows (&optional path)
57 "Return a list of Emacs Lisp files that create shadows. 61 "Return a list of Emacs Lisp files that create shadows.
58 This function does the work for `list-load-path-shadows'. 62 This function does the work for `list-load-path-shadows'.
59 63
60 We traverse PATH looking for shadows, and return a \(possibly empty\) 64 We traverse PATH looking for shadows, and return a \(possibly empty\)
76 file) ; The current file. 80 file) ; The current file.
77 81
78 82
79 (while path 83 (while path
80 84
81 (setq dir (file-truename (or (car path) "."))) 85 (setq dir (directory-file-name (file-truename (or (car path) "."))))
82 (if (member dir true-names) 86 (if (member dir true-names)
83 ;; We have already considered this PATH redundant directory. 87 ;; We have already considered this PATH redundant directory.
84 ;; Show the redundancy if we are interactiver, unless the PATH 88 ;; Show the redundancy if we are interactiver, unless the PATH
85 ;; dir is nil or "." (these redundant directories are just a 89 ;; dir is nil or "." (these redundant directories are just a
86 ;; result of the current working directory, and are therefore 90 ;; result of the current working directory, and are therefore
87 ;; not always redundant). 91 ;; not always redundant).
88 (or noninteractive 92 (or noninteractive
89 (and (car path) 93 (and (car path)
90 (not (string= (car path) ".")) 94 (not (string= (car path) "."))
91 (message "Ignoring redundant directory %s" (car path)))) 95 (message "Ignoring redundant directory %s" (car path))))
92 96
93 (setq true-names (append true-names (list dir))) 97 (setq true-names (append true-names (list dir)))
94 (setq dir (or (car path) ".")) 98 (setq dir (directory-file-name (or (car path) ".")))
95 (setq curr-files (if (file-accessible-directory-p dir) 99 (setq curr-files (if (file-accessible-directory-p dir)
96 (directory-files dir nil ".\\.elc?$" t))) 100 (directory-files dir nil ".\\.elc?$" t)))
97 (and curr-files 101 (and curr-files
98 (not noninteractive) 102 (not noninteractive)
99 (message "Checking %d files in %s..." (length curr-files) dir)) 103 (message "Checking %d files in %s..." (length curr-files) dir))
100 104
101 (setq files-seen-this-dir nil) 105 (setq files-seen-this-dir nil)
102 106
103 (while curr-files 107 (while curr-files
104 108
105 (setq file (car curr-files)) 109 (setq file (car curr-files))
115 ;; XXX.elc (or vice-versa) when they are in the same directory. 119 ;; XXX.elc (or vice-versa) when they are in the same directory.
116 (setq files-seen-this-dir (cons file files-seen-this-dir)) 120 (setq files-seen-this-dir (cons file files-seen-this-dir))
117 121
118 (if (setq orig-dir (assoc file files)) 122 (if (setq orig-dir (assoc file files))
119 ;; This file was seen before, we have a shadowing. 123 ;; This file was seen before, we have a shadowing.
124 ;; Report it unless the files are identical.
125 (let ((base1 (concat (cdr orig-dir) "/" file))
126 (base2 (concat dir "/" file)))
127 (if (not (and shadows-compare-text-p
128 (shadow-same-file-or-nonexistent
129 (concat base1 ".el") (concat base2 ".el"))
130 ;; This is a bit strict, but safe.
131 (shadow-same-file-or-nonexistent
132 (concat base1 ".elc") (concat base2 ".elc"))))
120 (setq shadows 133 (setq shadows
121 (append shadows 134 (append shadows (list base1 base2)))))
122 (list (concat (cdr orig-dir) "/" file)
123 (concat dir "/" file))))
124 135
125 ;; Not seen before, add it to the list of seen files. 136 ;; Not seen before, add it to the list of seen files.
126 (setq files (cons (cons file dir) files)))) 137 (setq files (cons (cons file dir) files))))
127 138
128 (setq curr-files (cdr curr-files)))) 139 (setq curr-files (cdr curr-files))))
129 (setq path (cdr path))) 140 (setq path (cdr path)))
130 141
131 ;; Return the list of shadowings. 142 ;; Return the list of shadowings.
132 shadows)) 143 shadows))
133 144
145 ;; Return true if neither file exists, or if both exist and have identical
146 ;; contents.
147 (defun shadow-same-file-or-nonexistent (f1 f2)
148 (let ((exists1 (file-exists-p f1))
149 (exists2 (file-exists-p f2)))
150 (or (and (not exists1) (not exists2))
151 (and exists1 exists2
152 (or (equal (file-truename f1) (file-truename f2))
153 ;; As a quick test, avoiding spawning a process, compare file
154 ;; sizes.
155 (and (= (nth 7 (file-attributes f1))
156 (nth 7 (file-attributes f2)))
157 (zerop (call-process "cmp" nil nil nil "-s" f1 f2))))))))
134 158
135 ;;;###autoload 159 ;;;###autoload
136 (defun list-load-path-shadows () 160 (defun list-load-path-shadows ()
137 "Display a list of Emacs Lisp files that shadow other files. 161 "Display a list of Emacs Lisp files that shadow other files.
138 162