aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1994-04-20 06:12:03 +0000
committerRichard M. Stallman1994-04-20 06:12:03 +0000
commit89fb82d61364a0a6a46954eec9c368e37d322513 (patch)
tree7b8866ac71f88c3591c83fcb545b401288673c32
parentc6207d0d29923eac4d3a01dff71b33ebc76f0971 (diff)
downloademacs-89fb82d61364a0a6a46954eec9c368e37d322513.tar.gz
emacs-89fb82d61364a0a6a46954eec9c368e37d322513.zip
Provide cmacexp.
(c-macro-prompt-p): Renamed from c-macro-always-prompt-p. (c-macro-cppflags): Var renamed from c-macro-default-cppflags. (c-macro-expand): Don't handle C-u C-u specially. Compute message here in var mymsg. Clear buffer-auto-save-file-name. (c-macro-display-buffer): Now takes no argument. Use point-max to get large number. (c-macro-default-message, c-macro-eval): Functions deleted. (c-macro-expansion): Use startinstring as the char to insert.
-rw-r--r--lisp/progmodes/cmacexp.el249
1 files changed, 74 insertions, 175 deletions
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
index e82940d2d44..e4c22f0dbe7 100644
--- a/lisp/progmodes/cmacexp.el
+++ b/lisp/progmodes/cmacexp.el
@@ -3,7 +3,7 @@
3;; Copyright (C) 1992 Free Software Foundation, Inc. 3;; Copyright (C) 1992 Free Software Foundation, Inc.
4 4
5;; Author: Francesco Potorti` <pot@cnuce.cnr.it> 5;; Author: Francesco Potorti` <pot@cnuce.cnr.it>
6;; Version: $Id: cmacexp.el,v 1.9 1994/02/07 05:40:46 rms Exp rms $ 6;; Version: $Id: cmacexp.el,v 1.10 1994/02/25 06:27:24 rms Exp rms $
7;; Adapted-By: ESR 7;; Adapted-By: ESR
8;; Keywords: c 8;; Keywords: c
9 9
@@ -23,35 +23,23 @@
23;; along with GNU Emacs; see the file COPYING. If not, write to 23;; along with GNU Emacs; see the file COPYING. If not, write to
24;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 25
26;;; Commentary: 26;; USAGE =============================================================
27 27
28;; In C mode C-M-x is bound to c-macro-expand. The result of the 28;; In C mode C-M-x is bound to c-macro-expand. The result of the
29;; expansion is put in a separate buffer. A user option 29;; expansion is put in a separate buffer. The buffer is put in
30;; view-mode if the Inge Frick's view.el is installed. A user option
30;; allows the window displaying the buffer to be optimally sized. 31;; allows the window displaying the buffer to be optimally sized.
31;; 32;;
32;; When called with a C-u prefix, c-macro-expand replaces the selected 33;; When called with a C-u prefix, c-macro-expand replaces the selected
33;; region with the expansion. With two C-u's the user is offered to 34;; region with the expansion. Both the preprocessor name and the
34;; change the flags to the preprocessor (while the results of the 35;; initial flag can be set by the user. If c-macro-prompt-p
35;; expansion go to a separate buffer). Preprocessor arguments default 36;; is set to a non-nil value the user is offered to change the flags
36;; to the last ones entered. Both the preprocessor name and the 37;; to the preprocessor each time c-macro-expand is invoked.
37;; initial flag defaults can be set by the user. Setting 38;; Preprocessor arguments default to the last ones entered.
38;; c-macro-always-prompt to a non-nil value allows one to be always 39;; If c-macro-prompt is nil, one must use M-x set-variable to set a
39;; prompted for the flags, regardless of the prefix used. 40;; different value for c-macro-cppflags.
40 41
41;; A c-macro-expansion function is provided for non-interactive use. 42;; A c-macro-expansion function is provided for non-interactive use.
42;; A still experimental function c-macro-eval is provided. It aims at
43;; evaluating the contents of a region by using calc (by Dave
44;; Gillespie). Select a region and type C-x C-e (if you followed the
45;; suggestions in the INSTALLATION section) or type M-x c-ma RET v
46;; RET. If you have calc installed, the computed value of the
47;; expression will appear in the message area. If you give an
48;; interactive C-u prefix the computed value will be shown in signed,
49;; unsigned, hex and boolean representations. Two C-u's allow to
50;; change the preprocessor flags via prompt. c-macro-eval works well
51;; for constant expressions, but see the BUG section.
52
53;; A patch to calc 2.02 has been written by Dave Gillespie. It can
54;; be downloaded via anonymous ftp at fly.cnuce.cnr.it:pub/calc.diff.
55 43
56;; INSTALLATION ====================================================== 44;; INSTALLATION ======================================================
57 45
@@ -61,9 +49,11 @@
61;; To make a directory ~/emacs be in front of your load-path: 49;; To make a directory ~/emacs be in front of your load-path:
62;;(setq load-path (cons (expand-file-name "~/emacs") load-path)) 50;;(setq load-path (cons (expand-file-name "~/emacs") load-path))
63;; 51;;
64;; Suggested keybindings (work only in c-mode): 52;; Suggested keybinding (work only in c-mode):
65;;(define-key c-mode-map "\C-\M-x" 'c-macro-expand) 53;;(if (boundp 'c-mode-map)
66;;(define-key c-mode-map "\C-x\C-e" 'c-macro-eval) 54;; (define-key c-mode-map "\C-x\C-e" 'c-macro-expand))
55;;(if (boundp 'c++-mode-map)
56;; (define-key c++-mode-map "\C-x\C-e" 'c-macro-expand))
67;; 57;;
68;; If you want the *Macroexpansion* window to be not higher than 58;; If you want the *Macroexpansion* window to be not higher than
69;; necessary: 59;; necessary:
@@ -74,18 +64,11 @@
74;; strip the comments): 64;; strip the comments):
75;;(setq c-macro-preprocessor "gpp -C") 65;;(setq c-macro-preprocessor "gpp -C")
76;; 66;;
77;; If you often use a particular set of flags, and want them to be 67;; If you often use a particular set of flags:
78;; the default: 68;;(setq c-macro-cppflags "-I /usr/include/local -DDEBUG"
79;;(setq c-macro-default-cppflags "-I /usr/include/local -DDEBUG"
80;; 69;;
81;; If you always want the "Preprocessor arguments: " prompt, 70;; If you want the "Preprocessor arguments: " prompt:
82;; regardless of the arguments provided: 71;;(setq c-macro-prompt-p t)
83;;(setq c-macro-always-prompt-p t)
84;;
85;; If you want to experiment with the C constant expressions
86;; evaluation feature:
87;;(autoload 'c-macro-eval "cmacexp"
88;; "C constant expressions evaluation. Requires calc. Experimental." t)
89 72
90;; BUG REPORTS ======================================================= 73;; BUG REPORTS =======================================================
91 74
@@ -108,31 +91,29 @@
108;; ACKNOWLEDGEMENTS ================================================== 91;; ACKNOWLEDGEMENTS ==================================================
109 92
110;; A lot of thanks to Don Maszle who did a great work of testing, bug 93;; A lot of thanks to Don Maszle who did a great work of testing, bug
111;; reporting and suggestion of new features and to Dave Gillespie for 94;; reporting and suggestion of new features and to Inge Fricks for her
112;; his suggestions about calc. This work has been partially inspired by 95;; help with view.el. This work has been partially inspired by Don
113;; Don Maszle and Jonathan Segal's. 96;; Maszle and Jonathan Segal's.
114 97
115;; BUGS ============================================================== 98;; By the way, I recommend you Inge Frick's view.el. It works like
99;; the standard view, but *it is not recursive* and has some more
100;; commands. Moreover it is a minor mode, so you preserve all your
101;; major mode keybindings (well, not always :). Mail me to obtain a
102;; copy, or get it by anonymous ftp in fly.cnuce.cnr.it:pub/view.el.
116 103
117;; calc 2.02 does not handle the C operators "->", ".", "*" (as a 104;; BUGS ==============================================================
118;; prefix), the composite assignement operators "+=" etc. It cannot
119;; handle the "," operator and will be confused by ";". Almost all
120;; these can be defined as no-ops using the Calc's Syntax Tables
121;; feature. The built-in calc functions will cause problems in
122;; certain circumstances. c-macro-eval behaves correctly only on
123;; expressions not containing such operators. Does not distinguish
124;; among integer and real division.
125 105
126;; If the start point of the region is inside a macro definition the 106;; If the start point of the region is inside a macro definition the
127;; macro expansion is often inaccurate. 107;; macro expansion is often inaccurate.
128 108
129;;; Code: 109
110(provide 'cmacexp)
130 111
131(defvar c-macro-shrink-window-p nil 112(defvar c-macro-shrink-window-p nil
132 "*Non-nil means shrink the *Macroexpansion* window to fit its contents.") 113 "*Non-nil means shrink the *Macroexpansion* window to fit its contents.")
133 114
134(defvar c-macro-always-prompt-p nil 115(defvar c-macro-prompt-p nil
135 "*Non-nil means always prompt for preprocessor arguments.") 116 "*Non-nil makes c-macro-expand prompt for preprocessor arguments.")
136 117
137(defvar c-macro-preprocessor "/lib/cpp -C" "\ 118(defvar c-macro-preprocessor "/lib/cpp -C" "\
138The preprocessor used by the cmacexp package. 119The preprocessor used by the cmacexp package.
@@ -140,33 +121,37 @@ The preprocessor used by the cmacexp package.
140If you change this, be sure to preserve the -C (don't strip comments) 121If you change this, be sure to preserve the -C (don't strip comments)
141option, or to set an equivalent one.") 122option, or to set an equivalent one.")
142 123
143(defvar c-macro-default-cppflags "" 124(defvar c-macro-cppflags ""
144 "Default cpp flags used by c-macro-expand.") 125 "*Preprocessor flags used by c-macro-expand.")
145 126
146(defconst c-macro-buffer-name "*Macroexpansion*") 127(defconst c-macro-buffer-name "*Macroexpansion*")
147 128
148(defun c-macro-expand (start end &optional flag) "\ 129(defun c-macro-expand (start end subst) "\
149Expand all C macros occurring in the region using c-macro-preprocessor. 130Expand all C macros occurring in the region using c-macro-preprocessor.
150Normally display output in temp buffer. 131Normally display output in temp buffer.
151Prefix arg means replace the region with it. 132Prefix arg means replace the region with it.
152Prompt for a string of arguments to the preprocessor, (e.g. 133Prompt for a string of arguments to the preprocessor
153-DDEBUG -I ./include) when prefixed with two C-u's. 134\(e.g. -DDEBUG -I ./include) if the user option c-macro-prompt-p is non-nil.
154 135
155It is intended for interactive use only. 136Noninteractive args are START, END, SUBST.
156For non interactive use, see the c-macro-expansion function." 137For use inside programs see also c-macro-expansion."
157 138
158 (interactive "r\nP") 139 (interactive "r\nP")
159 (let* ((subst (and flag (not (equal flag '(16))))) 140 (let ((inbuf (current-buffer))
160 (inbuf (current-buffer)) 141 (displaybuf (if subst
161 (displaybuf (if subst 142 (get-buffer c-macro-buffer-name)
162 (get-buffer c-macro-buffer-name) 143 (get-buffer-create c-macro-buffer-name)))
163 (get-buffer-create c-macro-buffer-name))) 144 (expansion "")
164 (expansion "")) 145 (mymsg ""))
165 ;; Build the command string. 146 ;; Build the command string.
166 (if (or c-macro-always-prompt-p (equal flag '(16))) 147 (if c-macro-prompt-p
167 (setq c-macro-default-cppflags 148 (setq c-macro-cppflags
168 (read-string "Preprocessor arguments: " 149 (read-string "Preprocessor arguments: "
169 c-macro-default-cppflags))) 150 c-macro-cppflags)))
151 (setq mymsg (format "Invoking %s%s%s on region..."
152 c-macro-preprocessor
153 (if (string= "" c-macro-cppflags) "" " ")
154 c-macro-cppflags))
170 ;; Decide where to display output. 155 ;; Decide where to display output.
171 (if (and subst 156 (if (and subst
172 (and buffer-read-only (not inhibit-read-only)) 157 (and buffer-read-only (not inhibit-read-only))
@@ -179,12 +164,11 @@ For non interactive use, see the c-macro-expansion function."
179 (or displaybuf 164 (or displaybuf
180 (setq displaybuf (get-buffer-create c-macro-buffer-name))))) 165 (setq displaybuf (get-buffer-create c-macro-buffer-name)))))
181 ;; Expand the macro and output it. 166 ;; Expand the macro and output it.
182 (if (interactive-p) (message (c-macro-default-message))) 167 (message mymsg)
183 (setq expansion 168 (setq expansion (c-macro-expansion start end
184 (c-macro-expansion start end 169 (concat c-macro-preprocessor " "
185 (concat c-macro-preprocessor " " 170 c-macro-cppflags)))
186 c-macro-default-cppflags))) 171 (message (concat mymsg "done"))
187 (message (concat (c-macro-default-message) "done"))
188 (if subst 172 (if subst
189 (let ((exchange (= (point) start))) 173 (let ((exchange (= (point) start)))
190 (delete-region start end) 174 (delete-region start end)
@@ -199,16 +183,16 @@ For non interactive use, see the c-macro-expansion function."
199 (set-buffer-modified-p nil) 183 (set-buffer-modified-p nil)
200 (if (string= "" expansion) 184 (if (string= "" expansion)
201 (message "Null expansion") 185 (message "Null expansion")
202 (c-macro-display-buffer inbuf)) 186 (c-macro-display-buffer))
203 (setq buffer-read-only t) 187 (setq buffer-read-only t)
188 (setq buffer-auto-save-file-name nil)
204 (bury-buffer displaybuf)))) 189 (bury-buffer displaybuf))))
205 190
206 191
207;; Display the current buffer in a window which is either just large 192;; Display the current buffer in a window which is either just large
208;; enough to contain the entire buffer, or half the size of the 193;; enough to contain the entire buffer, or half the size of the
209;; screen, whichever is smaller. Put the current buffer in view-mode 194;; screen, whichever is smaller. Do not select the new
210;; if the Inge Frick's view-mode is installed, with buffer to return 195;; window.
211;; to set to RETBUF (if sensible). Do not select the new window.
212;; 196;;
213;; Several factors influence window resizing so that the window is 197;; Several factors influence window resizing so that the window is
214;; sized optimally if it is created anew, and so that it is messed 198;; sized optimally if it is created anew, and so that it is messed
@@ -218,7 +202,7 @@ For non interactive use, see the c-macro-expansion function."
218;; buffer, it is never shrunk, but possibly expanded. Finally, if the 202;; buffer, it is never shrunk, but possibly expanded. Finally, if the
219;; variable c-macro-shrink-window-p is nil the window size is *never* 203;; variable c-macro-shrink-window-p is nil the window size is *never*
220;; changed. 204;; changed.
221(defun c-macro-display-buffer (retbuf) 205(defun c-macro-display-buffer ()
222 206
223 (goto-char (point-min)) 207 (goto-char (point-min))
224 (c-mode) 208 (c-mode)
@@ -244,17 +228,17 @@ For non interactive use, see the c-macro-expansion function."
244 (setq maxheight (/ (screen-height) 2)) 228 (setq maxheight (/ (screen-height) 2))
245 (enlarge-window (- (min maxheight 229 (enlarge-window (- (min maxheight
246 (max minheight 230 (max minheight
247 (+ 2 (vertical-motion 1000000)))) 231 (+ 2 (vertical-motion (point-max)))))
248 (window-height))) 232 (window-height)))
249 (goto-char (point-min)) 233 (goto-char (point-min))
250 (select-window oldwin)))))) 234 (select-window oldwin))))))
251 235
252 236
253(defun c-macro-expansion (start end cppcommand) "\ 237(defun c-macro-expansion (start end cppcommand) "\
254Expands the region between START and END in the current buffer using 238Run a preprocessor on region and return the output as a string.
255the shell command CPPCOMMAND (e.g. \"/lib/cpp -C -DDEBUG\"). Be sure 239Expand the region between START and END in the current buffer using
256to use a -C (don't strip comments) or equivalent option. 240the shell command CPPCOMMAND (e.g. \"/lib/cpp -C -DDEBUG\").
257Returns the output as a string." 241Be sure to use a -C (don't strip comments) or equivalent option."
258 242
259;; Copy the current buffer's contents to a temporary hidden buffer. 243;; Copy the current buffer's contents to a temporary hidden buffer.
260;; Delete from END to end of buffer. Insert a preprocessor #line 244;; Delete from END to end of buffer. Insert a preprocessor #line
@@ -305,7 +289,7 @@ Returns the output as a string."
305 ;comment nor after quote 289 ;comment nor after quote
306 (progn 290 (progn
307 (goto-char (match-end 0)) 291 (goto-char (match-end 0))
308;; (setq linenum (count-lines 1 (point))) 292;;; (setq linenum (count-lines 1 (point)))
309 (setq linelist 293 (setq linelist
310 ;; This used to be a #line command 294 ;; This used to be a #line command
311 ;; but it's not guaranteed that the output 295 ;; but it's not guaranteed that the output
@@ -330,9 +314,11 @@ Returns the output as a string."
330 (startincomment (nth 4 startstat)) 314 (startincomment (nth 4 startstat))
331 (startafterquote (nth 5 startstat))) 315 (startafterquote (nth 5 startstat)))
332 (concat (if startafterquote " ") 316 (concat (if startafterquote " ")
333 (cond (startinstring "\"") (startincomment "*/")) 317 (cond (startinstring (char-to-string startinstring))
318 (startincomment "*/"))
334 (format "\n???!!!???!!!!") 319 (format "\n???!!!???!!!!")
335 (cond (startinstring "\"") (startincomment "/*")) 320 (cond (startinstring (char-to-string startinstring))
321 (startincomment "/*"))
336 (if startafterquote "\\"))) 322 (if startafterquote "\\")))
337 linelist)) 323 linelist))
338 (insert (car linelist)) 324 (insert (car linelist))
@@ -353,91 +339,4 @@ Returns the output as a string."
353 ;; Cleanup. 339 ;; Cleanup.
354 (kill-buffer outbuf)))) 340 (kill-buffer outbuf))))
355 341
356 342;;; cmacexp.el ends here
357;; Experimental. With an argument, print signed, unsigned, hex and
358;; boolean representations.
359(defun c-macro-eval (start end &optional flag) "\
360Expand region using cpp and evaluate it using calc.
361Interactively print value in minibuffer and push it on the kill ring.
362With a C-u argument shows the evaluation in a variety of formats.
363With two C-u's prompts the user for a string of flags to the preprocessor.
364
365Non interactively returns value of region between START and END
366as a string. Several formats are used if optional FLAG is non-nil."
367
368 (interactive "r\nP")
369 (or (fboundp 'calc-eval)
370 (require 'calc))
371 (if (or c-macro-always-prompt-p (equal flag '(16)))
372 (setq c-macro-default-cppflags
373 (read-string "Preprocessor arguments: "
374 c-macro-default-cppflags)))
375
376 ;; Expand the region.
377 (if (interactive-p) (message (c-macro-default-message)))
378 (let ((evaluation
379 (c-macro-expansion start end
380 (concat c-macro-preprocessor " "
381 c-macro-default-cppflags)))
382 (evalbuf (get-buffer-create " *Macro Evaluation*")))
383 (unwind-protect
384 (save-excursion
385 (set-buffer evalbuf)
386 (setq buffer-read-only nil)
387 (erase-buffer)
388 (insert evaluation)
389
390 ;; Evaluate expression(s).
391 (if (interactive-p)
392 (message "Invoking calc..."))
393 (setq evaluation
394 (let ((calc-eval-error t))
395 (calc-eval (list (buffer-string) 'calc-language 'c))))
396 (erase-buffer)
397 (cond
398 (flag
399 (insert (calc-eval (list evaluation
400 'calc-language 'c
401 'calc-simplify-mode 'binary))
402 "(u)" " == "
403 (calc-eval (list evaluation
404 'calc-language 'c
405 'calc-word-size (- calc-word-size)
406 'calc-simplify-mode 'binary))
407 "(d)" " == "
408 (calc-eval (list evaluation
409 'calc-language 'c
410 'calc-number-radix 16
411 'calc-simplify-mode 'binary))
412 "(x)")
413 (save-excursion
414 (insert " == " (calc-eval (list evaluation
415 'calc-language 'c
416 'calc-number-radix 16
417 'calc-simplify-mode 'binary))))
418 (while (re-search-forward "0x\\([^,]+\\)\\(, \\|\\'\\)" nil t)
419 (if (string= "0"
420 (buffer-substring (match-beginning 1)
421 (match-end 1)))
422 (replace-match "FALSE\\2")
423 (replace-match "TRUE\\2"))))
424 (t
425 (insert evaluation)))
426
427 ;; Output the evaluation.
428 (if (interactive-p)
429 (progn
430 (copy-region-as-kill 1 (point-max))
431 (message (buffer-string)))
432 (buffer-string)))
433 (kill-buffer evalbuf))))
434
435(defun c-macro-default-message ()
436 (format "Invoking %s%s%s on region..."
437 c-macro-preprocessor
438 (if (string= "" c-macro-default-cppflags) "" " ")
439 c-macro-default-cppflags))
440
441(provide 'cmacexp)
442
443;;; cmacexp.el ends here.