1 ;;; Copyright (C) 2011, 2014-2015 Rocky Bernstein <rocky@gnu.org>
2 (eval-when-compile (require 'cl))
4 (require 'load-relative)
5 (require-relative-list '("../../common/track" "../../common/core" "../../common/lang")
7 (require-relative-list '("../../common/buffer/command")
9 (require-relative-list '("init") "realgud:remake-")
11 (declare-function realgud:expand-file-name-if-exists 'realgud-core)
12 (declare-function realgud-parse-command-arg 'realgud-core)
13 (declare-function realgud-query-cmdline 'realgud-core)
14 (declare-function realgud-suggest-invocation 'realgud-core)
15 (declare-function realgud-lang-mode? 'realgud-lang)
16 (declare-function realgud-cmdbuf-command-string
17 'realgud-buffer-command)
18 (declare-function realgud-cmdbuf-debugger-name
19 'realgud-buffer-command)
20 ;; FIXME: I think the following could be generalized and moved to
21 ;; realgud-... probably via a macro.
22 (defvar realgud:remake-minibuffer-history nil
23 "minibuffer history list for the command `remake'.")
25 (easy-mmode-defmap remake-minibuffer-local-map
26 '(("\C-i" . comint-dynamic-complete-filename))
27 "Keymap for minibuffer prompting of gud startup command."
28 :inherit minibuffer-local-map)
30 ;; FIXME: I think this code and the keymaps and history
31 ;; variable chould be generalized, perhaps via a macro.
32 (defun remake-query-cmdline (&optional opt-debugger)
33 (realgud-query-cmdline
34 'remake-suggest-invocation
35 remake-minibuffer-local-map
36 'realgud:remake-minibuffer-history
39 (defun remake-parse-cmd-args (orig-args)
40 "Parse command line ARGS for the annotate level and name of script to debug.
42 ARGS should contain a tokenized list of the command line to run.
44 We return the a list containing
46 - the command processor (e.g. make)
48 - command args (which includes the makefile name)
50 For example for the following input
51 '(\"remake\" \"-x\" \"/tmp/Makefile\")
54 (\"remake\" \"/tmp/Makefile\" (\"-x\" \"/tmp/Makefile\"))
61 (if (member system-type (list 'windows-nt 'cygwin 'msdos))
62 "^\\(re\\)?make*\\(.exe\\)?$"
73 (list remake-name makefile-name remake-args)
75 ;; Strip off "make" or "remake" etc.
76 (when (string-match interp-regexp
77 (file-name-sans-extension
78 (file-name-nondirectory (car args))))
79 (setq remake-name (pop args))
84 (let ((arg (pop args)))
86 ;; ;; Annotation or emacs option with level number.
87 ;; ((or (member arg '("--annotate" "-A"))
88 ;; (equal arg "--emacs"))
89 ;; (setq annotate-p t)
90 ;; (nconc debugger-args (list (pop args))))
91 ;; ;; Combined annotation and level option.
92 ;; ((string-match "^--annotate=[0-9]" arg)
93 ;; (nconc debugger-args (list (pop args)) )
94 ;; (setq annotate-p t))
96 ((member arg '("--file" "--makefile" "-f"))
97 (setq remake-args (nconc remake-args (list arg)))
98 (setq makefile-name (realgud:expand-file-name-if-exists
100 (setq remake-args (nconc remake-args
101 (list (format "%s" makefile-name)))))
103 ;; Anything else add to remake-args
104 ('t (setq remake-args (nconc remake-args (list arg))))
106 (list remake-name makefile-name remake-args))))
108 (defconst realgud:remake-auto-suffix-regexp
110 "Common automake and autoconf Makefile suffixes"
113 (defconst realgud:remake-makefile-regexp
114 "\\(^[Mm]akefile$\\|\\.Makefile$\\|\\.mk\\)$"
115 "Regular expression matching common Makefile names"
118 (defun remake-suggest-file-priority(filename)
122 (if (realgud-lang-mode? filename "makefile")
124 (if (string-match realgud:remake-makefile-regexp filename)
126 (if (string-match realgud:remake-auto-suffix-regexp filename)
130 ;; The file isn't in a makefile-mode buffer,
131 ;; Check for an executable file with a .mk extension.
132 (if (setq is-not-directory (not (file-directory-p filename)))
133 (if (and (string-match realgud:remake-makefile-regexp filename))
136 (setq priority 6)))))
141 (defun remake-suggest-Makefile ()
142 "Suggest a Makefile to debug.
144 The first priority is given to the current buffer. If the major
145 mode matches GNUMakefile and doesn't end in .am or .in, then we
146 are done. If not, we'll set priority 2 (a low or easily
147 overridden priority) and we keep going. Then we will try files
148 in the default-directory. Of those that we are visiting we check
149 the major mode. There are demerits for a file ending in .in or
150 .am which are used by 'configure' and 'automake' respectively.
152 If the current buffer isn't a success, we see if the file matches
153 REGEXP. These have priority 9, 8 or 7 depending on whether there
154 is a .in or .am sufifx and there is a REGEXP match'. Within a
155 given priority, we use the first one we find."
157 (file-list (directory-files default-directory))
160 (result (buffer-file-name)))
161 (if (not (realgud-lang-mode? result "makefile"))
163 (while (and (setq file (car-safe file-list)) (< priority 8))
164 (setq file-list (cdr file-list))
165 (let ((try-priority (remake-suggest-file-priority file)))
166 (if (> try-priority priority)
168 (setq priority try-priority)
175 ;; To silence Warning: reference to free variable
176 (defvar realgud:remake-command-name)
178 ;; Note opt-debugger is not used. It has to be there because
179 ;; realgud-suggest-invocation passes an argument.
180 (defun remake-suggest-invocation (&optional opt-debugger)
181 "Suggest a remake command invocation via `realgud-suggest-invocaton'"
183 (let* ((buf (current-buffer))
184 (debugger-name realgud:remake-command-name)
185 (cmd-str-cmdbuf (realgud-cmdbuf-command-string buf))
188 ((and cmd-str-cmdbuf (equal debugger-name (realgud-cmdbuf-debugger-name buf)))
190 ((and minibuffer-history (listp minibuffer-history))
191 (car minibuffer-history))
192 (t (concat debugger-name " --debugger -f "
193 (remake-suggest-Makefile)))
196 ;; Convert a command line as would be typed normally to run a script
197 ;; into one that invokes an Emacs-enabled debugging session.
198 ;; "--debugger" in inserted as the first switch.
200 (defun realgud:remake-massage-args (command-line)
201 (let* ((new-args (list "--debugger"))
202 (args (split-string-and-unquote command-line))
206 (setq new-args (cons (car args) new-args))
207 (setq args (cdr args)))))
209 ;; Pass all switches and -e scripts through.
211 (string-match "^-" (car args))
212 (not (equal "-" (car args)))
213 (not (equal "--" (car args))))
217 (string-match "^-" (car args)))
218 (error "Can't use stdin as the script to debug"))
219 ;; This is the program name.
229 (defun remake-reset ()
230 "Remake cleanup - remove debugger's internal buffers (frame,
233 ;; (remake-breakpoint-remove-all-icons)
234 (dolist (buffer (buffer-list))
235 (when (string-match "\\*remake-[a-z]+\\*" (buffer-name buffer))
236 (let ((w (get-buffer-window buffer)))
239 (kill-buffer buffer))))
241 ;; (defun remake-reset-keymaps()
242 ;; "This unbinds the special debugger keys of the source buffers."
244 ;; (setcdr (assq 'remake-debugger-support-minor-mode minor-mode-map-alist)
245 ;; remake-debugger-support-minor-mode-map-when-deactive))
248 (defun realgud:remake-customize ()
249 "Use `customize' to edit the settings of the `remake' debugger."
251 (customize-group 'realgud:remake))
253 (provide-me "realgud:remake-")