unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Jumping to C source from *Help*
@ 2004-04-06 22:35 Stefan Monnier
  2004-04-07  1:01 ` Juanma Barranquero
  0 siblings, 1 reply; 43+ messages in thread
From: Stefan Monnier @ 2004-04-06 22:35 UTC (permalink / raw)



As has already been discussed in the past, it would be a good thing to be
able to jump from the *Help* buffer to the source of a var or fun that's
defined in C, just like we can do it when it's defined in Elisp.

Until recently I was using a hack based on TAGS, which was sadly too ugly
and fragile to be installed.  I have re-implemented the feature now in
a much cleaner way.

The source-file-name info is placed directly in DOC by make-docfile.

Please review and tell me of anything that might need to be changed before
installing the change.


        Stefan


Index: lib-src/make-docfile.c
===================================================================
RCS file: /cvsroot/emacs/emacs/lib-src/make-docfile.c,v
retrieving revision 1.56
diff -u -r1.56 make-docfile.c
--- lib-src/make-docfile.c	24 Dec 2003 06:49:23 -0000	1.56
+++ lib-src/make-docfile.c	6 Apr 2004 22:33:59 -0000
@@ -1,5 +1,5 @@
 /* Generate doc-string file for GNU Emacs from source files.
-   Copyright (C) 1985, 86, 92, 93, 94, 97, 1999, 2000, 2001
+   Copyright (C) 1985, 86, 92, 93, 94, 97, 1999, 2000, 01, 2004
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -105,11 +105,11 @@
 
 /* Like malloc but get fatal error if memory is exhausted.  */
 
-long *
+void *
 xmalloc (size)
      unsigned int size;
 {
-  long *result = (long *) malloc (size);
+  void *result = (void *) malloc (size);
   if (result == NULL)
     fatal ("virtual memory exhausted", 0);
   return result;
@@ -178,6 +178,35 @@
   return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
+/* Add a source file name boundary marker in the output file.  */
+void
+put_filename (filename)
+     char *filename;
+{
+  char *tmp = filename;
+  int len;
+  
+  while ((tmp = index (filename, '/')))
+    filename = tmp + 1;
+
+  len = strlen (filename);
+  tmp = xmalloc (len + 1);
+  strcpy (tmp, filename);
+  filename = tmp;
+
+  /* Turn object file names into source file names.  */
+  if (len > 4 && !strcmp (filename + len - 4, ".elc"))
+    /* Truncate `.elc' to `.el'.  */
+    filename[len - 1] = '\0';
+  else if (len > 2 && !strcmp (filename + len - 2, ".o"))
+    /* Switch `.o' to `.c'. */
+    filename[len - 1] = 'c';
+
+  putc (037, outfile);
+  putc ('S', outfile);
+  fprintf (outfile, "%s\n", filename);
+}
+
 /* Read file FILENAME and output its doc strings to outfile.  */
 /* Return 1 if file is not found, 0 if it is found.  */
 
@@ -186,6 +215,8 @@
      char *filename;
 {
   int len = strlen (filename);
+
+  put_filename (filename);
   if (len > 4 && !strcmp (filename + len - 4, ".elc"))
     return scan_lisp_file (filename, READ_BINARY);
   else if (len > 3 && !strcmp (filename + len - 3, ".el"))

Index: src/doc.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/doc.c,v
retrieving revision 1.103
diff -u -r1.103 doc.c
--- src/doc.c	2 Mar 2004 06:11:48 -0000	1.103
+++ src/doc.c	6 Apr 2004 22:33:59 -0000
@@ -1,5 +1,6 @@
 /* Record indices of function doc strings stored in a file.
-   Copyright (C) 1985, 86,93,94,95,97,98,99, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86,93,94,95,97,98,99,2000,04
+             Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -612,8 +613,7 @@
 	*p = '_';
       p++;
     }
-#endif /* not VMS4_4 */
-#ifdef VMS4_4
+#else /* VMS4_4 */
   strcpy (name, sys_translate_unix (name));
 #endif /* VMS4_4 */
 #endif /* VMS */
@@ -659,6 +659,9 @@
 	      /* Attach a docstring to a function?  */
 	      else if (p[1] == 'F')
 		store_function_docstring (sym, pos + end + 1 - buf);
+
+	      else if (p[1] == 'S')
+		; /* Just a source file name boundary marker.  Ignore it.  */
 
 	      else
 		error ("DOC file invalid at position %d", pos);

Index: lisp/help-fns.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v
retrieving revision 1.36
diff -u -r1.36 help-fns.el
--- lisp/help-fns.el	20 Feb 2004 03:48:32 -0000	1.36
+++ lisp/help-fns.el	6 Apr 2004 22:33:59 -0000
@@ -1,6 +1,6 @@
 ;;; help-fns.el --- Complex help functions
 
-;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003
+;; Copyright (C) 1985, 86, 93, 94, 98, 1999, 2000, 01, 02, 03, 2004
 ;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
@@ -215,6 +215,56 @@
 			(intern (upcase name))))))
 		arglist)))
 
