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