X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/074521be7ec6efd83c943f4339bc14c5dc43de3a..5988691b0425d1952aa32734ee4eb0fb8341faf9:/lisp/progmodes/cmacexp.el diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el index 76b86e2474..27fe81e451 100644 --- a/lisp/progmodes/cmacexp.el +++ b/lisp/progmodes/cmacexp.el @@ -1,9 +1,8 @@ ;;; cmacexp.el --- expand C macros in a region -;; Copyright (C) 1992 Free Software Foundation, Inc. +;; Copyright (C) 1992, 1994, 1996, 2000 Free Software Foundation, Inc. -;; Author: Francesco Potorti` -;; Version: $Id: cmacexp.el 1.14 1994/04/20 15:50:48 pot Exp $ +;; Author: Francesco Potorti` ;; Adapted-By: ESR ;; Keywords: c @@ -20,8 +19,11 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: ;; USAGE ============================================================= @@ -45,7 +47,7 @@ ;; Put the following in your ~/.emacs file. ;; If you want the *Macroexpansion* window to be not higher than -;; necessary: +;; necessary: ;;(setq c-macro-shrink-window-flag t) ;; ;; If you use a preprocessor other than /lib/cpp (be careful to set a @@ -62,11 +64,11 @@ ;; BUG REPORTS ======================================================= ;; Please report bugs, suggestions, complaints and so on to -;; pot@cnuce.cnr.it (Francesco Potorti`). +;; pot@gnu.org (Francesco Potorti`). ;; IMPROVEMENTS OVER emacs 18.xx cmacexp.el ========================== -;; - A lot of user visible changes. See above. +;; - A lot of user and programmer visible changes. See above. ;; - #line directives are inserted, so __LINE__ and __FILE__ are ;; correctly expanded. Works even with START inside a string, a ;; comment or a region #ifdef'd away by cpp. cpp is invoked with -C, @@ -84,26 +86,54 @@ ;; If the start point of the region is inside a macro definition the ;; macro expansion is often inaccurate. +;;; Code: -(provide 'cmacexp) - -(defvar c-macro-shrink-window-flag nil - "*Non-nil means shrink the *Macroexpansion* window to fit its contents.") +(require 'cc-mode) -(defvar c-macro-prompt-flag nil - "*Non-nil makes `c-macro-expand' prompt for preprocessor arguments.") +(provide 'cmacexp) -(defvar c-macro-preprocessor "/lib/cpp -C" +(defgroup c-macro nil + "Expand C macros in a region." + :group 'c) + + +(defcustom c-macro-shrink-window-flag nil + "*Non-nil means shrink the *Macroexpansion* window to fit its contents." + :type 'boolean + :group 'c-macro) + +(defcustom c-macro-prompt-flag nil + "*Non-nil makes `c-macro-expand' prompt for preprocessor arguments." + :type 'boolean + :group 'c-macro) + +(defcustom c-macro-preprocessor + ;; Cannot rely on standard directory on MS-DOS to find CPP. In + ;; fact, cannot rely on having cpp.exe, either, in latest GCC + ;; versions. + (cond ((eq system-type 'ms-dos) "gcc -E -C -o - -") + ;; Solaris has it in an unusual place. + ((and (string-match "^[^-]*-[^-]*-\\(solaris\\|sunos5\\)" + system-configuration) + (file-exists-p "/opt/SUNWspro/SC3.0.1/bin/acomp")) + "/opt/SUNWspro/SC3.0.1/bin/acomp -C -E") + ((file-exists-p "/usr/ccs/lib/cpp") "/usr/ccs/lib/cpp -C") + (t "/lib/cpp -C")) "The preprocessor used by the cmacexp package. -If you change this, be sure to preserve the -C (don't strip comments) -option, or to set an equivalent one.") +If you change this, be sure to preserve the `-C' (don't strip comments) +option, or to set an equivalent one." + :type 'string + :group 'c-macro) -(defvar c-macro-cppflags "" - "*Preprocessor flags used by c-macro-expand.") +(defcustom c-macro-cppflags "" + "*Preprocessor flags used by `c-macro-expand'." + :type 'string + :group 'c-macro) (defconst c-macro-buffer-name "*Macroexpansion*") +;;;###autoload (defun c-macro-expand (start end subst) "Expand C macros in the region, using the C preprocessor. Normally display output in temp buffer, but @@ -150,7 +180,7 @@ For use inside Lisp programs, see also `c-macro-expansion'." (exchange-point-and-mark))) (set-buffer displaybuf) (setq buffer-read-only nil) - (buffer-flush-undo displaybuf) + (buffer-disable-undo displaybuf) (erase-buffer) (insert expansion) (set-buffer-modified-p nil) @@ -181,7 +211,7 @@ For use inside Lisp programs, see also `c-macro-expansion'." (let ((oldwinheight (window-height)) (alreadythere ;the window was already there (get-buffer-window (current-buffer))) - (popped nil)) ;the window popped changing the layout + (popped nil)) ;the window popped changing the layout (or alreadythere (progn (display-buffer (current-buffer) t) @@ -197,7 +227,7 @@ For use inside Lisp programs, see also `c-macro-expansion'." (setq minheight (if alreadythere (window-height) window-min-height)) - (setq maxheight (/ (screen-height) 2)) + (setq maxheight (/ (frame-height) 2)) (enlarge-window (- (min maxheight (max minheight (+ 2 (vertical-motion (point-max))))) @@ -223,7 +253,7 @@ Optional arg DISPLAY non-nil means show messages in the echo area." ;; Preprocess the buffer contents, then look for all the lines stored ;; in linelist starting from end of buffer. The last line so found is ;; where START was, so return the substring from point to end of -;; buffer. +;; buffer. (let ((inbuf (current-buffer)) (outbuf (get-buffer-create " *C Macro Expansion*")) (filename (if (and buffer-file-name @@ -235,25 +265,31 @@ Optional arg DISPLAY non-nil means show messages in the echo area." c-macro-preprocessor (if (string= "" c-macro-cppflags) "" " ") c-macro-cppflags)) - (uniquestring "???!!!???!!! start of c-macro expansion ???!!!???!!!") + (uniquestring "??? !!! ??? start of c-macro expansion ??? !!! ???") (startlinenum 0) (linenum 0) (startstat ()) - (startmarker "")) + (startmarker "") + (exit-status 0) + (tempname (make-temp-file + (expand-file-name "cmacexp" + (or small-temporary-file-directory + temporary-file-directory))))) (unwind-protect (save-excursion (save-restriction (widen) - (set-buffer outbuf) - (setq buffer-read-only nil) - (erase-buffer) - (set-syntax-table c-mode-syntax-table) + (let ((in-syntax-table (syntax-table))) + (set-buffer outbuf) + (setq buffer-read-only nil) + (erase-buffer) + (set-syntax-table in-syntax-table)) (insert-buffer-substring inbuf 1 end)) ;; We have copied inbuf to outbuf. Point is at end of - ;; outbuf. Insert a space at the end, so cpp can correctly - ;; parse a token ending at END. - (insert " ") + ;; outbuf. Inset a newline at the end, so cpp can correctly + ;; parse a token ending at END. + (insert "\n") ;; Save sexp status and line number at START. (setq startstat (parse-partial-sexp 1 start)) @@ -289,26 +325,31 @@ Optional arg DISPLAY non-nil means show messages in the echo area." (char-to-string startinstring)) (startincomment "*/") ("")) - (format "\n#line %d \"%s\"\n" startlinenum filename) (setq startmarker - (concat uniquestring + (concat "\n" uniquestring (cond (startinstring (char-to-string startinstring)) (startincomment "/*") (startinbcomment "//")) - (if startafterquote "\\"))))) + (if startafterquote "\\"))) + (format "\n#line %d \"%s\"\n" startlinenum filename))) ;; Call the preprocessor. (if display (message mymsg)) - (call-process-region 1 (point-max) "sh" t t nil "-c" - (concat cppcommand " 2>/dev/null")) + (setq exit-status + (call-process-region 1 (point-max) + shell-file-name + t (list t tempname) nil "-c" + cppcommand)) (if display (message (concat mymsg "done"))) - - ;; Find and delete the mark of the start of the expansion. - ;; Look for `# nn "file.c"' lines and delete them. - (goto-char (point-min)) - (search-forward startmarker) - (delete-region 1 (point)) + (if (= (buffer-size) 0) + ;; Empty output is normal after a fatal error. + (insert "\nPreprocessor produced no output\n") + ;; Find and delete the mark of the start of the expansion. + ;; Look for `# nn "file.c"' lines and delete them. + (goto-char (point-min)) + (search-forward startmarker) + (delete-region 1 (point))) (while (re-search-forward (concat "^# [0-9]+ \"" (regexp-quote filename) "\"") nil t) @@ -317,6 +358,28 @@ Optional arg DISPLAY non-nil means show messages in the echo area." (forward-line 1) (delete-region beg (point)))) + ;; If CPP got errors, show them at the beginning. + ;; MS-DOS shells don't return the exit code of their children. + ;; Look at the size of the error message file instead, but + ;; don't punish those MS-DOS users who have a shell that does + ;; return an error code. + (or (and (or (not (boundp 'msdos-shells)) + (not (member (file-name-nondirectory shell-file-name) + msdos-shells))) + (eq exit-status 0)) + (zerop (nth 7 (file-attributes (expand-file-name tempname)))) + (progn + (goto-char (point-min)) + ;; Put the messages inside a comment, so they won't get in + ;; the way of font-lock, highlighting etc. + (insert + (format "/* Preprocessor terminated with status %s\n\n Messages from `%s\':\n\n" + exit-status cppcommand)) + (goto-char (+ (point) + (nth 1 (insert-file-contents tempname)))) + (insert "\n\n*/\n"))) + (delete-file tempname) + ;; Compute the return value, keeping in account the space ;; inserted at the end of the buffer. (buffer-substring 1 (max 1 (- (point-max) 1)))) @@ -324,4 +387,5 @@ Optional arg DISPLAY non-nil means show messages in the echo area." ;; Cleanup. (kill-buffer outbuf)))) +;;; arch-tag: 4f20253c-71ef-4e6d-a774-19087060910e ;;; cmacexp.el ends here