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