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