X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d733c5ec034baf089cdc50bc79b919897ab98bec..8d9cc0b7ea1893059df8788129998e9a71ec07f3:/lisp/progmodes/cmacexp.el diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el index 6c615c4d99..4722f0ca4a 100644 --- a/lisp/progmodes/cmacexp.el +++ b/lisp/progmodes/cmacexp.el @@ -1,9 +1,9 @@ ;;; cmacexp.el --- expand C macros in a region -;; Copyright (C) 1992, 1994 Free Software Foundation, Inc. +;; Copyright (C) 1992, 1994, 1996, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +;; Free Software Foundation, Inc. -;; Author: Francesco Potorti` -;; Version: $Id: cmacexp.el,v 1.13 1994/04/21 18:40:14 rms Exp kwzh $ +;; Author: Francesco Potorti` ;; Adapted-By: ESR ;; Keywords: c @@ -11,7 +11,7 @@ ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) +;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, @@ -20,8 +20,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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: ;; USAGE ============================================================= @@ -45,7 +48,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 +65,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,34 +87,72 @@ ;; 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" +(defvar msdos-shells) + + +(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 + (cond ;; 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") + ((locate-file "/usr/ccs/lib/cpp" + '("/") exec-suffixes 'file-executable-p) + "/usr/ccs/lib/cpp -C") + ((locate-file "/lib/cpp" + '("/") exec-suffixes 'file-executable-p) + "/lib/cpp -C") + ;; On some systems, we cannot rely on standard directories to + ;; find CPP. In fact, we cannot rely on having cpp, either, + ;; in some GCC versions. + ((locate-file "cpp" exec-path exec-suffixes 'file-executable-p) + "cpp -C") + (t "gcc -E -C -o - -")) "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 prefix arg means replace the region with it. `c-macro-preprocessor' specifies the preprocessor to use. -Prompt for arguments to the preprocessor \(e.g. `-DDEBUG -I ./include') -if the user option `c-macro-prompt-flag' is non-nil. +Tf the user option `c-macro-prompt-flag' is non-nil +prompt for arguments to the preprocessor \(e.g. `-DDEBUG -I ./include'), +otherwise use `c-macro-cppflags'. Noninteractive args are START, END, SUBST. For use inside Lisp programs, see also `c-macro-expansion'." @@ -150,7 +191,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 +222,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 +238,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 +264,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 +276,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 +336,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")) - (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 display (message "%s" mymsg)) + (setq exit-status + (call-process-region 1 (point-max) + shell-file-name + t (list t tempname) nil "-c" + cppcommand)) + (if display (message "%s" (concat mymsg "done"))) + (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 +369,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 +398,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