Mercurial > emacs
comparison lisp/progmodes/mantemp.el @ 16878:ffc3290d43bf
Initial revision
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 19 Jan 1997 00:47:24 +0000 |
parents | |
children | b020aae1fa01 |
comparison
equal
deleted
inserted
replaced
16877:f9d43993ed5a | 16878:ffc3290d43bf |
---|---|
1 ;;; mantemp.el --- Create manual template instantiations from g++ 2.7.2 output. | |
2 | |
3 ;; Copyright (C) 1996 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Tom Houlder <thoulder@icor.fr> | |
6 ;; Created: 10 Dec 1996 | |
7 ;; Keywords: g++, templates | |
8 | |
9 ;; This file is part of GNU Emacs. | |
10 | |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published | |
13 ;; by the Free Software Foundation; either version 2, or (at your | |
14 ;; option) any later version. | |
15 | |
16 ;; GNU Emacs is distributed in the hope that it will be useful, but | |
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 ;; General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
24 ;; Boston, MA 02111-1307, USA. | |
25 | |
26 ;;; Commentary: | |
27 | |
28 ;; The following is a typical error message from g++ using STL (here | |
29 ;; with split lines): | |
30 ;; | |
31 ;; AFile.o(.text+0x2d5): undefined reference to | |
32 ;; `vector<double>::begin(void)' | |
33 ;; AFile.o(.text+0x2e7): undefined reference to | |
34 ;; `vector<double>::insert(double *, unsigned int, double const &)' | |
35 ;; AnotherFile.o(.text+0x226b8): undefined reference to | |
36 ;; `operator!=(rb_tree<basic_string<char>, pair<basic_string<char> | |
37 ;; const, AClass *>, select1st<pair<basic_string<char> const, AClass | |
38 ;; *>, basic_string<char> >, less<basic_string<char> > >::iterator | |
39 ;; const &, rb_tree<basic_string<char>, pair<basic_string<char> | |
40 ;; const, AClass *>, select1st<pair<basic_string<char> const, AClass | |
41 ;; *>, basic_string<char> >, less<basic_string<char> > >::iterator | |
42 ;; const &)' | |
43 ;; | |
44 ;; The message means that in the object file AFile.o there is one | |
45 ;; uninstantiated template class, vector<double>, and in AnotherFile.o | |
46 ;; there is one uninstantiated template function, operator!=(...). To | |
47 ;; turn this output into manual template instantiations, copy from the | |
48 ;; first name of an objective file (here this is AFile.o) to right | |
49 ;; after the very last `'' of the output. Put this in a buffer and | |
50 ;; call mantemp-make-mantemps-buffer with the point in the buffer. | |
51 ;; You can also use mantemp-make-mantemps-region directly on the | |
52 ;; region if the output is already in Emacs. | |
53 ;; | |
54 ;; The resulting buffer yields (connect the three output lines above | |
55 ;; if you want to try): | |
56 ;; | |
57 ;; template operator!=(rb_tree<basic_string<char>, | |
58 ;; pair<basic_string<char> const, AClass *>, | |
59 ;; select1st<pair<basic_string<char> const, AClass *>, | |
60 ;; basic_string<char> >, less<basic_string<char> > >::iterator const | |
61 ;; &, rb_tree<basic_string<char>, pair<basic_string<char> const, | |
62 ;; AClass *>, select1st<pair<basic_string<char> const, AClass *>, | |
63 ;; basic_string<char> >, less<basic_string<char> > >::iterator const | |
64 ;; &); | |
65 ;; template class vector<double>; | |
66 ;; | |
67 ;; which can be included in your C++ program. However, its probably | |
68 ;; better to include the necessary header files in the buffer and | |
69 ;; compile it as a stand alone implementation file. | |
70 | |
71 ;; g++ does not output the templates that are needed by the | |
72 ;; uninstantiated templates. Therefore you will often get new error | |
73 ;; messages after the first instantiations have been included and you | |
74 ;; must repeat the operation. | |
75 | |
76 ;;; Code: | |
77 | |
78 (defun mantemp-remove-comments () | |
79 "Remove g++ comments surrounding each function and member function." | |
80 (save-excursion | |
81 (goto-char (point-min)) | |
82 (message "Removing comments") | |
83 (while (re-search-forward "^[A-z\.()+0-9: ]*`\\|'.*$" nil t) | |
84 (replace-match "")))) | |
85 | |
86 (defun mantemp-remove-memfuncs () | |
87 "Remove member function extensions so that only class names remain." | |
88 (save-excursion | |
89 ;; Remove conversion operator extensions. | |
90 (goto-char (point-min)) | |
91 (message "Removing member function extensions") | |
92 (while (re-search-forward | |
93 "^[A-z :&*<>~=,0-9+]*>::operator " nil t nil) | |
94 (progn | |
95 (backward-char 11) | |
96 (kill-line))) | |
97 ;; Remove other member function extensions. | |
98 (goto-char (point-min)) | |
99 (message "Removing member function extensions") | |
100 (while (re-search-forward "^[A-z :&*<>~=,0-9+]*>::" nil t nil) | |
101 (progn | |
102 (backward-char 2) | |
103 (kill-line))))) | |
104 | |
105 (defun mantemp-sort-and-unique-lines () | |
106 "Eliminate all consecutive duplicate lines in the buffer." | |
107 (save-excursion | |
108 (message "Sorting") | |
109 (sort-regexp-fields nil "^.*$" "\\&" | |
110 (point-min) | |
111 (point-max)) | |
112 (goto-char (point-min)) | |
113 (message "Removing consecutive duplicate lines") | |
114 (while (re-search-forward "\\(^.+\\)\n\\1" nil t nil) | |
115 (progn | |
116 (forward-line -1) | |
117 (beginning-of-line) | |
118 (kill-line 1))))) | |
119 | |
120 (defun mantemp-insert-cxx-syntax () | |
121 "Insert C++ syntax around each template class and function. | |
122 Insert 'template class' for classes, 'template' for | |
123 functions and add the statement delimiter `;' at the end of | |
124 the lines." | |
125 (save-excursion | |
126 ;; Insert ';' at the end of each nonempty line. | |
127 (goto-char (point-min)) | |
128 (message "Inserting `;' at the ends") | |
129 (while (re-search-forward ".+$" nil t) | |
130 (progn | |
131 (insert ";") | |
132 (if (not (equal (point) (point-max))) | |
133 (forward-char)))) | |
134 ;; We first insert 'template class' at each nonempty line and | |
135 ;; subsequently remove 'class' for functions so we don't need to | |
136 ;; both scan for classes and functions. | |
137 (goto-char (point-min)) | |
138 (message "Inserting 'template class' for classes") | |
139 (while (re-search-forward "^.+" nil t) | |
140 (progn | |
141 (beginning-of-line) | |
142 (insert "template class "))) | |
143 (goto-char (point-min)) | |
144 (message "Inserting 'template' for functions") | |
145 (while (re-search-forward | |
146 "^template class [A-z :&*<>~=,0-9+!]*(" nil t nil) | |
147 (progn | |
148 (beginning-of-line) | |
149 (forward-word 1) | |
150 (kill-word 1))))) | |
151 | |
152 (defun mantemp-make-mantemps () | |
153 "Gathering interface to the functions modifying the buffer." | |
154 (mantemp-remove-comments) | |
155 (mantemp-remove-memfuncs) | |
156 (mantemp-sort-and-unique-lines) | |
157 (mantemp-insert-cxx-syntax)) | |
158 | |
159 (defun mantemp-make-mantemps-buffer () | |
160 "Make manual template instantiations from g++ error messages in the buffer. | |
161 Scan the output of g++ describing uninstantiated template | |
162 classes and functions and generate the corresponding C++ | |
163 manual template instantiations. The output is supposed to | |
164 have been placed in the current buffer and the current buffer | |
165 should otherwise be empty. | |
166 | |
167 See the commentary in file mantemp.el for an example of use." | |
168 (interactive) | |
169 (mantemp-make-mantemps) | |
170 (message "mantemp-make-mantemps-buffer is done")) | |
171 | |
172 (defun mantemp-make-mantemps-region () | |
173 "Make manual template instantiations from g++ error messages in the region. | |
174 This function does the same as | |
175 'mantemp-make-mantemps-buffer' but operates on the region." | |
176 (interactive) | |
177 (let ((cur-buf (current-buffer)) | |
178 (mantemp-buffer (generate-new-buffer "*mantemp*"))) | |
179 ;; Copy the region to a temporary buffer, make the C++ code there | |
180 ;; and copy the result back to the current buffer. | |
181 (kill-region (mark) (point)) | |
182 (set-buffer mantemp-buffer) | |
183 (yank) | |
184 (mantemp-make-mantemps) | |
185 (kill-region (point-min) (point-max)) | |
186 (set-buffer cur-buf) | |
187 (yank) | |
188 (kill-buffer mantemp-buffer)) | |
189 (message "mantemp-make-mantemps-region is done")) | |
190 | |
191 (provide 'mantemp) | |
192 | |
193 ;;; mantemp.el ends here |