unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* building directory
@ 2003-04-04  8:13 Masatake YAMATO
  2003-04-04 10:27 ` Masatake YAMATO
  2003-04-04 14:51 ` Stefan Monnier
  0 siblings, 2 replies; 7+ messages in thread
From: Masatake YAMATO @ 2003-04-04  8:13 UTC (permalink / raw)


Is there anyway to know in which directory the current running 
emacs was built?

I'd like to prepare an user interface to access emacs C source
files easily. M-x describe-function is very good entry point for
my goal.

For functions written in elisp, you can access its source easily
with M-x describe-function.

e.g. M-x describe-function gnus
---------------------------------------------------------
gnus is an interactive autoloaded Lisp function in `gnus'.
It is bound to <menu-bar> <tools> <gnus>.
(gnus &optional ARG DONT-CONNECT SLAVE)
-E:**--*Help*--------All-(4,0)----(Help View Abberv)-----

You can click `gnus' to show its emacs lisp source code.

But what happen if the target function is written in C?

e.g. M-x describe-function car
---------------------------------------------------------
car is a built-in function.
(car LIST)
-E:**--*Help*--------All-(4,0)----(Help View Abberv)-----

There is no pointer to the C source code. sigh.
I'd like to change the *Help* buffer for the built-in function
like:

---------------------------------------------------------
car is data.c in `data.c'.
(car LIST)
-E:**--*Help*--------All-(4,0)----(Help View Abberv)-----

So you can click data.c to read the definition of `car'.

I've tired to implement with using __FILE__ and __LINE__ cpp
predefined macro. However, __FILE__ shows just relative path,
not complete path. So I'd like to know the way to know in which 
directory current running Emacs was built.

Masatake YAMATO

Index: src/lisp.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/lisp.h,v
retrieving revision 1.449
diff -u -r1.449 lisp.h
--- src/lisp.h	23 Mar 2003 02:08:04 -0000	1.449
+++ src/lisp.h	4 Apr 2003 07:52:52 -0000
@@ -856,6 +856,8 @@
     char *symbol_name;
     char *prompt;
     char *doc;
+    const char *src_file;
+    short src_line;
   };
 
 \f
@@ -1611,9 +1613,9 @@
   Lisp_Object fnname ();						\
   struct Lisp_Subr sname =						\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
-      fnname, minargs, maxargs, lname, prompt, 0};			\
+      fnname, minargs, maxargs, lname, prompt, 0, __FILE__, (short)__LINE__}; \
   Lisp_Object fnname
-
+									
 #else
 
 /* This version of DEFUN declares a function prototype with the right
@@ -1622,7 +1624,7 @@
   Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;				\
   struct Lisp_Subr sname =						\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
-      fnname, minargs, maxargs, lname, prompt, 0};			\
+      fnname, minargs, maxargs, lname, prompt, 0, __FILE__, (short)__LINE__}; \
   Lisp_Object fnname
 
 /* Note that the weird token-substitution semantics of ANSI C makes
@@ -3003,6 +3005,8 @@
 /* defined in doc.c */
 extern Lisp_Object Vdoc_file_name;
 EXFUN (Fsubstitute_command_keys, 1);
+EXFUN (Fsource_line, 1);
+EXFUN (Fsource_file, 1);
 EXFUN (Fdocumentation, 2);
 EXFUN (Fdocumentation_property, 3);
 extern Lisp_Object read_doc_string P_ ((Lisp_Object));
Index: src/doc.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/doc.c,v
retrieving revision 1.99
diff -u -r1.99 doc.c
--- src/doc.c	4 Feb 2003 14:03:12 -0000	1.99
+++ src/doc.c	4 Apr 2003 07:52:52 -0000
@@ -360,6 +360,32 @@
   return 1;
 }
 
