Fix doxy-tag RE
[emacsstuff.git] / cc-ide / cc-ide.el
1 ;;; cc-ide.el --- C++ IDE
2 ;;
3 ;; $Id$
4 ;;
5 ;; Copyright (C) 2000 Stefan Bund
6
7 ;; cc-ide.el is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 2, or (at your
10 ;; option) any later version.
11
12 ;; cc-ide.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 ccide-compile-opts "DEBUG=1"
27   "*Additional options to make command")
28
29 (defvar ccide-file-vars nil)
30
31 (defvar ccide-default-author "")
32 (defvar ccide-default-copyright "")
33
34 (defvar ccide-corba-skel-dir "")
35 (defvar ccide-corba-idl-dir "")
36 (defvar ccide-corba-idl-command "omniidl2 -w")
37
38 (defvar c-user-prefixes '("inline" "static" "prefix_")
39   "*List of possible prefixes for function definitions.")
40
41 (defvar ccide-default-prefix "prefix_"
42   "*Prefix added to every implementation header. Probably eiter empty or 'prefix_'")
43
44 (defvar ccide-gen-throw nil
45   "*If non-nil, generate throw_ specs")
46
47 (defconst c-user-prefix-re (regexp-opt c-user-prefixes t))
48
49 (defconst ccide-doxy-tag-re 
50   "\\\\\\(group\\|defgroup\\|see\\|author\\|version\\|id\\|since\\|returns?\\|throws\\|exception\\|raises\\|param\\|li\\|short\\|internal\\)\\b")
51
52 (defconst ccide-special-extensions
53   '(".h" ".hh" ".mpp" ".ih" ".cc" ".cpp" ".ct" ".cti" ".cci"))
54
55 (defconst ccide-implementation-extensions
56   '(".h" ".hh" ".ih" ".cc" ".cpp" ".ct" ".cti" ".cci"))
57
58 (defconst ccide-class-defaults-word 
59   "// \\(default\\|no\\|protected\\|private\\|disabled\\|my\\)")
60
61 (defconst  ccide-bindings
62   '(
63     ;; file level
64     ("fc"  ccide-file-comment                 "File comment")
65     ("fs"  ccide-syncronize-includes          "Sync includes")
66     (nil   nil                                separator)
67                                           
68     ;; class level                        
69     ("cc"  ccide-class-comment                "Class comment")
70     ("cg"  ccide-gen-class                    "Generate class")
71     ("cd"  ccide-gen-class-defaults           "Generate class defaults")
72     ("cD"  ccide-gen-class-defaults-impl      "Generate class defaults impl")
73
74     ("csd" ccide-set-class-defaults-default   "Set class defaults comment" "Default")
75     ("csn" ccide-set-class-defaults-no        "Set class defaults comment" "No")
76     ("csp" ccide-set-class-defaults-protected "Set class defaults comment" "Protected")
77     ("csr" ccide-set-class-defaults-private   "Set class defaults comment" "Private")
78     ("csx" ccide-set-class-defaults-disabled  "Set class defaults comment" "Disabled")
79     ("csm" ccide-set-class-defaults-my        "Set class defaults comment" "My")
80
81     ("cS"  ccide-gen-struct-constructors      "Generate structure constructors")
82
83     ("ci"  ccide-class-impl-comment           "Generate class implemenation comment")
84
85     (nil   nil                                separator)
86                                           
87     ;; method level                       
88     ("mc"  ccide-function-comment             "Method comment")
89     ("mp"  ccide-grab-prototype               "Grab prototype")
90     ("mr"  ccide-reformat-defun               "Reformat defun")
91     ("mx"  ccide-replace-defun                "Replace defun")
92     ("mt"  ccide-prefix-defun-type-with-class "Prefix defun type with class")
93     ("mn"  ccide-prefix-defun-type-with-namespace "Prefix defun type with namespace")
94     ("mi"  ccide-grab-inline-decl             "Grab inline decl")
95     ("mA"  ccide-grab-all-inlines             "Grab ALL inline decls")
96     ("mC"  ccide-grab-create-constructor      "Grab CREATE constructor")
97     ("mI"  ccide-grab-create-constructor-impl "Build CREATE cosntructor")
98     ("mf"  ccide-find-implementation          "Find method implementation")
99     ("mT"  ccide-insert-defun-prefix          "Insert current defun prefix at point")
100     (nil   nil                                separator)
101                                           
102     ;; variable level                     
103     ("vc"  ccide-variable-comment             "Variable comment")
104     ("vf"  ccide-grab-acces-fn                "Grab access methods")
105     (nil   nil                                separator)
106                                           
107     ;; CORBA                              
108     ("Cg"  ccide-gen-corba-impl               "Generate CORBA impl")
109     ("Cm"  ccide-gen-corba-impl-methods       "Generate CORBA impl methods")
110     (nil   nil                                separator)
111                                           
112     ;; templates                          
113 ;    ("ts"  ccide-scan-mantemps               "Scan mantemps")
114 ;    (nil   nil                                separator)
115
116     ;; other
117     ("of"  ccide-open-compilation-frame       "Open *compilation* frame")
118     ("oc"  ccide-compile-compile              "Make -> Compile")
119     ("ox"  ccide-compile-clean                "Make -> Clean")
120     ("od"  ccide-compile-cleandepends         "Make -> Clean depends")
121     ("ok"  ccide-compile-kill                 "Kill compilation")
122     ("oh"  ccide-hide-compilation             "Hide *compilation* buffer")))
123
124 ;;; Code:
125
126 (require 'cc-engine-2)
127 (require 'cc-helper)
128 (require 'c++)
129 (require 'cl)
130 (require 'hideshow)
131 ;(require 'mantemp)
132 (require 'locate)
133 (require 'lucid)
134 (require 'varcmd)
135 (require 'misc-local)
136
137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138 ;; utils
139
140 (defsubst ccide-match-string (n)
141   (buffer-substring-no-properties (match-beginning n) (match-end n)))
142
143 (defun ccide-file-macro-name (&optional file-name)
144   (concat (upcase (file-name-extension (or file-name (buffer-file-name))))
145           "_" 
146           (string-replace "\\." "_" (file-name-sans-extension 
147                                      (file-name-nondirectory 
148                                       (or file-name (buffer-file-name))))
149                           t nil t t)
150           "_"))
151
152 (defun ccide-file-name (&optional extension file-name directory)
153   (concat (if directory (file-name-as-directory directory) "")
154           (file-name-sans-extension
155            (file-name-nondirectory 
156             (or file-name (buffer-file-name))))
157           extension))
158
159 (defun ccide-in-doxy-comment ()
160   (save-excursion
161     (back-to-indentation)
162     (if (eq (c-in-literal) 'c)
163         (progn
164           (goto-char (car (c-literal-limits)))
165           (and (looking-at "/\\*\\*[ \t\n\r@]")
166                (current-column))))))
167
168 (defun ccide-shell-command (command)
169   (let ((obuf (get-buffer-create "*ccide shell command*"))
170         exit-status)
171     (save-excursion
172       (set-buffer obuf)
173       (erase-buffer)
174       (insert command "\n"))
175     (setq exit-status (call-process shell-file-name nil "*ccide shell command*" nil
176                                     shell-command-switch command))
177     (and exit-status (equal exit-status 0))))
178
179 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
180 ;; file level
181
182 (defun ccide-file-comment ()
183   "Add a comment to this source file."
184   (interactive)
185   (let ((mode "c++")
186         point)
187     (push-mark)
188     (goto-char (point-min))
189     (insert "// $Id$\n"
190             "//\n"
191             "// Copyright (C) " (number-to-string (nth 5 (decode-time)))
192             " " ccide-default-author "\n"
193             ccide-default-copyright
194             "\n")
195     (cond ((string-match "\\.hh?$" (buffer-file-name))
196            (insert "#ifndef " (ccide-file-macro-name) "\n"
197                    "#define " (ccide-file-macro-name) " 1\n\n"
198                    "// Custom includes\n\n"
199                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
200                    "///////////////////////////////hh.p////////////////////////////////////////\n\n")
201            (setq point (point))
202            (goto-char (point-max))
203            (insert "\n\n///////////////////////////////hh.e////////////////////////////////////////\n"
204                    "//#include \"" (ccide-file-name ".cci") "\"\n"
205                    "//#include \"" (ccide-file-name ".ct") "\"\n"
206                    "//#include \"" (ccide-file-name ".cti") "\"\n"
207                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
208                    "#endif"))
209           ((string-match "\\.mpp$" (buffer-file-name))
210            (insert "#if !BOOST_PP_IS_ITERATING\n"
211                    "#ifndef " (ccide-file-macro-name) "\n\n"
212                    "// Custom includes\n\n"
213                    "//////////////////////////////mpp.p////////////////////////////////////////\n"
214                    "// Local Macros\n\n"
215                    "//////\n"
216                    "#endif\n"
217                    "#else\n"
218                    "///////////////////////////////////////////////////////////////////////////\n\n"
219                    "//////\n"
220                    "#if BOOST_PP_ITERATION_FLAGS()==1\n"
221                    "///////////////////////////////////////////////////////////////////////////\n\n")
222            (setq point (point))
223            (goto-char (point-max))
224            (insert "\n\n//////\n"
225                    "#endif\n"
226                    "#endif\n"
227                    "#if !BOOST_PP_IS_ITERATING\n"
228                    "#ifdef " (ccide-file-macro-name) "\n"
229                    "///////////////////////////////////////////////////////////////////////////\n"
230                    "// Undefine local Macros\n\n"
231                    "//////////////////////////////mpp.e////////////////////////////////////////\n"
232                    "#else\n"
233                    "#define " (ccide-file-macro-name) " 1\n"
234                    "#endif\n"
235                    "#endif"))
236           ((string-match "\\.ih$" (buffer-file-name))
237            (insert "#ifndef " (ccide-file-macro-name) "\n"
238                    "#define " (ccide-file-macro-name) " 1\n\n"
239                    "// Custom includes\n\n"
240                    "///////////////////////////////ih.p////////////////////////////////////////\n\n")
241            (setq point (point))
242            (goto-char (point-max))
243            (insert "\n\n///////////////////////////////ih.e////////////////////////////////////////\n"
244                    "#endif"))
245           ((or (string-match "\\.test\\.cc$" (buffer-file-name))
246                (string-match "\\.test\\.cpp$" (buffer-file-name)))
247            (insert "// Unit tests\n\n"
248                    "//#include \"" (ccide-file-name ".hh") "\"\n"
249                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
250                    "// Custom includes\n"
251                    "#include \"" (ccide-file-name ".hh" (ccide-file-name)) "\"\n\n"
252                    "#include <boost/test/auto_unit_test.hpp>\n"
253                    "#include <boost/test/test_tools.hpp>\n\n"
254                    "#define prefix_\n"
255                    "///////////////////////////////cc.p////////////////////////////////////////\n\n")
256            (setq point (point))
257            (goto-char (point-max))
258            (insert "\n\n///////////////////////////////cc.e////////////////////////////////////////\n"
259                    "#undef prefix_"))
260           ((or (string-match "\\.cc$" (buffer-file-name))
261                (string-match "\\.cpp$" (buffer-file-name)))
262            (insert "// Definition of non-inline non-template functions\n\n"
263                    "//#include \"" (ccide-file-name ".hh") "\"\n"
264                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
265                    "// Custom includes\n\n"
266                    "//#include \"" (ccide-file-name ".mpp") "\"\n"
267                    "#define prefix_\n"
268                    "///////////////////////////////cc.p////////////////////////////////////////\n\n")
269            (setq point (point))
270            (goto-char (point-max))
271            (insert "\n\n///////////////////////////////cc.e////////////////////////////////////////\n"
272                    "#undef prefix_\n"
273                    "//#include \"" (ccide-file-name ".mpp") "\""))
274           ((string-match "\\.cci$" (buffer-file-name))
275            (insert "// Definition of inline non-template functions\n\n"
276                    "// Custom includes\n\n"
277                    "#define prefix_ inline\n"
278                    "///////////////////////////////cci.p///////////////////////////////////////\n\n")
279            (setq point (point))
280            (goto-char (point-max))
281            (insert "\n\n///////////////////////////////cci.e///////////////////////////////////////\n"
282                    "#undef prefix_"))
283           ((string-match "\\.ct$" (buffer-file-name))
284            (insert "// Definition of non-inline template functions\n\n"
285                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
286                    "// Custom includes\n\n"
287                    "#define prefix_\n"
288                    "///////////////////////////////ct.p////////////////////////////////////////\n\n")
289            (setq point (point))
290            (goto-char (point-max))
291            (insert "\n\n///////////////////////////////ct.e////////////////////////////////////////\n"
292                    "#undef prefix_"))
293           ((string-match "\\.cti$" (buffer-file-name))
294            (insert "// Definition of inline template functions\n\n"
295                    "//#include \"" (ccide-file-name ".ih") "\"\n\n"
296                    "// Custom includes\n\n"
297                    "#define prefix_ inline\n"
298                    "///////////////////////////////cti.p///////////////////////////////////////\n\n")
299            (setq point (point))
300            (goto-char (point-max))
301            (insert "\n\n///////////////////////////////cti.e///////////////////////////////////////\n"
302                    "#undef prefix_"))
303           ((string-match "\\.java$" (buffer-file-name))
304            (setq mode "jde")
305            (setq point (point))
306            (goto-char (point-max)))
307           (t
308            (setq point (point))
309            (goto-char (point-max))))
310     (insert "\n\n\f\n"
311             "// Local Variables:\n"
312             "// mode: " mode "\n")
313     (loop for (var . value) in ccide-file-vars
314           do (insert "// " (symbol-name var) ": " (prin1-to-string value) "\n"))
315     (insert "// End:\n")
316     (if point
317         (goto-char point))
318     (if (equal mode "jde")
319         (let ((package (file-name-directory (buffer-file-name))))
320           (jdeap-initialize-setup)
321           (if (not (equal jdeap-current-source-directory "."))
322               (if (string-match 
323                    (concat "^" (regexp-quote jdeap-current-source-directory))
324                    package)
325                   (progn
326                     (setq package (substring package 
327                                              (match-end 0)
328                                              (1- (length package))))
329                     (insert "package "
330                             (string-replace "/" "." package t)
331                             ";\n\n"))))
332           (insert "class " (file-name-sans-extension
333                             (file-name-nondirectory 
334                              (buffer-file-name))) "\n{}")
335           (beginning-of-line)))))
336
337 (defun ccide-syncronize-includes ()
338   "Syncronize include's in all other files"
339   (interactive)
340   (let (buffer-map)
341     (loop for extension in ccide-special-extensions
342           for file-name = (ccide-file-name extension)
343           do (setq buffer-map
344                    (cons (cons file-name
345                                (or (find-buffer-visiting file-name)
346                                    (and (file-readable-p file-name)
347                                         (find-file-noselect file-name))))
348                          buffer-map)))
349     (save-excursion
350       (loop for buffer in buffer-map
351             if (cdr buffer)
352               do (progn 
353                    (set-buffer (cdr buffer))
354                    (save-excursion
355                      (loop for include in buffer-map
356                            do (progn 
357                                 (goto-char (point-min))
358                                 (while (re-search-forward 
359                                         (concat "^\\(//\\)?#\\s-*include \""
360                                                 (regexp-quote (car include))
361                                                 "\"\\s-*$")
362                                         nil t)
363                                   (goto-char (match-beginning 0))
364                                   (if (looking-at "//")
365                                       (if (cdr include)
366                                           (delete-char 2))
367                                     (if (not (cdr include))
368                                         (insert "//")))
369                                   (forward-line 1))))))))))
370
371 (defun ccide-auto-decorate-new-files ()
372   (if (= (point-min) (point-max))
373       (let ((status (buffer-modified-p)))
374         (ccide-file-comment)
375         (set-buffer-modified-p status))))
376
377 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
378 ;; class level
379
380 (defun ccide-class-comment ()
381   "Add comment to start of current class definition"
382   (interactive)
383   (let ((class (c-get-class-at-point)))
384     (if (not class)
385         (error "No class found")
386       (goto-char (or (aref (car class) 3)
387                      (aref (car class) 1)))
388       (if (save-excursion 
389             (forward-line -1)
390             (ccide-in-doxy-comment))
391           (progn
392             (search-backward "/**" nil t)
393             (forward-char 4))
394         (let ((indent (make-string (current-indentation) ? )))
395           (insert "/** ")
396           (save-excursion
397             (insert "\n"
398                     indent "    @short \n"
399                     indent " */\n"
400                     indent)))))))
401
402 (defun ccide-gen-class (name &optional defns)
403   "Generate class declaration template"
404   (interactive (list (read-string (concat "Class name (default "
405                                           (ccide-file-name)
406                                           "): ")
407                                   nil nil (ccide-file-name))))
408   (insert "class " name)
409   (indent-according-to-mode)
410   (let ((in (make-string c-basic-offset ? ))
411         (ofs (make-string (current-indentation) ? )))
412     (save-excursion
413       (beginning-of-line)
414       (open-line 1)
415       (insert ofs "/** \\brief\n"
416               ofs "  */"))
417     (insert "\n" ofs)
418     (save-excursion
419       (insert "{\n"
420               ofs "public:\n"
421               ofs in "///////////////////////////////////////////////////////////////////////////\n"
422               ofs in "// Types\n\n"
423               ofs in "///////////////////////////////////////////////////////////////////////////\n"
424               ofs in "///\\name Structors and default members\n"
425               ofs in "///@{\n\n"
426               ofs in "// default default constructor\n"
427               ofs in "// default copy constructor\n"
428               ofs in "// default copy assignment\n"
429               ofs in "// default destructor\n\n"
430               ofs in "// no conversion constructors\n\n"
431               ofs in "///@}\n"
432               ofs in "///////////////////////////////////////////////////////////////////////////\n"
433               ofs in "///\\name Accessors\n"
434               ofs in "///@{\n\n"
435               ofs in "///@}\n"
436               ofs in "///////////////////////////////////////////////////////////////////////////\n"
437               ofs in "///\\name Mutators\n"
438               ofs in "///@{\n\n"
439               ofs in "///@}\n\n")
440       (loop for defn in defns
441             do (insert ofs in defn ";\n"))
442       (if defns
443           (insert "\n"))
444       (insert ofs "protected:\n\n"
445               ofs "private:\n\n"
446               ofs "};\n"))))
447
448 (defun ccide-gen-class-defaults ()
449   "Generate signatures of the default functions: default constructor,
450 copy constructor, assignment operator and destructor."
451   (indent-according-to-mode)
452   (let* ((name (c-scope-name (aref (car (c-get-class-at-point)) 1)))
453          (in (make-string c-basic-offset ? ))
454          (ofs (make-string (current-indentation) ? ))
455          (tspec (if ccide-gen-throw (concat "\n" ofs in "throw_(());\n") ";\n"))
456          (colon 0))
457     (while (string-match "::" name colon)
458       (setq colon (match-end 0)))
459     (setq name (substring name colon))
460     (beginning-of-line)
461     (delete-horizontal-space)
462     (loop with exit = nil
463           do (message (concat "1-dflt constr, 2-destr, "
464                               "3-copy constr, 4-copy assmnt, "
465                               "c-all copy, d-all dflt, RET-all/done: "))
466           for ch = (read-event)
467           for first = t then nil
468           do (cond ((eq ch 'return)
469                     (if first
470                         (insert ofs name "()" 
471                                 tspec
472                                 ofs name "(const " name "& other)" 
473                                 tspec
474                                 ofs "~" name "();\n"
475                                 ofs name "& operator=(const " name "& other)"
476                                 tspec))
477                     (setq exit t))
478                    ((eq ch ?1)
479                     (insert ofs name "()" 
480                             tspec))
481                    ((eq ch ?2)
482                     (insert ofs "~" name "();\n"))
483                    ((eq ch ?3)
484                     (insert ofs name "(const " name "& other)" 
485                             tspec))
486                    ((eq ch ?4)
487                     (insert ofs name "& operator=(const " name "& other)"
488                             tspec))
489                    ((eq ch ?c)
490                     (insert ofs name "(const " name "& other)" 
491                             tspec
492                             ofs name "& operator=(const " name "& other)"
493                             tspec))
494                    ((eq ch ?d)
495                     (insert ofs name "()" 
496                             tspec
497                             ofs "~" name "();\n"))
498                    (t (setq unread-command-events (cons ch unread-command-events))
499                       (setq exit t)))
500           while (not exit))))
501
502 (defun ccide-gen-class-defaults-impl ()
503   "Generate default implementations for class default functions"
504   (interactive)
505   (let ((defn (c-build-default-funcions-impl)))
506     (kill-new (cadr defn))
507     (message (concat (car defn) " default members"))))
508
509 (defun ccide-set-class-defaults-comment (word)
510   (save-excursion
511     (back-to-indentation)
512     (if (not (looking-at ccide-class-defaults-word))
513         (message "Not at class defaults commnet")
514       (replace-match word t t nil 1))))
515
516 (defmacro ccide-build-class-defaults-f (sym)
517   (let ((fn (intern (concat "ccide-set-class-defaults-" 
518                             (symbol-name sym)))))
519     `(defun ,fn ()
520        (interactive)
521        (ccide-set-class-defaults-comment ,(symbol-name sym)))))
522
523 (ccide-build-class-defaults-f no)
524 (ccide-build-class-defaults-f default)
525 (ccide-build-class-defaults-f my)
526 (ccide-build-class-defaults-f protected)
527 (ccide-build-class-defaults-f private)
528 (ccide-build-class-defaults-f disabled)
529
530 (defun ccide-gen-struct-constructors ()
531   (save-excursion
532     (beginning-of-line)
533     (open-line 1)
534     (indent-according-to-mode)
535     (let* ((scope (c-get-block-scope))
536            (class (c-parse-class scope))
537            (variables (c-get-variable-members-with-type class))
538            (name (c-scope-name (aref (car (last scope)) 1)))
539            (in (make-string (current-indentation) ? ))
540            (inin (make-string (+ (current-indentation) c-basic-offset) ? )))
541       (insert name "()\n" inin ": ")
542       (indent-according-to-mode)
543       (loop for var in variables
544             for first = t then nil
545             if (not first) do (insert ", ")
546             do (insert (car var) "()"))
547       (insert "\n" in "{}\n"
548               in name "(")
549       (loop for var in variables
550             for first = t then nil
551             if (not first) do (insert ", ")
552             do (insert (cdr var) " " (car var) "_"))
553       (insert ")\n" inin ": ")
554       (loop for var in variables
555             for first = t then nil
556             if (not first) do (insert ", ")
557             do (insert (car var) "(" (car var) "_)"))
558       (insert "\n" in "{}"))))
559
560 (defun ccide-class-impl-comment ()
561   "Get implementation comment for current class"
562   (interactive)
563   (let* ((scope (c-get-block-scope))
564          (name (c-get-full-prefix scope)))
565     (kill-new (concat (make-string 75 ?/) "\n"
566                       "// " name "\n\n"
567                       "// protected\n\n"
568                       "// private\n\n"))
569     (message name)))
570
571 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
572 ;; function/method level
573
574 (defun ccide-function-comment ()
575   "Add comment to start of current function"
576   (interactive)
577   (c-forward-out-of-comment)
578   (let ((defun (c-get-defun-state))
579         place indent)
580     (c-goto-beginning-of-defun defun)
581     (setq indent (make-string (current-indentation) ? ))
582     (if (save-excursion
583           (forward-line -1)
584           (ccide-in-doxy-comment))
585         ()
586       (insert "/** ")
587       (setq place (point))
588       (insert "\n\n" 
589               indent "    @li @em PRE : \n"
590               indent "    @li @em POST : \n\n"
591               indent "    @short \n"
592               indent " */\n" indent)
593       (setq defun (c-get-defun-state)))
594     (ccide-function-comment-adjust defun indent)
595     (if place (goto-char place))))
596
597 (defun ccide-function-comment-grab-args ()
598   (let ((limit (save-excursion
599                  (search-backward "/**" nil t)
600                  (point)))
601         (end (progn (forward-line -1) (point)))
602         begin start args argend)
603     (if (search-backward "@throws" limit t)
604         (setq argend (progn (beginning-of-line) (point)))
605       (setq argend end))
606     (while (or (search-backward "@param" limit t)
607                (search-backward "@return" limit t)))
608     (beginning-of-line)
609     (setq start (point))
610     (setq begin start)
611     (while (search-forward "@param" argend t)
612       (or (search-forward "@param" argend t)
613           (search-forward "@return" argend t)
614           (search-forward "@throws" argend t)
615           (goto-char argend))
616       (beginning-of-line)
617       (setq args (cons (ccide-function-comment-parse-arg start (point))
618                        args))
619       (setq start (point)))
620     (prog1
621         (if (not (search-forward "@return" argend t))
622             (cons nil args)
623           (beginning-of-line)
624           (cons (buffer-substring (point) argend) args))
625       (delete-region begin end))))
626
627 (defun ccide-function-comment-parse-arg (start end)
628   (save-excursion
629     (goto-char start)
630     (re-search-forward "@param\\s-*\\(\\S-*\\)" end t)
631     (cons (match-string 1) 
632           (cons (buffer-substring start (match-beginning 1))
633                 (buffer-substring (match-end 1) end)))))
634   
635 (defun ccide-function-comment-get-throws (defun)
636   (if (aref defun 4)
637       (save-excursion
638         (goto-char (car (aref defun 4)))
639         (if (re-search-forward "\\(throw_\\|throw\\)((?\\s-*\\([^()]*\\))?)" 
640                                (cdr (aref defun 4)) t)
641             (let ((spec (match-string 2)))
642               (if (> (length spec) 0)
643                   spec))))))
644
645 (defun ccide-function-comment-adjust (defun indent)
646   (let* ((defargs (mapcar (function (lambda (x)
647                                       (c-get-template-argument-name (car x) (cdr x))))
648                           (aref defun 3)))
649          (defret (and (aref defun 1)
650                       (not (string-match (concat "^\\("
651                                                  c-special-key 
652                                                  "\\s-*\\)*\\s-*void$")
653                                          (buffer-substring (car (aref defun 1))
654                                                            (cdr (aref defun 1)))))))
655          (throws (ccide-function-comment-get-throws defun))
656          (xargs (ccide-function-comment-grab-args))
657          (docargs (cdr xargs))
658          (docret (car xargs))
659          (def-in-doc (loop for defarg in defargs always (assoc defarg docargs)))
660          (doc-in-def (loop for docarg in docargs always (member (car docarg) defargs)))
661          (size-eq (= (length defargs) (length docargs))))
662     (if (or defargs defret throws)
663         (if (not (save-excursion 
664                    (forward-line -1)
665                    (looking-at "\\s-*$")))
666             (insert "\n")))
667     ;; We differentiate four types changes
668     ;;  - new arguments
669     ;;  - removed arguments
670     ;;  - reordered arguments
671     ;;  - renamed arguments
672     ;; 
673     ;; If the change cannot be described by one of the above, it has
674     ;; to be resolved manually
675     (save-excursion
676       (cond (doc-in-def
677              ;; reordered arguments or new arguments (or no change)
678              (loop for defarg in defargs
679                    for docarg = (assoc defarg docargs)
680                    do (if docarg
681                           (insert (cadr docarg) (car docarg) (cddr docarg))
682                         (insert indent "    @param " defarg " \n"))))
683             (size-eq ; and (not doc-in-def)
684              ;; renamed arguments
685              (loop for defarg in defargs
686                    for docarg in docargs
687                    do (insert (cadr docarg) defarg (cddr docarg))))
688             (def-in-doc
689               ;; removed arguments
690               (loop for defarg in defargs
691                     for docarg = (assoc defarg docargs)
692                     do (insert (cadr docarg) (car docarg) (cddr docarg))))
693             (t (error "Arg change too complex. Resolve manualy.")))
694       ;; return value is simple
695       (if defret
696           (if docret
697               (insert docret)
698             (insert indent "    @return \n")))
699       (if throws
700           (insert indent "    @throws " throws "\n")))
701     (back-to-indentation)))
702
703 (defun ccide-grab-prototype (&optional prefix)
704   "Grab prototype of function defined or declared at point. Prefix
705 arg, if given, specifies the kind of prefix (inline, static, ...) to use."
706   (interactive "P")
707   (let* ((prfx (or (and prefix (nth (prefix-numeric-value prefix) c-user-prefixes))
708                    ccide-default-prefix))
709          (defn (c-build-defun prfx)))
710     (kill-new (concat (cadr defn) "\n{}\n"))
711     (message (concat (or prfx "")
712                      (if prfx " " "")
713                      (car defn)))))
714
715 (defun ccide-reformat-defun ()
716   "Reformat the defn of the current defun."
717   (interactive)
718   (save-excursion
719     (c-beginning-of-defun-or-decl)
720     (let ((defn (c-build-defun nil t)))
721       (delete-region (or (caar (aref (caddr defn) 0))
722                          (car (aref (caddr defn) 1))
723                          (car (aref (caddr defn) 2)))
724                      (or (car (aref (caddr defn) 6))
725                          (aref (caddr defn) 7)))
726       (insert (cadr defn) "\n"))))
727
728 (defun ccide-replace-defun ()
729   "Replace the function header with the one on the top of the kill
730 ring (presumably placed there using c++-grab-prototype)."
731   (interactive)
732   (save-excursion
733     (c-beginning-of-defun-or-decl)
734     (let ((parse (c-parse-defun)))
735       (delete-region (or (aref parse 0)
736                          (aref parse 1)
737                          (aref parse 2))
738                      (or (aref parse 5)
739                          (aref parse 6)))
740       (yank)
741       (delete-char -3))))
742
743 (defun ccide-prefix-defun-type-with-class (&optional strip)
744   "If a non-keyword type symbol is found prefixing the current defun,
745 it will be prefixed with the current class prefix."
746   (interactive "p")
747   (save-excursion
748     (c-beginning-of-defun-or-decl)
749     (let* ((parse (c-parse-defun))
750            (prefix (c-scope-name (aref parse 2) (+ (or strip 0) 0))))
751       (goto-char (aref parse 1))
752       (while (and (or (looking-at c-any-key)
753                       (looking-at c-user-prefix-re)
754                       (not (c-at-symbol-p)))
755                   (< (point) (aref parse 2))
756                   (not (eobp)))
757         (c-forward-token-1)
758         (c-forward-syntactic-ws))
759       (if (and (c-at-symbol-p)
760                (< (point) (aref parse 2))
761                (not (looking-at (regexp-quote prefix))))
762           (let ((pos (string-match "<" prefix)))
763             (if (and pos (looking-at (concat (substring prefix 0 pos)
764                                              "\\b[^_]")))
765                 (progn
766                   (goto-char (match-end 0))
767                   (c-backward-syntactic-ws)
768                   (insert (substring prefix pos)))
769               (insert prefix "::"))
770             (ccide-reformat-defun))))))
771
772 (defun ccide-prefix-defun-type-with-namespace (&optional strip)
773   (interactive "p")
774   (ccide-prefix-defun-type-with-class (+ (or strip 0) 1)))
775
776 (defun ccide-insert-defun-prefix (&optional strip)
777   "Insert the current defun prefix at point."
778   (interactive "p")
779   (let* ((parse (c-parse-defun))
780          (prefix (c-scope-name (aref parse 2) (+ (or strip 0) 0))))
781     (insert prefix "::")))
782
783 (defun ccide-kill-inline-decl (defn)
784   (save-excursion
785     (if (aref (caddr defn) 6)
786         (progn
787           (goto-char (cdr (aref (caddr defn) 6)))
788           (let ((end-mark (point-marker)))
789             (goto-char (car (aref (caddr defn) 6)))
790             (indent-rigidly (point) end-mark
791                             (- (current-column)))
792             (prog1
793                 (concat (cadr defn)
794                         "\n"
795                         (buffer-substring-no-properties (point) end-mark)
796                         "\n")
797               (when (aref (caddr defn) 5)
798                 (goto-char (caar (aref (caddr defn) 5)))
799                 (c-backward-syntactic-ws)
800                 (skip-chars-backward ":"))
801               (c-backward-syntactic-ws)
802               (delete-region (point) end-mark)
803               (insert ";"))))
804       (concat (cadr defn) "\n{}\n"))))
805
806 (defun ccide-grab-inline-decl ()
807   "Grab the inline decl at point at turn it into an out-of-line inline
808 declaration at the top of the kill ring."
809   (interactive)
810   (let ((defn (c-build-defun (or ccide-default-prefix "inline"))))
811     (kill-new (ccide-kill-inline-decl defn))
812     (message (concat (or ccide-default-prefix "indline") 
813                      " " 
814                      (car defn)))))
815
816 (defun ccide-grab-all-inlines ()
817   "Grab all inline decls in the current class"
818   (interactive)
819   (let ((class (c-parse-class (c-get-block-scope)))
820         defns)
821     (when class
822       (loop for method in (nreverse (aref class 4))
823             do (when (eq (car method) 'method)
824                  (let ((defn (save-excursion
825                                (goto-char (cdr method))
826                                (c-build-defun (or ccide-default-prefix "inline")))))
827                    (if (aref (caddr defn) 6)
828                        (setq defns (nconc defns (list (ccide-kill-inline-decl defn))))))))
829       (kill-new (loop for defn in (nreverse defns)
830                       for next = nil then t
831                       if next concat "\n";
832                       concat defn))
833       (message (format "%d inlines grabed to kill ring" (length defns))))))
834                        
835
836 (defun ccide-grab-create-constructor ()
837   (interactive)
838   (let ((defn (c-build-create-constructor)))
839     (kill-new (cadr defn))
840     (message (car defn))))
841
842 (defun ccide-grab-create-constructor-impl (&optional prefix)
843   (interactive "P")
844   (let* ((prfx (or (and prefix (nth (prefix-numeric-value prefix) c-user-prefixes))
845                    ccide-default-prefix))
846          (defn (c-build-create-constructor-impl prfx)))
847     (kill-new (cadr defn))
848     (message (concat (or prfx "")
849                      (if prfx " " "")
850                      (car defn)))))
851
852 ;; (defun ccide-find-implementation (&optional other-window)
853 ;;   "Find implementation of method declared at point."
854 ;;   (interactive "P")
855 ;;   (let ((def (c-build-defun))
856 ;;      match pos)
857 ;;     (setq match (concat (regexp-quote (car def)) "[ \t\n\r]*("))
858 ;;     (setq match (string-replace "::" "::[ \t\n\r]*" match t nil t t))
859 ;;     (message match)
860 ;;     (loop for ext in ccide-implementation-extensions
861 ;;        do (let* ((filename (ccide-file-name ext))
862 ;;                  (buf (and (file-readable-p filename) (find-file-noselect filename))))
863 ;;             (if buf
864 ;;                 (save-excursion
865 ;;                   (set-buffer buf)
866 ;;                   (goto-char (point-min))
867 ;;                   (if (loop while (search-forward-regexp match nil t)
868 ;;                             do (forward-char -1)
869 ;;                             thereis (c-at-toplevel-p))
870 ;;                       (setq pos (cons buf (point)))))))
871 ;;        until pos)
872 ;;     (if pos
873 ;;      (let ((win (get-buffer-window (car pos))))
874 ;;           (if win
875 ;;               (select-window win)
876 ;;             (if other-window
877 ;;                 (switch-to-buffer-other-window (car pos))
878 ;;               (switch-to-buffer (car pos))))
879 ;;        (goto-char (cdr pos))
880 ;;        (forward-char -1)
881 ;;        (c-beginning-of-defun-or-decl))
882 ;;       (message (concat "Implementation of " (car def) " not found.")))))
883
884 (defun ccide-find-implementation (&optional other-window)
885   "Find implementation of method declared at point."
886   (interactive "P")
887   (let* ((state (c-get-defun-state))
888          (name (c-defun-short-name state))
889          (scoped-name (c-defun-full-name state))
890          (args (ccide-implementation-args state))
891          rv fallback)
892
893     (loop for ext in ccide-implementation-extensions
894           for filename = (ccide-file-name ext)
895           while (not rv)
896           do (progn
897                (let ((buf (or (find-buffer-visiting filename)
898                                   (and (file-readable-p filename)
899                                        (find-file-noselect filename)))))
900                  (when buf
901                    (let ((found (save-excursion
902                                   (set-buffer buf)
903                                   (ccide-find-implementation-1 name scoped-name args
904                                                                (car (aref state 2))))))
905                      (if found
906                          (if (cdr found)
907                              (setq rv (cons buf found))
908                            (if (not fallback) (setq fallback (cons buf found))))))))))
909     (if (not rv) (setq rv fallback))
910     (if rv
911         (let* ((buf (car rv))
912                (pos (cadr rv))
913                (win (get-buffer-window buf)))
914           (if win 
915               (select-window win)
916             (if other-window
917                 (switch-to-buffer-other-window buf)
918               (switch-to-buffer buf)))
919           (goto-char pos)
920           (forward-char -1)
921           (c-beginning-of-defun-or-decl))
922       (message (concat "Implementation of " scoped-name " not found.")))))
923
924 (defun ccide-implementation-args (state)
925   (string-replace "[ \t\n\r]+" ""
926                   (loop for (start . end) in (aref state 3)
927                         for sep = "" then ","
928                         concat sep
929                         concat (buffer-substring-no-properties 
930                                 start (save-excursion
931                                         (goto-char start)
932                                         (if (search-forward "=" end 'move) (forward-char -1))
933                                         (point))))
934                   
935                   t))
936
937 (defun ccide-find-implementation-1 (name scoped-name args skip-def)
938   ;; Within the current buffer, search for all implementations of the
939   ;; given function. The rv is a list of conses. The car holds the
940   ;; buffer position of the implementation, the cdr is t if the name,
941   ;; scoped-name and args are matched, otherwise the args did not match.
942   (save-excursion
943     (goto-char (point-min))
944     (let (fallback rv check-state)
945       (while (and (not rv) (search-forward name nil t))
946         (if (and (c-at-toplevel-p) 
947                  (not (c-in-literal))
948                  (setq check-state (condition-case nil (c-get-defun-state) (error nil)))
949                  (not (= (car (aref check-state 2)) skip-def)))
950             (if (string= scoped-name (c-defun-full-name check-state))
951                 (if (string= args (ccide-implementation-args check-state))
952                     (setq rv (cons (point) t))
953                   (if (not fallback) 
954                       (setq fallback (cons (point) nil)))))))
955       (or rv fallback))))
956
957 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
958 ;; variable/type level
959   
960 (defun ccide-variable-comment ()
961   "Add a comment to current variable declaration."
962   (interactive)
963   (push-mark)
964   (beginning-of-line)
965   (open-line 1)
966   (insert "/// ")
967   (indent-according-to-mode))
968
969 (defun ccide-grab-access-fn ()
970   (interactive)
971   (save-excursion
972     (beginning-of-line)
973     (if (looking-at (concat c++-simple-type-regexp "[ \t\n\r][a-zA-Z0-9_]+[ \t\n\r]*;"))
974         (let ((vardef (match-string 0))
975               (in (make-string c-basic-offset ? ))
976               type varname ws doc)
977           (forward-line -1)
978           (back-to-indentation)
979           (if (looking-at "///[ \t\n\r]*")
980               (setq doc (buffer-substring (match-end 0)
981                                           (progn (end-of-line) (point)))))
982           (string-match "^[ \t\n\r]*\\(.*\\)[ \t\n\r]\\([a-zA-Z0-9_]+\\)[ \t\n\r]*;$"
983                         vardef)
984           (setq varname (match-string 2 vardef)
985                 type (match-string 1 vardef)
986                 ws (substring vardef 0 (match-beginning 1)))
987           (if (string-match "^[ \t\n\r]*" type)
988               (setq type (substring type (match-end 0))))
989           (kill-new (concat (if doc
990                                 (concat ws "/** Setze " doc ".\n\n"
991                                         ws "    @param _" varname " neu: " doc "\n"
992                                         ws "    @return alt: " doc "\n"
993                                         ws " */\n")
994                               "")
995                             ws type " q_" varname "(" type " _" varname ")\n"
996                             ws in "{\n"
997                             ws in in type " old" varname " = " varname ";\n"
998                             ws in in varname " = _" varname ";\n"
999                             ws in in "return(old" varname ");\n"
1000                             ws in "}\n\n"
1001                             (if doc
1002                                 (concat ws "/** Hole " doc ".\n\n"
1003                                         ws "    @return " doc "\n"
1004                                         ws "*/\n")
1005                               "")
1006                             ws type " q_" varname "(void) const\n"
1007                             ws in "{ return(" varname "); }\n"))
1008           
1009           (message varname))
1010       (message "No variable found"))))
1011
1012 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1013 ;; doxy comment support functions
1014
1015 (defun ccide-special-indent-function ()
1016   "Function to indent doxy comments correctly"
1017   (let ((indent (ccide-in-doxy-comment)))
1018     (if indent
1019         (let ((lim (save-excursion
1020                      (back-to-indentation)
1021                      (c-literal-limits)))
1022               (pos (- (point-max) (point))))
1023           (incf indent 4)
1024           (save-excursion
1025             (back-to-indentation)
1026             (if (looking-at "*/")
1027                 (incf indent -3)
1028               (let ((para (or (save-excursion (re-search-backward "^\\s-*$" (car lim) t))
1029                               (car lim))))
1030                 (if (and (not (looking-at ccide-doxy-tag-re))
1031                          (re-search-backward (concat "^\\s-*"
1032                                                      ccide-doxy-tag-re)
1033                                              para t))
1034                     (incf indent 4)))))
1035           (delete-region (progn (beginning-of-line) (point))
1036                          (progn (back-to-indentation) (point)))
1037           (indent-to indent)
1038           (if (> (- (point-max) pos) (point))
1039               (goto-char (- (point-max) pos)))))))
1040   
1041 (defun ccide-fill-function ()
1042   "auto-fill function for doxy comments"
1043   (if (do-auto-fill)
1044       (if (not fill-prefix)
1045           (indent-according-to-mode))))
1046
1047 (defun ccide-hide-all-doxy-comments ()
1048   "Hide all doxy comments"
1049   (interactive)
1050   (save-excursion
1051     (goto-char (point-min))
1052     (while (re-search-forward "^\\s-*/\\*\\*" nil t)
1053       (beginning-of-line)
1054       (forward-line -1)
1055       (if (not (looking-at "\\s-*$"))
1056           (forward-line 1))
1057       (forward-char -1)
1058       (let ((start (point)))
1059         (if (re-search-forward "\\*/" nil t)
1060             (progn
1061               (if (looking-at "\\s-*\n")
1062                   (forward-line 1))
1063               (forward-char -1)
1064               (let ((overlay (make-overlay start (point))))
1065                 (overlay-put overlay 'intangible 'hs)
1066                 (overlay-put overlay 'invisible 'hs)))))))
1067   (message "Done."))
1068
1069 (defun ccide-show-all-comments ()
1070   "Show all comments"
1071   (interactive)
1072   (save-excursion
1073     (goto-char (point-min))
1074     (while (not (eobp))
1075       (goto-char (next-overlay-change (point)))
1076       (loop for overlay in (overlays-at (point))
1077             if (eq (overlay-get overlay 'invisible) 'hs)
1078             do (delete-overlay overlay))))
1079   (message "Done."))
1080
1081
1082
1083 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1084 ;; CORBA support (omniORB2)
1085
1086 (defun ccide-get-corba-headers ()
1087   (let (files)
1088     (save-excursion
1089       (goto-char (point-min))
1090       (while (re-search-forward "#include\\s-*[\"<]\\([^\">]*\\)\\.hh[\">]" nil t)
1091         (setq files (cons (ccide-match-string 1) files)))
1092       (nreverse files))))
1093
1094 (defun ccide-corba-maybe-build-hh (file)
1095   (let ((skel (ccide-file-name ".hh" file ccide-corba-skel-dir))
1096         (idl (ccide-file-name ".idl" file ccide-corba-idl-dir)))
1097     (if (and (file-readable-p idl)
1098              (or (not (file-readable-p skel))
1099                  (file-newer-than-file-p idl skel)))
1100         (let ((buffer (find-buffer-visiting (ccide-file-name ".hh" file))))
1101           (if buffer
1102               (kill-buffer buffer))
1103           (message "Please wait ... building %s" (ccide-file-name ".hh" file))
1104           (if (ccide-shell-command (concat "cd " 
1105                                            (real-path-name ccide-corba-skel-dir) 
1106                                            " && " 
1107                                            ccide-corba-idl-command 
1108                                            (if (> (length ccide-corba-idl-dir) 0)
1109                                                (concat " -I" ccide-corba-idl-dir))
1110                                            " " 
1111                                            idl))
1112               ()
1113             (display-buffer (get-buffer-create "*ccide shell command*"))
1114             (error "Generation of %s failed" (ccide-file-name ".hh")))))
1115     (if (not (file-readable-p skel))
1116         (error "No file %s or %s" 
1117                (ccide-file-name ".hh" file) (ccide-file-name ".idl" file)))))
1118
1119 (defun ccide-corba-list-skeletons-1 (hh-file)
1120   (ccide-corba-maybe-build-hh hh-file)
1121   (let ((hh-buf (find-file-noselect (ccide-file-name ".hh" hh-file)))
1122         skels)
1123     (save-excursion
1124       (set-buffer hh-buf)
1125       (save-excursion
1126         (goto-char (point-min))
1127         (while (re-search-forward "^\\s-*class\\s-+_sk_\\([a-zA-Z0-9_]+\\)\\s-+:"
1128                                   nil t)
1129           (setq skels (cons (ccide-match-string 1) skels)))))
1130     (mapcar (function (lambda (x) (cons x hh-file)))
1131             (sort skels 'string-lessp))))
1132
1133 (defun ccide-corba-list-skeletons ()
1134   (let ((files (ccide-get-corba-headers)))
1135     (loop for file in files
1136           append (ccide-corba-list-skeletons-1 file))))
1137
1138 (defun ccide-gen-corba-impl (class)
1139   (interactive (list (completing-read "Class name of skeleton: "
1140                                       (ccide-corba-list-skeletons)
1141                                       nil t)))
1142   (let* ((skels (ccide-corba-list-skeletons))
1143          (hh-file (ccide-file-name ".hh" (cdr (assoc class skels))
1144                                    ccide-corba-skel-dir))
1145          (hh-buf (find-file-noselect (ccide-file-name ".hh" hh-file
1146                                                       ccide-corba-skel-dir))))
1147     (ccide-gen-class (concat class "_i"))
1148     (insert (make-string c-basic-offset ? ) ": public virtual _sk_" class "\n")
1149     (save-excursion
1150       (search-forward "protected:" nil t)
1151       (forward-line -1)
1152       (ccide-gen-corba-impl-methods)
1153       (insert "\n"))))
1154
1155 (defun ccide-get-corba-defns (hh-file class)
1156   (let ((hh-buf (find-file-noselect hh-file))
1157         defns)
1158     (save-excursion
1159       (set-buffer hh-buf)
1160       (save-excursion
1161         (goto-char (point-min))
1162         (if (not (re-search-forward (concat "^\\s-*class\\s-+_sk_" class "\\s-+:")
1163                                     nil t))
1164             (error "CORBA skeleton class not found.")
1165           (search-forward "{")
1166           (forward-char -1)
1167           (let ((end (save-excursion (forward-sexp) (point))))
1168             (while (and (< (point) end)
1169                         (< (forward-line 1) 1))
1170               (if (looking-at "\\s-+virtual\\s-+\\(.*)\\)\\s-*=\\s-*0;\\s-*$")
1171                   (setq defns (cons (match-string 1) defns))))))))
1172     (nreverse defns)))
1173
1174 (defun ccide-gen-corba-impl-methods ()
1175   (interactive)
1176   (let* ((class (c-get-class-at-point))
1177          (point (point)))
1178     (if (not class)
1179         (error "No class at point."))
1180     (save-excursion
1181       (goto-char (aref (car class) 1))
1182       (if (not (re-search-forward ":\\s-*public\\s-*virtual\\s-*_sk_\\([^ \t\n\r{},:]*\\)"
1183                                   nil t))
1184           (error "No CORBA impl at point."))
1185       (let* ((name (ccide-match-string 1))
1186              (skels (ccide-corba-list-skeletons))
1187              (hh-file (ccide-file-name ".hh" (cdr (assoc name skels))
1188                                        ccide-corba-skel-dir))
1189              (defns (ccide-get-corba-defns hh-file name))
1190              end)
1191         (goto-char (aref (car class) 2))
1192         (save-excursion
1193           (c-forward-sexp)
1194           (setq end (point)))
1195         (if (re-search-forward "^\\s-*// CORBA$" end t)
1196             (let ((start (match-beginning 0)))
1197               (if (re-search-forward "^\\s-*// END-CORBA$" end t)
1198                   (let ((eend (match-end 0)))
1199                     (goto-char start)
1200                     (forward-line 1)
1201                     (if (re-search-forward "/\\*\\|//" (match-beginning 0) t)
1202                         (if (y-or-n-p "Remove CORBA Funktion comments? (y/n)")
1203                             (delete-region start (1+ eend))
1204                           (goto-char eend)
1205                           (beginning-of-line)
1206                           (delete-region (point) (progn 
1207                                                    (end-of-line)
1208                                                    (1+ (point))))
1209                           (save-excursion
1210                             (goto-char start)
1211                             (delete-region (point) (progn 
1212                                                      (end-of-line)
1213                                                      (1+ (point)))))
1214                           (insert "\n"))
1215                       (delete-region start (1+ eend))))))
1216           (goto-char point))
1217         (indent-according-to-mode)
1218         (insert "// CORBA\n")
1219         (loop for defn in defns
1220               do (progn
1221                    (save-excursion (insert defn ";"))
1222                    (indent-according-to-mode)
1223                    (let ((start (point)) end)
1224                      (end-of-line)
1225                      (setq end (point))
1226                      (goto-char start)
1227                      (while (re-search-forward "\\s-+" end t)
1228                        (replace-match " ")
1229                        (setq end (- end (- (match-end 0) (match-beginning 0) 1))))
1230                      (end-of-line)
1231                      (loop with done = nil
1232                            while (> (current-column) c-max-def-column)
1233                            do (while (and (> (current-column) c-max-def-column)
1234                                           (search-backward "," start t)))
1235                            do (if (looking-at ",")
1236                                   (progn
1237                                     (forward-char 1)
1238                                     (insert "\n")
1239                                     (open-line 1)
1240                                     (indent-according-to-mode)
1241                                     (delete-char 2)
1242                                     (setq start (point))
1243                                     (end-of-line))
1244                                 (setq done t))
1245                            while (not done)))
1246                    (insert "\n")))
1247         (indent-according-to-mode)
1248         (insert "// END-CORBA\n")))))
1249
1250 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1251 ;; template support
1252
1253 (defun ccide-scan-mantemps ()
1254   "Scan *compilation* buffer for errors and generate manual template
1255 instatiations at point."
1256   (interactive)
1257   (save-excursion
1258     (set-buffer "*compilation*")
1259     (goto-char (point-min)))
1260   (save-excursion
1261     (set-buffer (get-buffer-create "*mantemps*"))
1262     (erase-buffer)
1263     (loop for temp = (ccide-get-mantemp)
1264           while temp
1265           do (insert temp "\n"))
1266     (mantemp-make-mantemps-buffer)
1267     (goto-char (point-min))
1268     (while (progn
1269              (ccide-fix-mantemp)
1270              (< (forward-line 1) 1))))
1271   (insert-buffer-substring "*mantemps*"))
1272
1273 (defun ccide-get-mantemp ()
1274   (save-excursion
1275     (set-buffer "*compilation*")
1276     (if (search-forward "undefined reference to `" nil t)
1277         (let ((start (point)))
1278           (end-of-line)
1279           (search-backward "'" nil t)
1280           (buffer-substring start (point))))))
1281
1282 (defun ccide-fix-mantemp ()
1283   (let ((end (save-excursion
1284                (end-of-line) (point))))
1285     (if (and (save-excursion (search-forward "(" end t))
1286              (search-forward " class" end t))
1287         (progn
1288           (forward-char -6)
1289           (delete-char 6)))))
1290       
1291 (provide 'cc-ide)
1292
1293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1294 ;; other stuff
1295
1296 (defun ccide-open-compilation-frame ()
1297   (interactive)
1298   (let ((c-frame (selected-frame))
1299         (compilation-frame (make-frame '((minibuffer . nil) 
1300                                          (unsplittable . t) 
1301                                          (menu-bar-lines . 0) 
1302                                          (top . -87) 
1303                                          (left . 36) 
1304                                          (width . 169) 
1305                                          (height . 9)))))
1306     (select-frame compilation-frame)
1307     (switch-to-buffer "*compilation*")
1308     (set-window-dedicated-p (selected-window) t)))
1309
1310 (defun ccide-compile (command)
1311   (delete-other-windows)
1312   (split-window-horizontally)
1313   (compile command)
1314   (save-excursion
1315     (set-buffer "*compilation*")
1316     (let ((point (point-max)))
1317       (goto-char point)
1318       (loop for window in (get-buffer-window-list "*compilation*" nil t)
1319             do (set-window-point window point)))))
1320
1321 (defun ccide-compile-compile ()
1322   (interactive)
1323   (ccide-compile (concat "make -k " ccide-compile-opts)))
1324
1325 (defun ccide-compile-clean ()
1326   (interactive)
1327   (ccide-compile (concat "make -k " ccide-compile-opts " clean")))
1328
1329 (defun ccide-compile-cleandepends ()
1330   (interactive)
1331   (ccide-compile (concat "make -k " ccide-compile-opts " cleandepends")))
1332
1333 (defun ccide-compile-kill ()
1334   (interactive)
1335   (set-buffer "*compilation*")
1336   (kill-compilation))
1337
1338 (defun ccide-hide-compilation ()
1339   (interactive)
1340   (let ((active (selected-window)))
1341     (unwind-protect
1342         (loop for window in (get-buffer-window-list "*compilation*")
1343               do (progn (select-window window)
1344                         (switch-to-buffer (other-buffer "*compilation*"))))
1345       (select-window active))))
1346
1347 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1348 ;; keymap and installation
1349
1350 (defun ccide-bind-keys (prefix map)
1351   (loop for binding in ccide-bindings
1352         do (apply 'vcmd-define-key
1353                   map
1354                   (concat prefix (car binding))
1355                   (cadr binding)
1356                   "IDE"
1357                   (cddr binding))))
1358
1359 (defun ccide-install-it ()
1360   (save-excursion
1361     (hs-minor-mode 1)
1362     (hs-show-all))
1363   (local-unset-key "\C-c;")
1364   (local-unset-key [menu-bar IDE])
1365   (ccide-bind-keys "\C-c;" (current-local-map))
1366   (local-set-key "\C-cC" 'ccide-hide-all-doxy-comments)
1367   (local-set-key "\C-cS" 'ccide-show-all-comments)
1368   (set (make-local-variable 'auto-fill-function) 'ccide-fill-function)
1369   (auto-fill-mode -1)
1370   (ccide-auto-decorate-new-files))
1371
1372 (add-hook 'c-mode-hook 'ccide-install-it)
1373 (add-hook 'c++-mode-hook 'ccide-install-it)
1374 (add-hook 'c-special-indent-hook 'ccide-special-indent-function)
1375
1376 (loop for extension in ccide-special-extensions
1377       for re = (concat (regexp-quote extension) "$")
1378       if (not (assoc re auto-mode-alist))
1379         do (setq auto-mode-alist (append auto-mode-alist
1380                                          (list (cons re 'c++-mode)))))
1381
1382 (defadvice c-indent-line (after c-indent-less compile disable) ;activate
1383   ;; new indent function for c-mode: do standard indentation first. If line
1384   ;; is to long using standard indentation, just indent by c-basic-indentation.
1385   (let ((cc (save-excursion (end-of-line) (current-column)))
1386         indent)
1387     (if (> cc  85)
1388         (let ((pos (- (point-max) (point))))
1389           (beginning-of-line)
1390           (let ((point (point))
1391                 (line (1+ (count-lines 1 (point))))
1392                 indent)
1393             (c-beginning-of-statement-2)
1394             (if (and (not (c-crosses-statement-barrier-p (point) point))
1395                      (not (eq (+ (count-lines 1 (point))
1396                                  (if (bolp) 1 0))
1397                               line)))
1398                 (progn
1399                   (setq indent (+ (current-indentation) c-basic-offset))
1400                   (goto-char point)
1401                   (if (< indent (current-indentation))
1402                       (progn
1403                         (setq ad-return-value
1404                               (+ ad-return-value
1405                                  (- (current-indentation) indent)))
1406                         (delete-region (c-point 'bol) (c-point 'boi))
1407                         (indent-to indent))))))
1408           (if (< (point) (c-point 'boi))
1409               (back-to-indentation)
1410             (if (> (- (point-max) pos) (point))
1411                 (goto-char (- (point-max) pos))))))))
1412
1413
1414 \f
1415 ;;; Local Variables:
1416 ;;; elisp-project-autoload-file-name: "cc-autoload.el"
1417 ;;; End: