e25f2e21d89a3e17d229501dc74b338331e47e1b
[emacsstuff.git] / cc-ide / cc-helper.el
1 ;;; cc-helper.el --- helper and generator functions for C++
2 ;;
3 ;; $Id$
4 ;;
5 ;; Copyright (C) 2000 Stefan Bund
6
7 ;; cc-helper.el is free software; you can redistribute it and/or
8 ;; modify it under the terms of the GNU General Public License as
9 ;; published by the Free Software Foundation; either version 2, or (at
10 ;; your option) any later version.
11
12 ;; cc-helper.el is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
16
17 ;;; Commentary:
18
19 ;;; Change-Log:
20
21 ;; $Log$
22 ;;
23
24 ;;; Variables:
25
26 (defvar c-max-def-column 95
27   "*Maximum length of generated argdef lines")
28
29 (defconst c-special-key "\\(static\\|virtual\\|friend\\|explicit\\)\\b")
30
31 ;;; Code:
32
33 (require 'cc-engine-2)
34 (require 'cc-vars)
35
36 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
37 ;; generators (functions generating new sourcecode)
38
39 (defun c-kill-special-keywords ()
40   ;; kill all keywords in c-special-key directly after point
41   (c-forward-syntactic-ws)
42   (while (looking-at c-special-key)
43     (delete-region (point) (match-end 1))
44     (delete-region (point) (progn (c-forward-syntactic-ws) (point)))))
45
46 (defun c-build-template-specs (templates cbuf)
47   ;; build temlate specs for TEMPLATES
48   (loop for template in templates
49         do (insert 
50             (save-excursion
51               (set-buffer cbuf)
52               (save-excursion
53                 (goto-char (car template))
54                 (concat "template <"
55                         (loop for arg in (c-parse-template-declaration)
56                               for sep = "" then ", "
57                               concat sep
58                               concat (progn
59                                        (buffer-substring-no-properties
60                                         (car arg) (if (c-move-to-initializer 
61                                                        (car arg) (cdr arg))
62                                                       (progn 
63                                                         (forward-char -1)
64                                                         (c-backward-syntactic-ws)
65                                                         (point))
66                                                     (cdr arg)))))
67                         ">"))))
68         do (insert "\n")))
69
70 (defun c-build-defun (&optional add-words no-kill)
71   ;; build a function definition header for the current defun. if
72   ;; ADD-WORDS is non-nil, it is prepended to the definition header
73   ;; after any template specifications. the return value is a cons of
74   ;; the name of the function and the complete text of the header.
75   ;; c-build-defun tries hard to keep the with of the declaration
76   ;; below c-max-def-column
77   (save-excursion
78     (c-beginning-of-defun-or-decl)
79     (let* ((tbuf (get-buffer-create " *cc-temp-buffer*"))
80            (state (c-get-defun-state))
81            (prefix (c-get-full-prefix (aref state 8)))
82            (cbuf (current-buffer))
83            p1 p2 p3 c maxc fname)
84       (set-buffer tbuf)
85       (erase-buffer)
86       (c-build-template-specs (aref state 0) cbuf)
87       (if (aref state 1)
88           (progn
89             (insert-buffer-substring cbuf (car (aref state 1)) (cdr (aref state 1)))
90             (if (not no-kill)
91                 (progn
92                   (beginning-of-line)
93                   (c-kill-special-keywords)
94                   (goto-char (point-max))))
95             (insert " ")))
96       (if add-words
97           (progn
98             (beginning-of-line)
99             (insert add-words " ")
100             (goto-char (point-max))))
101       (setq p1 (point))
102       (insert prefix)
103       (if (> (length prefix) 0)
104           (progn
105             (insert "::")
106             (setq p2 (point))))
107       (save-excursion
108         (insert-buffer-substring cbuf (car (aref state 2)) (cdr (aref state 2))))
109       (save-excursion
110         (while (re-search-forward "\\s-+" nil t)
111           (replace-match "")))
112       (if (not p2)
113           (progn
114             (c-with-temporary-syntax-table c-mode-syntax-table
115               (setq p2 (car (last (c-forward-scoped-name))))
116               (if p2
117                   (setq p2 (+ p2 2))))))
118       (goto-char (point-max))
119       (setq fname (buffer-substring-no-properties p1 (point)))
120       (if (> (current-column) c-max-def-column)
121           (progn
122             (goto-char p1)
123             (delete-char -1)
124             (insert "\n")
125             (end-of-line)
126             (setq p1 nil)))
127       (insert "(")
128       (setq p3 (point))
129       (setq c (current-column)
130             maxc 0)
131       (insert "\n")
132       (loop for arg in (aref state 3)
133             for next = nil then t
134             if next do (insert ",\n")
135             do (progn
136                  (save-excursion
137                    (insert-buffer-substring cbuf (car arg) (cdr arg)))
138                  (save-excursion
139                    (if (search-forward "=" nil t)
140                        (progn
141                          (forward-char -1)
142                          (c-backward-syntactic-ws)
143                          (forward-char 1)
144                          (delete-region (1- (point)) (progn (end-of-line) (point))))))
145                  (replace-regexp "\\s-+" " ")
146                  (end-of-line)
147                  (let ((cc (current-column)))
148                    (if (> cc maxc)
149                        (setq maxc cc)))))
150       (if (> (+ c maxc) c-max-def-column)
151           (progn
152             (if (and p1
153                      (progn
154                        (goto-char p1)
155                        (> (1- (current-column))
156                           (- (+ c maxc) c-max-def-column))))
157                 (progn
158                   (delete-char -1)
159                   (insert "\n"))
160               (if p2
161                   (progn
162                     (goto-char p2)
163                     (insert "\n")
164                     (setq p3 (1+ p3)))))))
165       (goto-char p3)
166       (setq c (current-column))
167       (loop for next = nil then t
168             for p = (point)
169             while (not (eobp))
170             do (progn
171                  (if next (insert " "))
172                  (delete-char 1)
173                  (end-of-line)
174                  (if (and next (> (current-column) c-max-def-column))
175                      (progn
176                        (goto-char p)
177                        (delete-char 1)
178                        (insert "\n" (make-string c ? ))
179                        (end-of-line)))))
180       (insert ")")
181       (if (aref state 4)
182           (progn
183             (insert "\n    ")
184             (save-excursion
185               (insert-buffer-substring cbuf (car (aref state 4)) (cdr (aref state 4))))
186             (replace-regexp "\\s-+" " ")
187             (end-of-line)))
188       (if (aref state 5)
189           (progn
190             (insert "\n    : ")
191             (loop with first = t
192                   for initializer in (aref state 5)
193                   for next = nil then t
194                   for p = (point)
195                   do (progn
196                        (if next (insert ", "))
197                        (save-excursion
198                          (insert-buffer-substring cbuf (car initializer) 
199                                                   (cdr initializer)))
200                        (replace-regexp "\\s-+" " ")
201                        (end-of-line)
202                        (if (not first)
203                            (if (> (current-column) c-max-def-column)
204                                (progn
205                                  (goto-char (1+ p))
206                                  (delete-char 1)
207                                  (insert "\n      ")
208                                  (setq first t)
209                                  (end-of-line)))
210                          (setq first nil))))))
211       (prog1
212           (list fname 
213                 (buffer-substring-no-properties (point-min) (point-max))
214                 state)
215         (kill-buffer tbuf)))))
216
217 (defun c-build-create-constructor ()
218   (save-excursion
219     (c-beginning-of-defun-or-decl)
220     (let* ((tbuf (get-buffer-create " *cc-temp-buffer*"))
221            (cbuf (current-buffer))
222            (state (c-get-defun-state))
223            (indent (make-string (current-indentation) ? ))
224            (fname (buffer-substring-no-properties (car (aref state 2))
225                                                   (cdr (aref state 2)))))
226       (set-buffer tbuf)
227       (if (aref state 1)
228           (error "Not a constructor"))
229       (insert indent "static ptr create(")
230       (let ((indent2 (make-string (current-column) ? ))
231             ml)
232         (save-excursion
233           (insert "\n")
234           (loop for arg in (aref state 3)
235                 for next = nil then t
236                 if next do (insert ",\n")
237                 do (progn
238                      (save-excursion
239                        (insert-buffer-substring cbuf (car arg) (cdr arg)))
240                      (replace-regexp "\\s-+" " ")
241                      (end-of-line))))
242         (loop for next = nil then t
243               for p = (point)
244               while (not (eobp))
245               do (progn
246                    (if next (insert " "))
247                    (delete-char 1)
248                    (end-of-line)
249                    (if (and next (> (current-column) c-max-def-column))
250                        (progn
251                          (setq ml t)
252                          (goto-char p)
253                          (delete-char 1)
254                          (insert "\n" indent2)
255                          (end-of-line)))))
256         (insert ")");
257         (if (aref state 4)
258             (progn
259               (insert " ")
260               (let ((p (point)))
261                 (save-excursion
262                   (insert-buffer-substring cbuf 
263                                            (car (aref state 4))
264                                            (cdr (aref state 4))))
265                 (replace-regexp "\\s-+" " ")
266                 (end-of-line)
267                 (if (or ml (> (current-column) c-max-def-column))
268                     (progn
269                       (goto-char p)
270                       (insert "\n" indent (make-string c-basic-offset ? ))
271                       (end-of-line))))))
272         (insert ";\n"))
273       (prog1
274           (list "create"
275                 (buffer-substring-no-properties (point-min) (point-max))
276                 state)
277         (kill-buffer tbuf)))))
278
279 (defun c-build-create-constructor-impl (&optional add-words no-kill)
280   (save-excursion
281     (let* ((proto (c-build-defun add-words no-kill))
282            (cbuf (current-buffer))
283            (tbuf (get-buffer-create " *cc-temp-buffer*"))
284            (indent (make-string c-basic-offset ? )))
285       (set-buffer tbuf)
286       (erase-buffer)
287       (insert (nth 1 proto) "\n{\n" indent "return ptr(new "
288               (save-excursion
289                 (set-buffer cbuf)
290                 (c-scope-name (aref (car (last (aref (nth 2 proto) 8))) 1)))
291               "(")
292       (let ((indent2 (make-string (current-column) ? )))
293         (save-excursion
294           (insert "\n")
295           (loop for arg in (aref (nth 2 proto) 3)
296                 for next = nil then t
297                 if next do (insert ",\n")
298                 do (insert (save-excursion
299                              (set-buffer cbuf)
300                              (c-get-template-argument-name (car arg) (cdr arg))))))
301         (loop for next = nil then t
302               for p = (point)
303               while (not (eobp))
304               do (progn
305                    (if next (insert " "))
306                    (delete-char 1)
307                    (end-of-line)
308                    (if (and next (> (current-column) c-max-def-column))
309                        (progn
310                          (goto-char p)
311                          (delete-char 1)
312                          (insert "\n" indent2)
313                          (end-of-line)))))
314         (insert "));\n}\n"))
315       (prog1
316           (list (car proto)
317                 (buffer-substring-no-properties (point-min) (point-max))
318                 (cdr proto))
319         (kill-buffer tbuf)))))
320
321 (eval-when-compile (autoload 'ccide-reformat-defun "cc-ide"))
322
323 (defun c-build-default-funcions-impl ()
324   (save-excursion
325     (let* ((scope (c-get-block-scope))
326            (templates (c-get-templates scope))
327            (prefix (c-get-full-prefix scope))
328            (class (c-parse-class scope))
329            (bases (c-get-base-classes class))
330            (variables (c-get-variable-members class))
331            (name (c-scope-name (aref (car (last scope)) 1)))
332            (in (make-string c-basic-offset ? ))
333            (cbuf (current-buffer))
334            (tbuf (get-buffer-create " *cc-temp-buffer-2*"))
335            template-specs)
336       (set-buffer tbuf)
337       (erase-buffer)
338       (c-build-template-specs templates cbuf)
339       (setq template-specs (buffer-substring (point-min) (point-max)))
340       (save-excursion 
341         (insert "prefix_ " prefix "::" name "()\n")
342         (if ccide-gen-throw
343             (insert in "throw_(())\n"))
344         (insert "{}\n"
345                 "\n"))
346       (ccide-reformat-defun)
347       (goto-char (point-max))
348       (insert template-specs)
349       (save-excursion
350         (insert "prefix_ " prefix "::" name "(const " name "& other)\n")
351         (if ccide-gen-throw
352             (insert in "throw_(())\n"))
353         (insert in ": " 
354                 (mapconcat (function (lambda (x) (concat x "(other)")))
355                            bases ", ")
356                 (if (and bases variables) ", " "")
357                 (mapconcat (function (lambda (x) (concat x "(other." x ")")))
358                            variables ", ")
359                 "\n{}\n\n"))
360       (ccide-reformat-defun)
361       (goto-char (point-max))
362       (insert template-specs)
363       (save-excursion
364         (insert "prefix_ " prefix " & " prefix "::operator=(const " 
365                 name "& other)\n")
366         (if ccide-gen-throw
367             (insert in "throw_(())\n"))
368         (insert "{\n"
369                 (mapconcat (function (lambda (x) 
370                                        (concat in "*((" x "*)this) = other;\n")))
371                            bases "")
372                 (mapconcat (function (lambda (x)
373                                        (concat in x " = other." x ";\n")))
374                            variables "")
375                 in "return *this"
376                 "}\n\n"))
377       (ccide-reformat-defun)
378       (goto-char (point-max))
379       (insert template-specs)
380       (save-excursion
381         (insert "prefix_ " prefix "::~" name "()\n{}\n"))
382       (ccide-reformat-defun)
383       (prog1
384           (list prefix
385                 (buffer-substring-no-properties (point-min) (point-max)))
386         (kill-buffer tbuf)))))
387
388 (provide 'cc-helper)
389
390 \f
391 ;;; Local Variables:
392 ;;; elisp-project-autoload-file-name: "cc-autoload.el"
393 ;;; End: