2
;; $XORP: xorp/devnotes/kdoc.el,v 1.1.1.1 2002/12/11 23:55:54 hodson Exp $
4
;; This file is a modification of the original gnome-doc.el
5
;; The original copyright message is included below.
8
;; Copyright (C) 1998 Michael Zucchi
10
;; This program is free software; you can redistribute it and/or
11
;; modify it under the terms of the GNU General Public License as
12
;; published by the Free Software Foundation; either version 2 of
13
;; the License, or (at your option) any later version.
15
;; This program is distributed in the hope that it will be
16
;; useful, but WITHOUT ANY WARRANTY; without even the implied
17
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18
;; PURPOSE. See the GNU General Public License for more details.
20
;; You should have received a copy of the GNU General Public
21
;; License along with this program; if not, write to the Free
22
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28
;; This file auto-generates a C or C++ function document header from the
31
;; Load into emacs and use C-x5, or M-x kdoc-insert to insert
32
;; a new header for the current function. You have to be somewhere in
33
;; the body of the function you wish to document.
35
;; The default header format is setup to do 'kdoc' style headers.
36
;; These headers are used in the KDE project to automatically
37
;; produce SGML API documentation directly from the source code.
39
;; These headers look something like this (the cursor is left at
47
;; * @param param1 the parameter that ...
48
;; * @param param2 the parameter that ...
51
;; int function_name(char *param1, int param2)
55
;; It should be able to transform this into quite a few different
56
;; header formats by customising the options.
58
;; For example, for a more gnu-ish header style, the following
59
;; settings could be used:
61
;; (setq-default kdoc-header "/* %s\n")
62
;; or for no function name in the header:
63
;; (setq-default kdoc-header "/* \n")
65
;; (setq-default kdoc-blank " \n")
66
;; or for more compact version:
67
;; (setq-default kdoc-blank "")
69
;; (setq-default kdoc-parameter " %s \n")
70
;; or to exclude parameters:
71
;; (setq-default kdoc-parameter "")
73
;; (setq-default kdoc-trailer " */\n")
74
;; (setq-default kdoc-section " %s \n")
75
;; (setq-default kdoc-match-block "^ ")
76
;; (setq-default kdoc-match-header "^/\\*")
78
;; The important thing is to ensure all lines match
79
;; the kdoc-match-block regular expression.
81
;; This will produce something like this:
93
;; With the blank line defined as "", a much more
94
;; compact version is generated:
103
;; This is my first attempt at anything remotely lisp-like, you'll just
104
;; have to live with it :)
106
;; It works ok with emacs-20, AFAIK it should work on other versions too.
109
"Generates automatic headers for functions"
113
(defcustom kdoc-header "/**\n * \n"
114
"Start of documentation header.
116
Using '%s' will expand to the name of the function."
120
(defcustom kdoc-h-header " /**\n * \n"
121
"Start of documentation header.
123
Using '%s' will expand to the name of the function."
127
(defcustom kdoc-class-header "/**\n * @short \n"
128
"Start of documentation class header."
132
(defcustom kdoc-blank " * \n"
133
"Used to put a blank line into the header."
137
(defcustom kdoc-h-blank " * \n"
138
"Used to put a blank line into the header."
142
(defcustom kdoc-class-blank " * \n"
143
"Used to put a blank line into the class header."
147
(defcustom kdoc-trailer " */\n"
148
"End of documentation header.
150
Using '%s' will expand to the name of the function being defined."
154
(defcustom kdoc-h-trailer " */\n"
155
"End of documentation header.
157
Using '%s' will expand to the name of the function being defined."
161
(defcustom kdoc-class-trailer " */\n"
162
"End of documentation class header."
166
(defcustom kdoc-parameter " * @param %s \n"
167
"Used to add another parameter to the header.
169
Using '%s' will be replaced with the name of the parameter."
173
(defcustom kdoc-h-parameter " * @param %s \n"
174
"Used to add another parameter to the header.
176
Using '%s' will be replaced with the name of the parameter."
180
(defcustom kdoc-section " * %s \n"
181
"How to define a new section in the output.
183
Using '%s' is replaced with the name of the section.
184
Currently this will only be used to define the 'return value' field."
188
(defcustom kdoc-h-section " * %s \n"
189
"How to define a new section in the output.
191
Using '%s' is replaced with the name of the section.
192
Currently this will only be used to define the 'return value' field."
196
(defcustom kdoc-class-section " * %s \n"
197
"How to define a new section in the output.
199
Using '%s' is replaced with the name of the section."
203
(defcustom kdoc-match-block "^ \\*"
204
"Regular expression which matches all lines in the header.
206
It should match every line produced by any of the header specifiers.
207
It is therefore convenient to start all header lines with a common
212
(defcustom kdoc-h-match-block "^ \\*"
213
"Regular expression which matches all lines in the header.
215
It should match every line produced by any of the header specifiers.
216
It is therefore convenient to start all header lines with a common
221
(defcustom kdoc-class-match-block "^ \\*"
222
"Regular expression which matches all lines in the class header.
224
It should match every line produced by any of the header specifiers.
225
It is therefore convenient to start all header lines with a common
230
(defcustom kdoc-match-header "^/\\*\\*"
231
"Regular expression which matches the first line of the header.
233
It is used to identify if a header has already been applied to this
234
function. It should match the line produced by kdoc-header, or
235
at least the first line of this which matches kdoc-match-block"
239
(defcustom kdoc-h-match-header "^ /\\*\\*"
240
"Regular expression which matches the first line of the header.
242
It is used to identify if a header has already been applied to this
243
function. It should match the line produced by kdoc-h-header, or
244
at least the first line of this which matches kdoc-h-match-block"
248
(defcustom kdoc-class-match-header "^/\\*\\*"
249
"Regular expression which matches the first line of the class header.
251
It is used to identify if a header has already been applied to this
252
function. It should match the line produced by kdoc-class-header, or
253
at least the first line of this which matches kdoc-class-match-block"
258
(make-variable-buffer-local 'kdoc-header)
259
(make-variable-buffer-local 'kdoc-trailer)
260
(make-variable-buffer-local 'kdoc-parameter)
261
(make-variable-buffer-local 'kdoc-section)
262
(make-variable-buffer-local 'kdoc-blank)
263
(make-variable-buffer-local 'kdoc-match-block)
264
(make-variable-buffer-local 'kdoc-match-header)
265
(make-variable-buffer-local 'kdoc-h-header)
266
(make-variable-buffer-local 'kdoc-h-trailer)
267
(make-variable-buffer-local 'kdoc-h-parameter)
268
(make-variable-buffer-local 'kdoc-h-section)
269
(make-variable-buffer-local 'kdoc-h-blank)
270
(make-variable-buffer-local 'kdoc-h-match-block)
271
(make-variable-buffer-local 'kdoc-h-match-header)
272
(make-variable-buffer-local 'kdoc-class-header)
273
(make-variable-buffer-local 'kdoc-class-trailer)
274
;(make-variable-buffer-local 'kdoc-class-parameter)
275
(make-variable-buffer-local 'kdoc-class-section)
276
(make-variable-buffer-local 'kdoc-class-blank)
277
(make-variable-buffer-local 'kdoc-class-match-block)
278
(make-variable-buffer-local 'kdoc-class-match-header)
281
;; insert header at current location
282
(defun kdoc-insert-header (function)
283
(insert (format kdoc-header function)))
284
(defun kdoc-h-insert-header (function)
285
(insert (format kdoc-h-header function)))
286
(defun kdoc-class-insert-header ()
287
(insert kdoc-class-header))
289
;; insert a single variable, at current location
290
(defun kdoc-insert-var (var)
291
(insert (format kdoc-parameter var)))
292
(defun kdoc-h-insert-var (var)
293
(insert (format kdoc-h-parameter var)))
294
(defun kdoc-class-insert-var (var)
295
(insert (format kdoc-class-parameter var)))
297
;; insert a 'blank' comment line
298
(defun kdoc-insert-blank ()
300
(defun kdoc-h-insert-blank ()
301
(insert kdoc-h-blank))
302
(defun kdoc-class-insert-blank ()
303
(insert kdoc-class-blank))
305
;; insert a section comment line
306
(defun kdoc-insert-section (section)
307
(insert (format kdoc-section section)))
308
(defun kdoc-h-insert-section (section)
309
(insert (format kdoc-h-section section)))
310
(defun kdoc-class-insert-section (section)
311
(insert (format kdoc-class-section section)))
313
;; insert the end of the header
314
(defun kdoc-insert-footer (func)
315
(insert (format kdoc-trailer func)))
316
(defun kdoc-h-insert-footer (func)
317
(insert (format kdoc-h-trailer func)))
318
(defun kdoc-class-insert-footer ()
319
(insert kdoc-class-trailer))
321
(defun kdoc-insert ()
322
"Add a documentation header to the current function.
323
Only C/C++ function types are properly supported currently."
325
(let (c-insert-here (point))
334
(search-backward "(")
336
(while (or (looking-at "^$")
341
(if (or (looking-at ".*void.*(")
342
(looking-at ".*void[ \t]*$"))
345
(if (re-search-forward "\\([A-Za-z0-9_:~]+\\)[ \t\n]*[^(]*\\(([^)]*)\\)" c-point nil)
346
(let ((c-argstart (match-beginning 2))
347
(c-argend (match-end 2)))
348
(setq c-funcname (buffer-substring (match-beginning 1) (match-end 1)))
349
(goto-char c-argstart)
350
(while (re-search-forward "\\([A-Za-z0-9_]*\\) *[,)=]" c-argend t)
353
(list (buffer-substring (match-beginning 1) (match-end 1)))))))))
354
;; find C++ class name and class method
355
;; if this is a class constructor, or destructor, the function is void
356
(if (string-match "::~" c-funcname)
358
(setq cxx-class-name (substring c-funcname 0 (match-beginning 0)))
359
(setq cxx-class-method (substring c-funcname (match-end 0)))
360
( if (string-equal cxx-class-name cxx-class-method)
362
(if (string-match "::" c-funcname)
364
(setq cxx-class-name (substring c-funcname 0 (match-beginning 0)))
365
(setq cxx-class-method (substring c-funcname (match-end 0)))
366
( if (string-equal cxx-class-name cxx-class-method)
367
(setq c-isvoid 1)))))
369
;; see if we already have a header here ...
372
(while (looking-at kdoc-match-block)
374
(if (looking-at kdoc-match-header)
375
(error "Header already exists")
376
(setq c-doinsert t)))
381
(kdoc-insert-header c-funcname)
382
;; record the point of insertion
383
(setq c-insert-here (- (point) 1))
385
;; the blank space for description
388
(setq kdoc-extra-blank 0)
393
(setq c-arg (car c-arglist))
394
(setq c-arglist (cdr c-arglist))
395
(if (> (length c-arg) 0)
397
(if (= kdoc-extra-blank 0)
400
(setq kdoc-extra-blank 1)))
401
(kdoc-insert-var c-arg))))
403
;; insert a return value only if we have one ...
406
(if (= kdoc-extra-blank 0)
409
(setq kdoc-extra-blank 1)))
410
(kdoc-insert-section "@return")))
412
(kdoc-insert-footer c-funcname)))))
414
;; goto the start of the description saved above
415
(goto-char c-insert-here)))
418
(defun kdoc-h-insert ()
419
"Add a documentation header to the current function declaration.
420
Only C/C++ function types are properly supported currently."
422
(let (c-insert-here (point))
425
(search-forward ")");
426
;; (beginning-of-defun)
433
(search-backward "(")
435
(if (or (looking-at ".*void.*(")
436
(looking-at ".*void[ \t]*$")
437
(looking-at "[ \t]*\\(virtual[ \t]+\\)?[A-Za-z]+[A-Za-z0-9_]*[ \t]*(")
438
(looking-at "[ \t]*\\(virtual[ \t]+\\)?~[A-Za-z]+[A-Za-z0-9_]*[ \t]*("))
441
(if (re-search-forward "\\([A-Za-z0-9_:~]+\\)[ \t\n]*[^(]*\\(([^)]*)\\)" c-point nil)
442
(let ((c-argstart (match-beginning 2))
443
(c-argend (match-end 2)))
444
(setq c-funcname (buffer-substring (match-beginning 1) (match-end 1)))
445
(goto-char c-argstart)
446
(while (re-search-forward "\\([A-Za-z0-9_]*\\) *[,)=]" c-argend t)
449
(list (buffer-substring (match-beginning 1) (match-end 1)))))))))
451
;; see if we already have a header here ...
454
(while (looking-at kdoc-h-match-block)
456
(if (looking-at kdoc-h-match-header)
457
(error "Header already exists")
458
(setq c-doinsert t)))
463
(kdoc-h-insert-header c-funcname)
464
;; record the point of insertion
465
(setq c-insert-here (- (point) 1))
467
;; the blank space for description
468
(kdoc-h-insert-blank)
469
(kdoc-h-insert-blank)
470
(setq kdoc-h-extra-blank 0)
475
(setq c-arg (car c-arglist))
476
(setq c-arglist (cdr c-arglist))
477
(if (> (length c-arg) 0)
479
(if (= kdoc-h-extra-blank 0)
481
(kdoc-h-insert-blank)
482
(setq kdoc-h-extra-blank 1)))
483
(kdoc-h-insert-var c-arg))))
485
;; insert a return value only if we have one ...
488
(if (= kdoc-h-extra-blank 0)
490
(kdoc-h-insert-blank)
491
(setq kdoc-h-extra-blank 1)))
492
(kdoc-h-insert-section "@return")))
494
(kdoc-h-insert-footer c-funcname)))))
496
;; goto the start of the description saved above
497
(goto-char c-insert-here)))
499
(defun kdoc-class-insert ()
500
"Add a documentation header to the current C++ class declaration."
502
(let (c-insert-here (point))
504
;; (re-search-backward "^[ \t\n]*\\(\\(export[ \t\n]+\\)?\\(template[ \t\n]*\\)<.*>[ \t\n]*\\)?class[ \t\n]+")
505
(re-search-backward "[ \t\n]*class[ \t\n]+")
507
(while (looking-at "^[ \t]*$")
509
;; check if a template with some of the keywords split over 1+ lines
510
(if (looking-at "^[ \t]*class[ \t\n]+")
513
(if (not (looking-at "^[ \t]*\\(export[ \t]+\\)*template[ \t]*<.*>[ \t]*$"))
516
(let ((c-point (point))
518
;; see if we already have a header here ...
521
(while (looking-at kdoc-class-match-block)
523
(if (looking-at kdoc-class-match-header)
524
(error "Header already exists")
525
(setq c-doinsert t)))
530
(kdoc-class-insert-header)
531
;; record the point of insertion
532
(setq c-insert-here (- (point) 1))
534
;; the blank space for description
535
(kdoc-class-insert-blank)
536
(kdoc-class-insert-blank)
537
(kdoc-class-insert-footer)))))
539
;; goto the start of the description saved above
540
(goto-char c-insert-here)))
543
;; set global binding for this key (follows the format for
544
;; creating a changelog entry ...)
545
(global-set-key "\C-x5h" 'kdoc-insert)
546
(global-set-key "\C-x6h" 'kdoc-h-insert)
547
(global-set-key "\C-x7h" 'kdoc-class-insert)