+DEFUN ("source-line", Fsource_line, Ssource_line, 1, 1, 0,
+       doc: /* The line number of the function definition in its source C file.  */)
+     (object)
+     Lisp_Object object;
+{
+  Lisp_Object fun;
+  fun = Findirect_function (object);
+  if (SUBRP (fun))
+    return make_number((EMACS_INT)XSUBR(fun)->src_line);
+  else
+    return Qnil;
+}
+
+DEFUN ("source-file", Fsource_file, Ssource_file, 1, 1, 0,
+       doc: /* The file name of the function definition of its source C file.  */)
+     (object)
+     Lisp_Object object;
+{
+  Lisp_Object fun;
+  fun = Findirect_function (object);
+  if (SUBRP (fun) && (EMACS_INT)XSUBR(fun)->src_file)
+    return build_string(XSUBR(fun)->src_file);
+  else
+    return Qnil;
+}
+
 DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0,
        doc: /* Return the documentation string of FUNCTION.
 Unless a non-nil second argument RAW is given, the
@@ -923,6 +949,8 @@
 	       doc: /* Name of file containing documentation strings of built-in symbols.  */);
   Vdoc_file_name = Qnil;
 
+  defsubr (&Ssource_line);
+  defsubr (&Ssource_file);
   defsubr (&Sdocumentation);
   defsubr (&Sdocumentation_property);
   defsubr (&Ssnarf_documentation);
Index: lisp/help-fns.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v
retrieving revision 1.30
diff -u -r1.30 help-fns.el
--- lisp/help-fns.el	12 Feb 2003 23:13:43 -0000	1.30
+++ lisp/help-fns.el	4 Apr 2003 07:52:52 -0000
@@ -225,7 +225,8 @@
 		((subrp def)
 		 (if (eq 'unevalled (cdr (subr-arity def)))
 		     (concat beg "special form")
-		   (concat beg "built-in function")))
+		   (concat beg "built-in function"))
+		 (setq file-name (source-file function)))
 		((byte-code-function-p def)
 		 (concat beg "compiled Lisp function"))
 		((symbolp def)

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

* Re: building directory
  2003-04-04  8:13 building directory Masatake YAMATO
@ 2003-04-04 10:27 ` Masatake YAMATO
  2003-04-04 12:10   ` Thien-Thi Nguyen
                     ` (2 more replies)
  2003-04-04 14:51 ` Stefan Monnier
  1 sibling, 3 replies; 7+ messages in thread
From: Masatake YAMATO @ 2003-04-04 10:27 UTC (permalink / raw)


Romain FRANCOISE <romain@orebokech.com> tells me the way to find
the emacs C source directory. Thank you, Romain.

With following patch, you can jump to the definition of built-in
function from *Help* created by M-x describe-function.

If you approve my patch, let me know. I'll write ChangeLog entry.

Masatake YAMATO
Index: src/lisp.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/lisp.h,v
retrieving revision 1.449
diff -u -r1.449 lisp.h
--- src/lisp.h	23 Mar 2003 02:08:04 -0000	1.449
+++ src/lisp.h	4 Apr 2003 10:22:54 -0000
@@ -856,6 +856,8 @@
     char *symbol_name;
     char *prompt;
     char *doc;
+    const char *src_file;
+    short src_line;
   };
 
 \f
@@ -1611,9 +1613,9 @@
   Lisp_Object fnname ();						\
   struct Lisp_Subr sname =						\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
-      fnname, minargs, maxargs, lname, prompt, 0};			\
+      fnname, minargs, maxargs, lname, prompt, 0, __FILE__, (short)__LINE__}; \
   Lisp_Object fnname
-
+									
 #else
 
 /* This version of DEFUN declares a function prototype with the right
@@ -1622,7 +1624,7 @@
   Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;				\
   struct Lisp_Subr sname =						\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
-      fnname, minargs, maxargs, lname, prompt, 0};			\
+      fnname, minargs, maxargs, lname, prompt, 0, __FILE__, (short)__LINE__}; \
   Lisp_Object fnname
 
 /* Note that the weird token-substitution semantics of ANSI C makes
@@ -3003,6 +3005,8 @@
 /* defined in doc.c */
 extern Lisp_Object Vdoc_file_name;
 EXFUN (Fsubstitute_command_keys, 1);
+EXFUN (Fsource_line, 1);
+EXFUN (Fsource_file, 1);
 EXFUN (Fdocumentation, 2);
 EXFUN (Fdocumentation_property, 3);
 extern Lisp_Object read_doc_string P_ ((Lisp_Object));
