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