Patchwork [RFC] Stop putting function comments in foo.h

login
register
mail settings
Submitter Doug Evans
Date March 26, 2014, 7:05 p.m.
Message ID <21299.9450.36720.381593@ruffy.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/302/
State New
Headers show

Comments

Doug Evans - March 26, 2014, 7:05 p.m.
Doug Evans writes:
 > On Tue, Mar 18, 2014 at 8:59 AM, Doug Evans <dje@google.com> wrote:
 > > On Mon, Mar 17, 2014 at 9:07 AM, Pedro Alves <palves@redhat.com> wrote:
 > >> IMO, a module's API documentation should be in its header file, as
 > >> that's where the module's "public" contract is defined.
 > >> Needing to peek at the module's implementation feels wrong to me.
 > >> If the function's documentation isn't clear without looking
 > >> at the function's body, something is already wrong with
 > >> the comment.
 > >
 > > It use to be that M-. took me to the function definition and its documentation.
 > >
 > > I'm curious what other emacs+etags users do now.
 > 
 > fwiw, I'd REALLY like an answer to this.
 > 
 > M-. worked great before people started moving function comments to headers.
 > I can be looking at any function in the source, put the cursor over
 > its name, M-. RET, and voila!  I'm reading the function's comment or I
 > I can begin hacking/reading its implementation.
 > 
 > People are breaking a common existing practice without offering a
 > replacement.  Why isn't that "Not cool."?
 > If I'm missing something I'll happily document it in the wiki, augment
 > Makefile's, or whatever.
 > I just want to continue to be able to hack on gdb as easily as I could
 > before people started doing this.

Ok, so here's a first pass at something to alleviate the growing pain.  Bleah.
It's just a prototype, but it seems to have promise in my initial testing.

2014-03-26  Doug Evans  <dje@google.com>

	* Makefile.in (DTAGS): New rule.
	(tags): Add DTAGS dependency.
	* contrib/dtags.el: New file.

Patch

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3efedc8..f20512a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1346,9 +1346,11 @@  gdb1$(EXEEXT): gdb$(EXEEXT)
 # Put the proper machine-specific files first, so M-. on a machine
 # specific routine gets the one for the correct machine.  (FIXME: those
 # files go in twice; we should be removing them from the main list).
-
-# TAGS depends on all the files that go into it so you can rebuild TAGS
-# with `make TAGS' and not have to say `rm TAGS' first.
+# TAGS,DTAGS depend on all the files that go into them so they can be
+# rebuilt without having to remove them first.
+# Because more and more function comments are being moved to headers,
+# we now create a second tags file, DTAGS, which contains just the
+# headers.  See contrib/dtags.el for example code on how to use it.
 
 GDB_NM_FILE = @GDB_NM_FILE@
 TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR)
@@ -1361,7 +1363,16 @@  TAGS: $(TAGFILES_NO_SRCDIR) $(TAGFILES_WITH_SRCDIR)
 	done) | sed -e 's/\.o$$/\.c/'` \
 	`find $(srcdir)/config -name '*.h' -print`
 
-tags: TAGS
+DTAGS: $(HFILES_NO_SRCDIR) $(HFILES_WITH_SRCDIR)
+	@echo Making DTAGS
+	etags -o $@ --declarations \
+	    `(for i in $(HFILES_NO_SRCDIR); do \
+		echo $(srcdir)/$$i ; \
+	done ; for i in $(HFILES_WITH_SRCDIR); do \
+		echo $$i ; \
+	done)`
+
+tags: TAGS DTAGS
 
 clean mostlyclean: $(CONFIG_CLEAN)
 	@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do
diff --git a/gdb/contrib/dtags.el b/gdb/contrib/dtags.el
new file mode 100644
index 0000000..a90783c
--- /dev/null
+++ b/gdb/contrib/dtags.el
@@ -0,0 +1,73 @@ 
+;; DTAGS support.
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; DTAGS is just a variant of TAGS that contains declarations from header
+;; files for documentation purposes.  The "D" in DTAGS is for documentation,
+;; not declaration.  It's needed because more and more function comments
+;; are being moved to headers, making M-. less and less useful.
+;; The goal is to support fast lookup of a function's comment.
+;;
+;; N.B. This is just a prototype cribbed from emacs's etags.el.
+
+(defvar doc-tags-file-name nil
+  "*File name of doc tags table.
+To switch to a new doc tags table, setting this variable is sufficient.
+If you set this variable, do not also set `doc-tags-table-list'.
+Use the `etags' program to make a tags table file.")
+
+(defcustom doc-tags-table-list nil
+  "*List of file names of tags tables to search.
+An element that is a directory means the file \"TAGS\" in that directory.
+To switch to a new list of tags tables, setting this variable is sufficient.
+If you set this variable, do not also set `doc-tags-file-name'.
+Use the `etags' program to make a tags table file."
+  :group 'etags
+  :type '(repeat file))
+
+(defun find-doc-tag (tagname &optional next-p regexp-p)
+  "Find tag (in current tags table) whose name contains TAGNAME.
+Select the buffer containing the tag's definition, and move point there.
+The default for TAGNAME is the expression in the buffer around or before point.
+
+If second arg NEXT-P is t (interactively, with prefix arg), search for
+another tag that matches the last tagname or regexp used.  When there are
+multiple matches for a tag, more exact matches are found first.  If NEXT-P
+is the atom `-' (interactively, with prefix arg that is a negative number
+or just \\[negative-argument]), pop back to the previous tag gone to.
+
+If third arg REGEXP-P is non-nil, treat TAGNAME as a regexp.
+
+A marker representing the point when this command is invoked is pushed
+onto a ring and may be popped back to with \\[pop-tag-mark].
+Contrast this with the ring of marks gone to by the command.
+
+See documentation of variable `tags-file-name'."
+  ;; FIXME: Assumes using tags-file-name, and not tags-table-list.
+  (interactive (find-tag-interactive "Find doc tag: "))
+  (let ((tags-file-name doc-tags-file-name)
+	(tags-table-list doc-tags-table-list))
+    (let* ((buf (find-tag-noselect tagname next-p regexp-p))
+	   (pos (with-current-buffer buf (point))))
+      (setq doc-tags-file-name tags-file-name)
+      (setq doc-tags-table-list tags-table-list)
+      (condition-case nil
+	  (switch-to-buffer buf)
+	(error (pop-to-buffer buf)))
+      (goto-char pos))))
+
+;; TODO: visit-doc-tags-table, anything else?
+
+;;(global-set-key "\M-," 'find-doc-tag)