Index: src/doc.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/doc.c,v
retrieving revision 1.99
diff -u -r1.99 doc.c
--- src/doc.c	4 Feb 2003 14:03:12 -0000	1.99
+++ src/doc.c	4 Apr 2003 10:22:54 -0000
@@ -360,6 +360,32 @@
   return 1;
 }
 
+DEFUN ("source-line", Fsource_line, Ssource_line, 1, 1, 0,
+       doc: /* The line number of the function definition in its source C file.  */)
+     (object)
+     Lisp_Object object;
+{
+  Lisp_Object fun;
+  fun = Findirect_function (object);
+  if (SUBRP (fun))
+    return make_number((EMACS_INT)XSUBR(fun)->src_line);
+  else
+    return Qnil;
+}
+
+DEFUN ("source-file", Fsource_file, Ssource_file, 1, 1, 0,
+       doc: /* The file name of the function definition of its source C file.  */)
+     (object)
+     Lisp_Object object;
+{
+  Lisp_Object fun;
+  fun = Findirect_function (object);
+  if (SUBRP (fun) && (EMACS_INT)XSUBR(fun)->src_file)
+    return build_string(XSUBR(fun)->src_file);
+  else
+    return Qnil;
+}
+
 DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0,
        doc: /* Return the documentation string of FUNCTION.
 Unless a non-nil second argument RAW is given, the
@@ -923,6 +949,8 @@
 	       doc: /* Name of file containing documentation strings of built-in symbols.  */);
   Vdoc_file_name = Qnil;
 
+  defsubr (&Ssource_line);
+  defsubr (&Ssource_file);
   defsubr (&Sdocumentation);
   defsubr (&Sdocumentation_property);
   defsubr (&Ssnarf_documentation);
Index: lisp/help-mode.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-mode.el,v
retrieving revision 1.15
diff -u -r1.15 help-mode.el
--- lisp/help-mode.el	10 Feb 2003 21:52:30 -0000	1.15
+++ lisp/help-mode.el	4 Apr 2003 10:22:54 -0000
@@ -64,6 +64,14 @@
   "Hook run by `help-mode'."
   :type 'hook
   :group 'help)
+
+(defcustom help-mode-emacs-source-directory source-directory
+  "Path specifying the place where emacs C source files are.
+`source-directory' is used as the default value. Specify
+the top source directory. Don't include `src'."
+  :type 'directory
+  :group 'help)
+
 \f
 ;; Button types used by help
 
@@ -155,6 +163,17 @@
 		     (pop-to-buffer (car location))
 		     (goto-char (cdr location))))
   'help-echo (purecopy "mouse-2, RET: find function's definition"))
+
+(define-button-type 'help-subr-def
+  :supertype 'help-xref
+  'help-function (lambda (fun file line)
+		   (let ((buf (find-file-noselect 
+			       (concat help-mode-emacs-source-directory "/src/" file))))
+		   (pop-to-buffer buf)
+		   (with-current-buffer buf
+		     (widen)
+		     (goto-line line))))
+  'help-echo (purecopy "mouse-2, RET: find subr's definition"))
 
 (define-button-type 'help-variable-def
   :supertype 'help-xref
Index: lisp/help-fns.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v
retrieving revision 1.30
diff -u -r1.30 help-fns.el
--- lisp/help-fns.el	12 Feb 2003 23:13:43 -0000	1.30
+++ lisp/help-fns.el	4 Apr 2003 10:22:55 -0000
@@ -217,7 +217,8 @@
 		  (symbol-function function)
 		function))
 	 file-name string