+(defvar help-C-source-directory
+  (let ((dir (expand-file-name "src" source-directory)))
+    (when (and (file-directory-p dir) (file-readable-p dir))
+      dir))
+  "Directory where the C source files of Emacs can be found.
+If nil, do not try to find the source code of functions and variables
+defined in C.")
+
+(defun help-subr-name (subr)
+  (let ((name (prin1-to-string subr)))
+    (if (string-match "\\`#<subr \\(.*\\)>\\'" name)
+	(match-string 1 name)
+      (error "Unexpected internal name: %s" name))))
+
+(defun help-C-file-name (subr-or-var kind)
+  "Return the name of the C file where SUBR-OR-VAR is defined.
+KIND should be `var' for a variable or `subr' for a subroutine."
+  (let ((docbuf (get-buffer-create " *DOC*"))
+	(name (if (eq 'var kind)
+		  (concat "V" (symbol-name subr-or-var))
+		(concat "F" (help-subr-name subr-or-var)))))
+    (with-current-buffer docbuf
+      (goto-char (point-min))
+	  (if (eobp)
+	      (insert-file-contents-literally
+	       (expand-file-name internal-doc-file-name doc-directory)))
+	  (search-forward (concat "\x1f" name "\n"))
+	  (re-search-backward "\x1fS\\(.*\\)")
+	  (match-string 1))))
+
+(defun help-find-C-source (fun-or-var file kind)
+  (setq file (expand-file-name file help-C-source-directory))
+  (unless (file-readable-p file)
+    (error "The C source file %s is not available"
+	   (file-name-nondirectory file)))
+  (if (eq 'fun kind)
+      (setq fun-or-var (indirect-function fun-or-var)))
+  (with-current-buffer (find-file-noselect file)
+    (goto-char (point-min))
+    (unless (re-search-forward
+	     (if (eq 'fun kind)
+		 (concat "DEFUN[ \t\n]*([ \t\n]*\""
+			 (regexp-quote (help-subr-name fun-or-var))
+			 "\"")
+	       (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
+		       (regexp-quote (symbol-name fun-or-var))))
+	     nil t)
+      (error "Can't find source for %s" fun))
+    (cons (current-buffer) (match-beginning 0))))
+
 ;;;###autoload
 (defun describe-function-1 (function)
   (let* ((def (if (symbolp function)
@@ -280,8 +330,11 @@
 	    (when (re-search-backward
 		   "^;;; Generated autoloads from \\(.*\\)" nil t)
 	      (setq file-name (match-string 1)))))))
-    (cond
-     (file-name
+    (when (and (null file-name) (subrp def))
+      (if help-C-source-directory
+	  (setq file-name (concat "src/" (help-C-file-name def 'subr)))
+	(princ " in core C code")))
+    (when file-name
       (princ " in `")
       ;; We used to add .el to the file name,
       ;; but that's completely wrong when the user used load-file.
@@ -289,9 +342,9 @@
       (princ "'")
       ;; Make a hyperlink to the library.
       (with-current-buffer standard-output
-	(save-excursion
+        (save-excursion
 	  (re-search-backward "`\\([^`']+\\)'" nil t)
-	  (help-xref-button 1 'help-function-def function file-name)))))
+	  (help-xref-button 1 'help-function-def function file-name))))
     (princ ".")
     (terpri)
     (when (commandp function)
@@ -500,6 +553,13 @@
 		      (when (re-search-backward
 			     "^;;; Generated autoloads from \\(.*\\)" nil t)
 			(setq file-name (match-string 1)))))))
+	      (when (and (null file-name)
+			 (integerp (get variable 'variable-documentation)))
+		;; It's a variable not defined in Elisp but in C.
+		(if help-C-source-directory
+		    (setq file-name
+			  (concat "src/" (help-C-file-name variable 'var)))
+		  (princ "\n\nDefined in core C code.")))
 	      (when file-name
 		(princ "\n\nDefined in `")
 		(princ file-name)

Index: lisp/help-mode.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-mode.el,v
retrieving revision 1.23
diff -u -r1.23 help-mode.el
--- lisp/help-mode.el	5 Apr 2004 12:09:53 -0000	1.23
+++ lisp/help-mode.el	6 Apr 2004 22:33:59 -0000
@@ -1,6 +1,6 @@
 ;;; help-mode.el --- `help-mode' used by *Help* buffers
 
-;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002
+;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2004
 ;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
@@ -150,8 +150,11 @@
 		   ;; Don't use find-function-noselect because it follows
 		   ;; aliases (which fails for built-in functions).
 		   (let ((location
-			  (if (bufferp file) (cons file fun)
-			    (find-function-search-for-symbol fun nil file))))
+			  (cond
+			   ((bufferp file) (cons file fun))
+			   ((string-match "\\`src/\\(.*\\.c\\)" file)
+			    (help-find-C-source fun (match-string 1 file) 'fun))
+			   (t (find-function-search-for-symbol fun nil file)))))
 		     (pop-to-buffer (car location))
 		     (goto-char (cdr location))))
   'help-echo (purecopy "mouse-2, RET: find function's definition"))
@@ -160,7 +163,10 @@
   :supertype 'help-xref
   'help-function (lambda (var &optional file)
 		   (let ((location
-			  (find-variable-noselect var file)))
+			  (cond
+			   ((string-match "\\`src/\\(.*\\.c\\)" file)
+			    (help-find-C-source var (match-string 1 file) 'var))
+			   (t (find-variable-noselect var file)))))
 		     (pop-to-buffer (car location))
 		     (goto-char (cdr location))))
   'help-echo (purecopy"mouse-2, RET: find variable's definition"))

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2004-04-21 15:38 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-06 22:35 Jumping to C source from *Help* Stefan Monnier
2004-04-07  1:01 ` Juanma Barranquero
2004-04-07 19:44   ` Stefan Monnier
2004-04-08  0:35     ` Kim F. Storm
2004-04-08  6:12     ` Juri Linkov
2004-04-08 16:10       ` Kim F. Storm
2004-04-09 22:44         ` Richard Stallman
2004-04-08 16:46       ` Stefan Monnier
2004-04-08 17:27         ` switch-buffer to use other window if dedicated window (was: Jumping to C source from *Help*) Drew Adams
2004-04-09 22:44         ` Jumping to C source from *Help* Richard Stallman
2004-04-10 18:51           ` Kim F. Storm
2004-04-11 23:17             ` Stefan Monnier
2004-04-12 17:34               ` Glenn Morris
2004-04-14 18:01                 ` Richard Stallman
2004-04-15 17:36                   ` Glenn Morris
2004-04-19 18:20                     ` Richard Stallman
2004-04-19 23:59                       ` Kim F. Storm
2004-04-20  0:41                       ` Glenn Morris
2004-04-20 16:05                         ` Drew Adams
2004-04-20 20:47                         ` Richard Stallman
2004-04-20 23:33                           ` Glenn Morris
2004-04-20 23:48                             ` Miles Bader
2004-04-20 22:04                         ` Nick Roberts
2004-04-20 23:40                           ` Glenn Morris
2004-04-21 10:21                             ` Kim F. Storm
2004-04-21 15:38                               ` Stefan Monnier
2004-04-13 17:44               ` Richard Stallman
2004-04-13 18:12                 ` Stefan Monnier
2004-04-14 22:53                   ` Richard Stallman
2004-04-15 13:58                     ` Stefan Monnier
2004-04-15 16:27                       ` Kim F. Storm
2004-04-15 16:08                         ` Drew Adams
2004-04-16 18:08                         ` Richard Stallman
2004-04-16 18:37                           ` David Kastrup
2004-04-16 18:08                       ` Richard Stallman
2004-04-16 18:39                         ` Stefan Monnier
2004-04-17 19:46                           ` Richard Stallman
2004-04-19 14:09                             ` Stefan Monnier
2004-04-18 21:47             ` Richard Stallman
2004-04-19 14:12               ` Stefan Monnier
2004-04-08  6:19     ` Juri Linkov
2004-04-08 16:07       ` Kim F. Storm
2004-04-09 22:43       ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).