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