root/trunk/lisp/international/mw32script.el

Revision 4030, 7.1 kB (checked in by shirai, 3 years ago)

* international/mw32script.el
(mw32script-file-executable-p): Add dos-string.
(mw32script-original-executable-find): New variable.
(mw32script-executable-find): New function.
(mw32script-init): Substitute `executable-find' to
`mw32script-executable-find' and tiny fix.

  • Property svn:eol-style set to LF
Line 
1 ;;; mw32script.el
2 ;;; Author: yamagus@kw.netlaputa.ne.jp (YAMAGUCHI, Shuhei)
3 ;;; Modified by H.Miyashita.
4 ;;; Version 1.2 (Feb 2, 1998)
5 ;;;
6 ;;; [USAGE]
7 ;;; Add the following in your .emacs:
8 ;;;  (require 'mw32script)
9 ;;;  (mw32script-init)
10
11 (defconst mw32script-version "W32 Script version 1.2")
12 ;; begin --- options
13 (defvar mw32script-argument-editing-alist
14   '(("/sh$" . "sh.exe")
15     ("/bash$" . "bash.exe")
16     ("/perl$" . "perl.exe")
17     ("/t?csh$" . "tcsh.exe")
18     ("/ruby$" . "ruby.exe")
19     ("/rubyw$" . "rubyw.exe")
20     ("/env$" . "env.exe"))
21   "Association list of script interpreter.")
22
23 (defvar mw32script-pathext '(".com" ".exe" ".bat" ".cmd")
24   "Extention list of executables.")
25
26 (defvar mw32script-resolve-script t
27   "If non-nil, mw32script-argument-editing-function
28 resolve the script association.")
29
30 (defvar mw32script-resolve-extention (fboundp 'Meadow-version)
31   "If non-nil, mw32script-argument-editing-function
32 resolve the filename association.
33 This only works with Meadow version Alpha-3.00 or later.")
34
35 (defvar mw32script-recursive nil)
36 (defvar mw32script-original-file-executable-p nil)
37 (defvar mw32script-original-executable-find nil)
38 ;; end --- options
39 (defvar mw32script-bufsiz 256)
40 (defvar mw32script-buffer-tmp " *mw32script*")
41 (defvar mw32script-pathext-regexp nil)
42
43 (defun mw32script-make-pathext-regexp ()
44   (setq mw32script-pathext-regexp
45         (concat "\\("
46                 (mapconcat
47                  (lambda (x) (regexp-quote x))
48                  mw32script-pathext "\\|")
49                 "\\)$")))
50
51 (defun mw32script-openp (command-name)
52   "Locate the full path name of external-command COMMAND-NAME."
53   (interactive "sExternal-command: ")
54   (catch 'tag
55     (let (path)
56       (if (file-name-absolute-p command-name)
57           (if (and (file-executable-p command-name)
58                    (null (file-directory-p command-name)))
59               (throw 'tag command-name)
60             (mapcar
61              (lambda (suf)
62                (setq path (expand-file-name (concat command-name suf)))
63                (and (file-executable-p path)
64                     (null (file-directory-p path))
65                     (throw 'tag path)))
66              (if (null mw32script-pathext)
67                  '("")
68                mw32script-pathext)))
69         (mapcar
70          (lambda (dir)
71            (mapcar
72             (lambda (suf)
73               (setq path (expand-file-name (concat command-name suf) dir))
74               (and (file-executable-p path)
75                    (null (file-directory-p path))
76                    (throw 'tag path)))
77             (if (null mw32script-pathext)
78                 '("")
79               (append (list "") mw32script-pathext))))
80          exec-path))) nil))
81
82
83 (defun mw32script-resolve-script (path &optional directory)
84   "Find executable path that interprets the script specified PATH.
85 Return value is a list of arguments, and car of the list is argv[0].
86 The optional argument DIRECTORY specify the default directory.
87 If the object executable is not found, return nil."
88   (interactive "fScript: ")
89   (setq path
90         (expand-file-name
91          (if directory
92              (concat (file-name-as-directory directory) path)
93            path)))
94   (let ((buf (generate-new-buffer mw32script-buffer-tmp))
95         limit args)
96     (unwind-protect
97         (save-excursion
98           (set-buffer buf)
99           (set-buffer-multibyte nil)
100           (condition-case nil
101               (progn
102                 (let ((coding-system-for-read 'raw-text))
103                   (insert-file-contents path nil 0 mw32script-bufsiz))
104                 (goto-line 2)
105                 (setq limit (point))
106                 (goto-char 1)
107                 (if (re-search-forward
108                      "\\`#![ \t]*\\([^ \t\n]+\\)[ \t]*" limit t)
109                     (while
110                         (progn
111                           (setq args
112                                 (nconc args
113                                        (list
114                                         (buffer-substring (match-beginning 1)
115                                                           (match-end 1)))))
116                           (re-search-forward "\\([^ \t\n]+\\)[ \t]*"
117                                              limit t))))
118                 args)
119             (file-error nil)))
120       (kill-buffer buf))))
121
122
123 (defun mw32script-resolve-extention (path &optional directory)
124   "Find executable path that associated with filename specified PATH.
125 Return value is a list of arguments, and car of the list is argv[0].
126 The optional argument DIRECTORY specify the default directory.
127 If the object executable is not found, return 'notfound."
128   (interactive "fFile: ")
129   (setq path
130         (expand-file-name
131          (if directory
132              (concat (file-name-as-directory directory) path)
133            path)))
134   (let (executable)
135     (condition-case nil
136         (progn
137           (setq executable (w32-find-executable path))
138           (if (eq executable 'notfound)
139               executable
140             (list executable)))
141       (error nil))))
142
143
144 (defun mw32script-argument-editing-function (argument)
145   "Resolv the script/filename association,
146 and do the argument editiong."
147   (let ((argv0 (car argument)) sargs func ret)
148     (if (string-match mw32script-pathext-regexp argv0)
149         (funcall default-process-argument-editing-function argument)
150       (and mw32script-resolve-extention
151            (setq sargs (mw32script-resolve-extention argv0)))
152       (and mw32script-resolve-script
153            (or (not sargs) (eq sargs 'notfound))
154            (setq sargs (mw32script-resolve-script argv0)))
155       (if (and sargs (not (eq sargs 'notfound)))
156           (progn
157             (setq argv0 (car sargs))
158             (catch 'tag
159               (mapcar
160                (lambda (pat)
161                  (and (string-match (car pat) argv0)
162                       (setq argv0 (mw32script-openp (cdr pat)))
163                       (throw 'tag t)))
164                mw32script-argument-editing-alist))
165             (and (eq (setq func (find-process-argument-editing-function argv0))
166                      (function mw32script-argument-editing-function))
167                  (not mw32script-recursive)
168                  (setq func default-process-argument-editing-function))
169             (if (consp (setq ret (funcall
170                                   func
171                                   (append (list argv0) (cdr sargs) argument))))
172                 ret
173               (cons argv0 ret)))
174         (funcall default-process-argument-editing-function argument)))))
175
176 (defun mw32script-file-executable-p (filename)
177   "Return t if filename can be executed by you.
178 For a directory, this means you can access files in that directory.
179
180 Add an analytical capability of the script file to this function by Meadow."
181   (or (funcall mw32script-original-file-executable-p filename)
182       (and (mw32script-resolve-script filename)
183            t)))
184
185 (defun mw32script-executable-find (command)
186   "Search for command in `exec-path' and return the absolute file name.
187 Return nil if command is not found anywhere in `exec-path'.
188
189 Add an analytical capability of the script file to this function by Meadow."
190   (catch 'detect
191     (let ((paths exec-path)
192           (suffixes exec-suffixes)
193           cmds names path file)
194       (while suffixes
195         (setq cmds (cons (concat command (car suffixes)) cmds))
196         (setq suffixes (cdr suffixes)))
197       (setq cmds (nreverse cmds))
198       (while (setq path (car paths))
199         (setq paths (cdr paths))
200         (setq names cmds)
201         (while names
202           (setq file (locate-file-internal (car names) (list path)))
203           (when (and file
204                      (not (file-directory-p file))
205                      (mw32script-file-executable-p file))
206             (throw 'detect file))
207           (setq names (cdr names)))))))
208
209 (defun mw32script-init ()
210   (interactive)
211   (mw32script-make-pathext-regexp)
212   (define-process-argument-editing
213     ".*"
214     (function mw32script-argument-editing-function) 'last)
215   (add-to-list 'exec-suffix-list "")
216   (unless mw32script-original-file-executable-p
217     (setq mw32script-original-file-executable-p
218           (symbol-function 'file-executable-p))
219     (fset 'file-executable-p 'mw32script-file-executable-p))
220   (unless mw32script-original-executable-find
221     (setq mw32script-original-executable-find
222           (symbol-function 'executable-find))
223     (fset 'executable-find 'mw32script-executable-find)))
224
225 (provide 'mw32script)
Note: See TracBrowser for help on using the browser.