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