-	 (beg (if (commandp def) "an interactive " "a ")))
+	 (beg (if (commandp def) "an interactive " "a "))
+	 line)
     (setq string
 	  (cond ((or (stringp def)
 		     (vectorp def))
@@ -225,7 +226,9 @@
 		((subrp def)
 		 (if (eq 'unevalled (cdr (subr-arity def)))
 		     (concat beg "special form")
-		   (concat beg "built-in function")))
+		   (concat beg "built-in function"))
+		 (setq file-name (source-file function)
+		       line      (source-line function)))
 		((byte-code-function-p def)
 		 (concat beg "compiled Lisp function"))
 		((symbolp def)
@@ -287,7 +290,9 @@
       (with-current-buffer standard-output
 	(save-excursion
 	  (re-search-backward "`\\([^`']+\\)'" nil t)
-	  (help-xref-button 1 'help-function-def function file-name)))))
+	  (if line
+	      (help-xref-button 1 'help-subr-def function file-name line)
+	    (help-xref-button 1 'help-function-def function file-name))))))
     (princ ".")
     (terpri)
     (when (commandp function)

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

* Re: building directory
  2003-04-04 10:27 ` Masatake YAMATO
@ 2003-04-04 12:10   ` Thien-Thi Nguyen
  2003-04-04 12:21   ` Jan D.
  2003-04-05  8:12   ` Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Thien-Thi Nguyen @ 2003-04-04 12:10 UTC (permalink / raw)
  Cc: emacs-devel

just a thought:

you can probably go a step further and add support for copying the source
under something like PREFIX/share/emacs/VERSION/source upon "make install",
perhaps by specifying "configure --enable-full-source-install".  then weird
people like me can take it to the logical extreme and add support for
"--enable-full-build-environment-install", the result being ability to do "M-x
rebuild-emacs".  these options would be disabled, normally.

thi

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

* Re: building directory
  2003-04-04 10:27 ` Masatake YAMATO
  2003-04-04 12:10   ` Thien-Thi Nguyen
@ 2003-04-04 12:21   ` Jan D.
  2003-04-05  8:12   ` Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Jan D. @ 2003-04-04 12:21 UTC (permalink / raw)
  Cc: emacs-devel


fredagen den 4 april 2003 kl 12.27 skrev Masatake YAMATO:

> Romain FRANCOISE <romain@orebokech.com> tells me the way to find
> the emacs C source directory. Thank you, Romain.
>
> With following patch, you can jump to the definition of built-in
> function from *Help* created by M-x describe-function.

What does it do if the source is not there?  When building and 
installing
a new Emacs version, I remove the source after make install, because
it is not needed anymore.  I don't think that is very uncommon.

	Jan D.

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

* Re: building directory
  2003-04-04  8:13 building directory Masatake YAMATO
  2003-04-04 10:27 ` Masatake YAMATO
@ 2003-04-04 14:51 ` Stefan Monnier
  2003-04-05  8:12   ` Richard Stallman
  1 sibling, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2003-04-04 14:51 UTC (permalink / raw)
  Cc: emacs-devel

> I'd like to prepare an user interface to access emacs C source
> files easily. M-x describe-function is very good entry point for
> my goal.

I'd like that too.  And also for built-in variables.
I've been using a patch (that I posted to this list a while back)
to do what you suggest.  There are several different possible
approaches to do what you want.

You want to be careful about the fact that source files
might have been edited since the last build so the source-line info
might be off.  This means that even if you have the line number,
you'll have to search for the right DEFUN, so the line info is not
that useful anyway.

I think an other approach along the lines of yours would be
to simply adjust the initial `load-history'.  That would
give you the equivalent of `source-file', but using `symbol-file'.
It's probably not that different in the end.  Although
the generalization to built-in variables is more obvious.

My patch (see below) simply relies on having TAGS built in the
source directory.  It's not a bad approach although it's not
great either: the main problem is that the etags.el functions
make it a bit difficult to locally use a tags table without impacting
other uses of tags that might be going on already.  Of course
the other problem is that it requires TAGS, but I find that it's
not a big problem and even has the advantage that it even works
in the case where a function is moved from one file to another.
Also it does not require any extra information in Emacs, so people
who don't use it don't pay anything for it.  This is relevant
(though maybe not too important) because it is a feature
likely to be used only by a small minority of the users.
I wanted to fix etags.el so that my patch could be made cleaner,
but I haven't gotten to it (mostly because it works well enough
for me :-( ).


	Stefan


Index: help-fns.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/help-fns.el,v
retrieving revision 1.30
diff -u -r1.30 help-fns.el
--- help-fns.el	12 Feb 2003 23:13:43 -0000	1.30
+++ help-fns.el	4 Apr 2003 14:43:23 -0000
@@ -285,9 +286,36 @@
       (princ "'")
       ;; Make a hyperlink to the library.
       (with-current-buffer standard-output
        (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))))
+     ;; If it's a subr, try to make a link to the C source.
+     ((and (subrp def) (symbolp function)
+	   (file-exists-p (expand-file-name "src/TAGS" source-directory)))
+      (let ((src-tags-file (expand-file-name "src/TAGS" source-directory))
+	    (tags-file-name (if (boundp 'tags-file-name) tags-file-name)))
+	(unless (equal tags-file-name src-tags-file)
+	  (setq tags-file-name nil)
+	  (visit-tags-table src-tags-file))
+	(let ((buf (condition-case nil
+		       (save-excursion
+			 (visit-tags-table-buffer)
+			 (find-tag-in-order
+			  (concat "\"" (symbol-name function) "\"")
+			  find-tag-search-function find-tag-tag-order
+			  find-tag-next-line-after-failure-p
+			  "containing" t))
+		     (error nil))))
+	  (when buf
+	    (let ((pos (with-current-buffer buf (point))))
+	      (princ " in `")
+	      (princ (with-current-buffer buf (file-name-nondirectory
+					       buffer-file-name)))
+	      (princ "'")
+	      (with-current-buffer standard-output
+		(save-excursion
+		  (re-search-backward "`\\([^`']+\\)'" nil t)
+		  (help-xref-button 1 'help-function-def pos buf)))))))))
     (princ ".")
     (terpri)
     (when (commandp function)

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

* Re: building directory
  2003-04-04 10:27 ` Masatake YAMATO
  2003-04-04 12:10   ` Thien-Thi Nguyen
  2003-04-04 12:21   ` Jan D.
@ 2003-04-05  8:12   ` Richard Stallman
  2 siblings, 0 replies; 7+ messages in thread
From: Richard Stallman @ 2003-04-05  8:12 UTC (permalink / raw)
  Cc: emacs-devel

That is a good hack.  As someone pointed out, it needs to cope with
the situation that the sources are not present in the specified
directory.

The suggestion that you should search through the file rather than
just go to the recorded line number is important.

A few other little changes are called for.

	 { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
    -      fnname, minargs, maxargs, lname, prompt, 0};			\
    +      fnname, minargs, maxargs, lname, prompt, 0, __FILE__, (short)__LINE__}; \

    +DEFUN ("source-line", Fsource_line, Ssource_line, 1, 1, 0,

Please call it `function-source-line'.  Likewise for 
`function-source-file'.

    +    return make_number((EMACS_INT)XSUBR(fun)->src_line);

Please write a space before the first openparen.

    +  "Path specifying the place where emacs C source files are.

In the GNU conventions, we don't use the term "path" this way.
Please say "Directory for visiting the Emacs C source files."

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

* Re: building directory
  2003-04-04 14:51 ` Stefan Monnier
@ 2003-04-05  8:12   ` Richard Stallman
  0 siblings, 0 replies; 7+ messages in thread
From: Richard Stallman @ 2003-04-05  8:12 UTC (permalink / raw)
  Cc: emacs-devel

    I think an other approach along the lines of yours would be
    to simply adjust the initial `load-history'.  That would
    give you the equivalent of `source-file', but using `symbol-file'.
    It's probably not that different in the end.  Although
    the generalization to built-in variables is more obvious.

That would work.  Searching for a DEFUN line would finish the job.

    My patch (see below) simply relies on having TAGS built in the
    source directory.

That is distinctly not as good.

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

end of thread, other threads:[~2003-04-05  8:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-04  8:13 building directory Masatake YAMATO
2003-04-04 10:27 ` Masatake YAMATO
2003-04-04 12:10   ` Thien-Thi Nguyen
2003-04-04 12:21   ` Jan D.
2003-04-05  8:12   ` Richard Stallman
2003-04-04 14:51 ` Stefan Monnier
2003-04-05  8:12   ` 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).