(exec-installed-p): Add parens.
[elisp/apel.git] / path-util.el
1 ;;; path-util.el --- Emacs Lisp file detection utility
2
3 ;; Copyright (C) 1996,1997,1999 Free Software Foundation, Inc.
4
5 ;; Author: MORIOKA Tomohiko <tomo@m17n.org>
6 ;; Keywords: file detection, install, module
7
8 ;; This file is part of APEL (A Portable Emacs Library).
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 (require 'poe)
28
29 (defvar default-load-path load-path
30   "*Base of `load-path'.
31 It is used as default value of target path to search file or
32 subdirectory under load-path.")
33
34 ;;;###autoload
35 (defun add-path (path &rest options)
36   "Add PATH to `load-path' if it exists under `default-load-path'
37 directories and it does not exist in `load-path'.
38
39 You can use following PATH styles:
40         load-path relative: \"PATH/\"
41                         (it is searched from `defaul-load-path')
42         home directory relative: \"~/PATH/\" \"~USER/PATH/\"
43         absolute path: \"/HOO/BAR/BAZ/\"
44
45 You can specify following OPTIONS:
46         'all-paths      search from `load-path'
47                         instead of `default-load-path'
48         'append         add PATH to the last of `load-path'"
49   (let ((rest (if (memq 'all-paths options)
50                   load-path
51                 default-load-path))
52         p)
53     (if (and (catch 'tag
54                (while rest
55                  (setq p (expand-file-name path (car rest)))
56                  (if (file-directory-p p)
57                      (throw 'tag p)
58                    )
59                  (setq rest (cdr rest))
60                  ))
61              (not (member p load-path))
62              )
63         (setq load-path
64               (if (memq 'append options)
65                   (append load-path (list p))
66                 (cons p load-path)
67                 ))
68       )))
69
70 ;;;###autoload
71 (defun add-latest-path (pattern &optional all-paths)
72   "Add latest path matched by PATTERN to `load-path'
73 if it exists under `default-load-path' directories
74 and it does not exist in `load-path'.
75
76 If optional argument ALL-PATHS is specified, it is searched from all
77 of load-path instead of default-load-path."
78   (let ((path (get-latest-path pattern all-paths)))
79     (if path
80         (add-to-list 'load-path path)
81       )))
82
83 ;;;###autoload
84 (defun get-latest-path (pattern &optional all-paths)
85   "Return latest directory in default-load-path
86 which is matched to regexp PATTERN.
87 If optional argument ALL-PATHS is specified,
88 it is searched from all of load-path instead of default-load-path."
89   (catch 'tag
90     (let ((paths (if all-paths
91                     load-path
92                   default-load-path))
93           dir)
94       (while (setq dir (car paths))
95         (if (and (file-exists-p dir)
96                  (file-directory-p dir)
97                  )
98             (let ((files (sort (directory-files dir t pattern t)
99                                (function file-newer-than-file-p)))
100                   file)
101               (while (setq file (car files))
102                 (if (file-directory-p file)
103                     (throw 'tag file)
104                   )
105                 (setq files (cdr files))
106                 )))
107         (setq paths (cdr paths))
108         ))))
109
110 ;;;###autoload
111 (defun file-installed-p (file &optional paths)
112   "Return absolute-path of FILE if FILE exists in PATHS.
113 If PATHS is omitted, `load-path' is used."
114   (if (null paths)
115       (setq paths load-path)
116     )
117   (catch 'tag
118     (let (path)
119       (while paths
120         (setq path (expand-file-name file (car paths)))
121         (if (file-exists-p path)
122             (throw 'tag path)
123           )
124         (setq paths (cdr paths))
125         ))))
126
127 ;;;###autoload
128 (defvar exec-suffix-list '("")
129   "*List of suffixes for executable.")
130
131 ;;;###autoload
132 (defun exec-installed-p (file &optional paths suffixes)
133   "Return absolute-path of FILE if FILE exists in PATHS.
134 If PATHS is omitted, `exec-path' is used.
135 If suffixes is omitted, `exec-suffix-list' is used."
136   (or paths
137       (setq paths exec-path)
138       )
139   (or suffixes
140       (setq suffixes exec-suffix-list)
141       )
142   (let (files)
143     (catch 'tag
144       (while suffixes
145         (let ((suf (car suffixes)))
146           (if (and (not (string= suf ""))
147                    (string-match (concat (regexp-quote suf) "$") file))
148               (progn
149                 (setq files (list file))
150                 (throw 'tag nil)
151                 )
152             (setq files (cons (concat file suf) files))
153             )
154           (setq suffixes (cdr suffixes))
155           )))
156     (setq files (nreverse files))
157     (catch 'tag
158       (while paths
159         (let ((path (car paths))
160               (files files)
161               )
162           (while files
163             (setq file (expand-file-name (car files) path))
164             (if (file-executable-p file)
165                 (throw 'tag file)
166               )
167             (setq files (cdr files))
168             )
169           (setq paths (cdr paths))
170           )))))
171
172 ;;;###autoload
173 (defun module-installed-p (module &optional paths)
174   "Return t if module is provided or exists in PATHS.
175 If PATHS is omitted, `load-path' is used."
176   (or (featurep module)
177       (let ((file (symbol-name module)))
178         (or paths
179             (setq paths load-path)
180             )
181         (catch 'tag
182           (while paths
183             (let ((stem (expand-file-name file (car paths)))
184                   (sufs '(".elc" ".el"))
185                   )
186               (while sufs
187                 (let ((file (concat stem (car sufs))))
188                   (if (file-exists-p file)
189                       (throw 'tag file)
190                     ))
191                 (setq sufs (cdr sufs))
192                 ))
193             (setq paths (cdr paths))
194             )))))
195
196
197 ;;; @ end
198 ;;;
199
200 (provide 'path-util)
201
202 ;;; path-util.el ends here