Emacs/cc-ide: More flexible ccide-all-includes implementation
[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             (save-excursion
90               (insert-buffer-substring cbuf (car (aref state 1)) (cdr (aref state 1)))
91               (insert " "))
92             (if (not no-kill)
93                 (progn
94                   (c-kill-special-keywords)))))
95       (if add-words
96           (progn
97             (insert add-words " ")))
98       (goto-char (point-max))
99       (setq p1 (point))
100       (insert prefix)
101       (if (> (length prefix) 0)
102           (progn
103             (insert "::")
104             (setq p2 (point))))
105       (save-excursion
106         (insert-buffer-substring cbuf (car (aref state 2)) (cdr (aref state 2))))
107       (save-excursion
108         (while (re-search-forward "\\s-+" nil t)
109           (replace-match "")))
110       (if (not p2)
111           (progn
112             (c-with-temporary-syntax-table c-mode-syntax-table
113               (setq p2 (car (last (c-forward-scoped-name))))
114               (if p2
115                   (setq p2 (+ p2 2))))))
116       (goto-char (point-max))
117       (setq fname (buffer-substring-no-properties p1 (point)))
118       (if (> (current-column) c-max-def-column)
119           (progn
120             (goto-char p1)
121             (delete-char -1)
122             (insert "\n")
123             (end-of-line)
124             (setq p1 nil)))
125       (insert "(")
126       (setq p3 (point))
127       (setq c (current-column)
128             maxc 0)
129       (insert "\n")
130       (loop for arg in (aref state 3)
131             for next = nil then t
132             if next do (insert ",\n")
133             do (progn
134                  (save-excursion
135                    (insert-buffer-substring cbuf (car arg) (cdr arg)))
136                  (save-excursion
137                    (if (search-forward "=" nil t)
138                        (progn
139                          (forward-char -1)
140                          (c-backward-syntactic-ws)
141                          (forward-char 1)
142                          (delete-region (1- (point)) (progn (end-of-line) (point))))))
143                  (replace-regexp "\\s-+" " ")
144                  (end-of-line)
145                  (let ((cc (current-column)))
146                    (if (> cc maxc)
147                        (setq maxc cc)))))
148       (if (> (+ c maxc) c-max-def-column)
149           (progn
150             (if (and p1
151                      (progn
152                        (goto-char p1)
153                        (> (1- (current-column))
154                           (- (+ c maxc) c-max-def-column))))
155                 (progn
156                   (delete-char -1)
157                   (insert "\n"))
158               (if p2
159                   (progn
160                     (goto-char p2)
161                     (insert "\n")
162                     (setq p3 (1+ p3)))))))
163       (goto-char p3)
164       (setq c (current-column))
165       (loop for next = nil then t
166             for p = (point)
167             while (not (eobp))
168             do (progn
169                  (if next (insert " "))
170                  (delete-char 1)
171                  (end-of-line)
172                  (if (and next (> (current-column) c-max-def-column))
173                      (progn
174                        (goto-char p)
175                        (delete-char 1)
176                        (insert "\n" (make-string c ? ))
177                        (end-of-line)))))
178       (insert ")")
179       (if (aref state 4)
180           (progn
181             (insert "\n    ")
182             (save-excursion
183               (insert-buffer-substring cbuf (car (aref state 4)) (cdr (aref state 4))))
184             (replace-regexp "\\s-+" " ")
185             (end-of-line)))
186       (if (aref state 5)
187           (progn
188             (insert "\n    : ")
189             (loop with first = t
190                   for initializer in (aref state 5)
191                   for next = nil then t
192                   for p = (point)
193                   do (progn
194                        (if next (insert ", "))
195                        (save-excursion
196                          (insert-buffer-substring cbuf (car initializer) 
197                                                   (cdr initializer)))
198                        (replace-regexp "\\s-+" " ")
199                        (end-of-line)
200                        (if (not first)
201                            (if (> (current-column) c-max-def-column)
202                                (progn
203                                  (goto-char (1+ p))
204                                  (delete-char 1)
205                                  (insert "\n      ")
206                                  (setq first t)
207                                  (end-of-line)))
208                          (setq first nil))))))
209       (prog1
210           (list fname 
211                 (buffer-substring-no-properties (point-min) (point-max))
212                 state)
213         (kill-buffer tbuf)))))
214
215 (defun c-build-create-constructor ()
216   (save-excursion
217     (c-beginning-of-defun-or-decl)
218     (let* ((tbuf (get-buffer-create " *cc-temp-buffer*"))
219            (cbuf (current-buffer))
220            (state (c-get-defun-state))
221            (indent (make-string (current-indentation) ? ))
222            (fname (buffer-substring-no-properties (car (aref state 2))
223                                                   (cdr (aref state 2)))))
224       (set-buffer tbuf)
225       (if (aref state 1)
226           (error "Not a constructor"))
227       (insert indent "static ptr create(")
228       (let ((indent2 (make-string (current-column) ? ))
229             ml)
230         (save-excursion
231           (insert "\n")
232           (loop for arg in (aref state 3)
233                 for next = nil then t
234                 if next do (insert ",\n")
235                 do (progn
236                      (save-excursion
237                        (insert-buffer-substring cbuf (car arg) (cdr arg)))
238                      (replace-regexp "\\s-+" " ")
239                      (end-of-line))))
240         (loop for next = nil then t
241               for p = (point)
242               while (not (eobp))
243               do (progn
244                    (if next (insert " "))
245                    (delete-char 1)
246                    (end-of-line)
247                    (if (and next (> (current-column) c-max-def-column))
248                        (progn
249                          (setq ml t)
250                          (goto-char p)
251                          (delete-char 1)
252                          (insert "\n" indent2)
253                          (end-of-line)))))
254         (insert ")");
255         (if (aref state 4)
256             (progn
257               (insert " ")
258               (let ((p (point)))
259                 (save-excursion
260                   (insert-buffer-substring cbuf 
261                                            (car (aref state 4))
262                                            (cdr (aref state 4))))
263                 (replace-regexp "\\s-+" " ")
264                 (end-of-line)
265                 (if (or ml (> (current-column) c-max-def-column))
266                     (progn
267                       (goto-char p)
268                       (insert "\n" indent (make-string c-basic-offset ? ))
269                       (end-of-line))))))
270         (insert ";\n"))
271       (prog1
272           (list "create"
273                 (buffer-substring-no-properties (point-min) (point-max))
274                 state)
275         (kill-buffer tbuf)))))
276
277 (defun c-build-create-constructor-impl (&optional add-words no-kill)
278   (save-excursion
279     (let* ((proto (c-build-defun add-words no-kill))
280            (cbuf (current-buffer))
281            (tbuf (get-buffer-create " *cc-temp-buffer*"))
282            (indent (make-string c-basic-offset ? )))
283       (set-buffer tbuf)
284       (erase-buffer)
285       (insert (nth 1 proto) "\n{\n" indent "return ptr(new "
286               (save-excursion
287                 (set-buffer cbuf)
288                 (c-scope-name (aref (car (last (aref (nth 2 proto) 8))) 1)))
289               "(")
290       (let ((indent2 (make-string (current-column) ? )))
291         (save-excursion
292           (insert "\n")
293           (loop for arg in (aref (nth 2 proto) 3)
294                 for next = nil then t
295                 if next do (insert ",\n")
296                 do (insert (save-excursion
297                              (set-buffer cbuf)
298                              (c-get-template-argument-name (car arg) (cdr arg))))))
299         (loop for next = nil then t
300               for p = (point)
301               while (not (eobp))
302               do (progn
303                    (if next (insert " "))
304                    (delete-char 1)
305                    (end-of-line)
306                    (if (and next (> (current-column) c-max-def-column))
307                        (progn
308                          (goto-char p)
309                          (delete-char 1)
310                          (insert "\n" indent2)
311                          (end-of-line)))))
312         (insert "));\n}\n"))
313       (prog1
314           (list (car proto)
315                 (buffer-substring-no-properties (point-min) (point-max))
316                 (cdr proto))
317         (kill-buffer tbuf)))))
318
319 (eval-when-compile (autoload 'ccide-reformat-defun "cc-ide"))
320
321 (defun c-build-default-funcions-impl ()
322   (save-excursion
323     (let* ((scope (c-get-block-scope))
324            (templates (c-get-templates scope))
325            (prefix (c-get-full-prefix scope))
326            (class (c-parse-class scope))
327            (bases (c-get-base-classes class))
328            (variables (c-get-variable-members class))
329            (name (c-scope-name (aref (car (last scope)) 1)))
330            (in (make-string c-basic-offset ? ))
331            (cbuf (current-buffer))
332            (tbuf (get-buffer-create " *cc-temp-buffer-2*"))
333            template-specs)
334       (set-buffer tbuf)
335       (erase-buffer)
336       (c-build-template-specs templates cbuf)
337       (setq template-specs (buffer-substring (point-min) (point-max)))
338       (save-excursion 
339         (insert "prefix_ " prefix "::" name "()\n")
340         (if ccide-gen-throw
341             (insert in "throw_(())\n"))
342         (insert "{}\n"
343                 "\n"))
344       (ccide-reformat-defun)
345       (goto-char (point-max))
346       (insert template-specs)
347       (save-excursion
348         (insert "prefix_ " prefix "::" name "(const " name "& other)\n")
349         (if ccide-gen-throw
350             (insert in "throw_(())\n"))
351         (insert in ": " 
352                 (mapconcat (function (lambda (x) (concat x "(other)")))
353                            bases ", ")
354                 (if (and bases variables) ", " "")
355                 (mapconcat (function (lambda (x) (concat x "(other." x ")")))
356                            variables ", ")
357                 "\n{}\n\n"))
358       (ccide-reformat-defun)
359       (goto-char (point-max))
360       (insert template-specs)
361       (save-excursion
362         (insert "prefix_ " prefix " & " prefix "::operator=(const " 
363                 name "& other)\n")
364         (if ccide-gen-throw
365             (insert in "throw_(())\n"))
366         (insert "{\n"
367                 (mapconcat (function (lambda (x) 
368                                        (concat in "*((" x "*)this) = other;\n")))
369                            bases "")
370                 (mapconcat (function (lambda (x)
371                                        (concat in x " = other." x ";\n")))
372                            variables "")
373                 in "return *this"
374                 "}\n\n"))
375       (ccide-reformat-defun)
376       (goto-char (point-max))
377       (insert template-specs)
378       (save-excursion
379         (insert "prefix_ " prefix "::~" name "()\n{}\n"))
380       (ccide-reformat-defun)
381       (prog1
382           (list prefix
383                 (buffer-substring-no-properties (point-min) (point-max)))
384         (kill-buffer tbuf)))))
385
386 (provide 'cc-helper)
387
388 \f
389 ;;; Local Variables:
390 ;;; elisp-project-autoload-file-name: "cc-autoload.el"
391 ;;; End: