Mercurial > emacs
changeset 16878:ffc3290d43bf
Initial revision
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 19 Jan 1997 00:47:24 +0000 |
parents | f9d43993ed5a |
children | b020aae1fa01 |
files | lisp/progmodes/mantemp.el |
diffstat | 1 files changed, 193 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/progmodes/mantemp.el Sun Jan 19 00:47:24 1997 +0000 @@ -0,0 +1,193 @@ +;;; mantemp.el --- Create manual template instantiations from g++ 2.7.2 output. + +;; Copyright (C) 1996 Free Software Foundation, Inc. + +;; Author: Tom Houlder <thoulder@icor.fr> +;; Created: 10 Dec 1996 +;; Keywords: g++, templates + +;; This file is part of GNU Emacs. + +;; 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) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The following is a typical error message from g++ using STL (here +;; with split lines): +;; +;; AFile.o(.text+0x2d5): undefined reference to +;; `vector<double>::begin(void)' +;; AFile.o(.text+0x2e7): undefined reference to +;; `vector<double>::insert(double *, unsigned int, double const &)' +;; AnotherFile.o(.text+0x226b8): undefined reference to +;; `operator!=(rb_tree<basic_string<char>, pair<basic_string<char> +;; const, AClass *>, select1st<pair<basic_string<char> const, AClass +;; *>, basic_string<char> >, less<basic_string<char> > >::iterator +;; const &, rb_tree<basic_string<char>, pair<basic_string<char> +;; const, AClass *>, select1st<pair<basic_string<char> const, AClass +;; *>, basic_string<char> >, less<basic_string<char> > >::iterator +;; const &)' +;; +;; The message means that in the object file AFile.o there is one +;; uninstantiated template class, vector<double>, and in AnotherFile.o +;; there is one uninstantiated template function, operator!=(...). To +;; turn this output into manual template instantiations, copy from the +;; first name of an objective file (here this is AFile.o) to right +;; after the very last `'' of the output. Put this in a buffer and +;; call mantemp-make-mantemps-buffer with the point in the buffer. +;; You can also use mantemp-make-mantemps-region directly on the +;; region if the output is already in Emacs. +;; +;; The resulting buffer yields (connect the three output lines above +;; if you want to try): +;; +;; template operator!=(rb_tree<basic_string<char>, +;; pair<basic_string<char> const, AClass *>, +;; select1st<pair<basic_string<char> const, AClass *>, +;; basic_string<char> >, less<basic_string<char> > >::iterator const +;; &, rb_tree<basic_string<char>, pair<basic_string<char> const, +;; AClass *>, select1st<pair<basic_string<char> const, AClass *>, +;; basic_string<char> >, less<basic_string<char> > >::iterator const +;; &); +;; template class vector<double>; +;; +;; which can be included in your C++ program. However, its probably +;; better to include the necessary header files in the buffer and +;; compile it as a stand alone implementation file. + +;; g++ does not output the templates that are needed by the +;; uninstantiated templates. Therefore you will often get new error +;; messages after the first instantiations have been included and you +;; must repeat the operation. + +;;; Code: + +(defun mantemp-remove-comments () + "Remove g++ comments surrounding each function and member function." + (save-excursion + (goto-char (point-min)) + (message "Removing comments") + (while (re-search-forward "^[A-z\.()+0-9: ]*`\\|'.*$" nil t) + (replace-match "")))) + +(defun mantemp-remove-memfuncs () + "Remove member function extensions so that only class names remain." + (save-excursion + ;; Remove conversion operator extensions. + (goto-char (point-min)) + (message "Removing member function extensions") + (while (re-search-forward + "^[A-z :&*<>~=,0-9+]*>::operator " nil t nil) + (progn + (backward-char 11) + (kill-line))) + ;; Remove other member function extensions. + (goto-char (point-min)) + (message "Removing member function extensions") + (while (re-search-forward "^[A-z :&*<>~=,0-9+]*>::" nil t nil) + (progn + (backward-char 2) + (kill-line))))) + +(defun mantemp-sort-and-unique-lines () + "Eliminate all consecutive duplicate lines in the buffer." + (save-excursion + (message "Sorting") + (sort-regexp-fields nil "^.*$" "\\&" + (point-min) + (point-max)) + (goto-char (point-min)) + (message "Removing consecutive duplicate lines") + (while (re-search-forward "\\(^.+\\)\n\\1" nil t nil) + (progn + (forward-line -1) + (beginning-of-line) + (kill-line 1))))) + +(defun mantemp-insert-cxx-syntax () + "Insert C++ syntax around each template class and function. +Insert 'template class' for classes, 'template' for +functions and add the statement delimiter `;' at the end of +the lines." + (save-excursion + ;; Insert ';' at the end of each nonempty line. + (goto-char (point-min)) + (message "Inserting `;' at the ends") + (while (re-search-forward ".+$" nil t) + (progn + (insert ";") + (if (not (equal (point) (point-max))) + (forward-char)))) + ;; We first insert 'template class' at each nonempty line and + ;; subsequently remove 'class' for functions so we don't need to + ;; both scan for classes and functions. + (goto-char (point-min)) + (message "Inserting 'template class' for classes") + (while (re-search-forward "^.+" nil t) + (progn + (beginning-of-line) + (insert "template class "))) + (goto-char (point-min)) + (message "Inserting 'template' for functions") + (while (re-search-forward + "^template class [A-z :&*<>~=,0-9+!]*(" nil t nil) + (progn + (beginning-of-line) + (forward-word 1) + (kill-word 1))))) + +(defun mantemp-make-mantemps () + "Gathering interface to the functions modifying the buffer." + (mantemp-remove-comments) + (mantemp-remove-memfuncs) + (mantemp-sort-and-unique-lines) + (mantemp-insert-cxx-syntax)) + +(defun mantemp-make-mantemps-buffer () + "Make manual template instantiations from g++ error messages in the buffer. +Scan the output of g++ describing uninstantiated template +classes and functions and generate the corresponding C++ +manual template instantiations. The output is supposed to +have been placed in the current buffer and the current buffer +should otherwise be empty. + +See the commentary in file mantemp.el for an example of use." + (interactive) + (mantemp-make-mantemps) + (message "mantemp-make-mantemps-buffer is done")) + +(defun mantemp-make-mantemps-region () + "Make manual template instantiations from g++ error messages in the region. +This function does the same as +'mantemp-make-mantemps-buffer' but operates on the region." + (interactive) + (let ((cur-buf (current-buffer)) + (mantemp-buffer (generate-new-buffer "*mantemp*"))) + ;; Copy the region to a temporary buffer, make the C++ code there + ;; and copy the result back to the current buffer. + (kill-region (mark) (point)) + (set-buffer mantemp-buffer) + (yank) + (mantemp-make-mantemps) + (kill-region (point-min) (point-max)) + (set-buffer cur-buf) + (yank) + (kill-buffer mantemp-buffer)) + (message "mantemp-make-mantemps-region is done")) + +(provide 'mantemp) + +;;; mantemp.el ends here