comparison src/doc.c @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 23a1cea22d13
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 /* Record indices of function doc strings stored in a file. 1 /* Record indices of function doc strings stored in a file.
2 Copyright (C) 1985, 86,93,94,95,97,98,99, 2000 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 4
4 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
5 6
6 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 15 GNU General Public License for more details.
15 16
16 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to 18 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02110-1301, USA. */
20 21
21 22
22 #include <config.h> 23 #include <config.h>
23 24
24 #include <sys/types.h> 25 #include <sys/types.h>
25 #include <sys/file.h> /* Must be after sys/types.h for USG and BSD4_1*/ 26 #include <sys/file.h> /* Must be after sys/types.h for USG and BSD4_1*/
26 27 #include <ctype.h>
27 #ifdef USG5 28
29 #ifdef HAVE_FCNTL_H
28 #include <fcntl.h> 30 #include <fcntl.h>
29 #endif 31 #endif
30 32
31 #ifdef HAVE_UNISTD_H 33 #ifdef HAVE_UNISTD_H
32 #include <unistd.h> 34 #include <unistd.h>
48 50
49 Lisp_Object Vdoc_file_name; 51 Lisp_Object Vdoc_file_name;
50 52
51 Lisp_Object Qfunction_documentation; 53 Lisp_Object Qfunction_documentation;
52 54
55 /* A list of files used to build this Emacs binary. */
56 static Lisp_Object Vbuild_files;
57
53 extern Lisp_Object Voverriding_local_map; 58 extern Lisp_Object Voverriding_local_map;
54 59
60 extern Lisp_Object Qremap;
61
55 /* For VMS versions with limited file name syntax, 62 /* For VMS versions with limited file name syntax,
56 convert the name to something VMS will allow. */ 63 convert the name to something VMS will allow. */
57 static void 64 static void
58 munge_doc_file_name (name) 65 munge_doc_file_name (name)
59 char *name; 66 char *name;
60 { 67 {
61 #ifdef VMS 68 #ifdef VMS
62 #ifndef VMS4_4 69 #ifndef NO_HYPHENS_IN_FILENAMES
63 /* For VMS versions with limited file name syntax, 70 extern char * sys_translate_unix (char *ufile);
64 convert the name to something VMS will allow. */ 71 strcpy (name, sys_translate_unix (name));
65 p = name; 72 #else /* NO_HYPHENS_IN_FILENAMES */
73 char *p = name;
66 while (*p) 74 while (*p)
67 { 75 {
68 if (*p == '-') 76 if (*p == '-')
69 *p = '_'; 77 *p = '_';
70 p++; 78 p++;
71 } 79 }
72 #endif /* not VMS4_4 */ 80 #endif /* NO_HYPHENS_IN_FILENAMES */
73 #ifdef VMS4_4
74 strcpy (name, sys_translate_unix (name));
75 #endif /* VMS4_4 */
76 #endif /* VMS */ 81 #endif /* VMS */
77 } 82 }
78 83
79 /* Buffer used for reading from documentation file. */ 84 /* Buffer used for reading from documentation file. */
80 static char *get_doc_string_buffer; 85 static char *get_doc_string_buffer;
567 This searches the `etc/DOC...' file for doc strings and 572 This searches the `etc/DOC...' file for doc strings and
568 records them in function and variable definitions. 573 records them in function and variable definitions.
569 The function takes one argument, FILENAME, a string; 574 The function takes one argument, FILENAME, a string;
570 it specifies the file name (without a directory) of the DOC file. 575 it specifies the file name (without a directory) of the DOC file.
571 That file is found in `../etc' now; later, when the dumped Emacs is run, 576 That file is found in `../etc' now; later, when the dumped Emacs is run,
572 the same file name is found in the `data-directory'. */) 577 the same file name is found in the `doc-directory'. */)
573 (filename) 578 (filename)
574 Lisp_Object filename; 579 Lisp_Object filename;
575 { 580 {
576 int fd; 581 int fd;
577 char buf[1024 + 1]; 582 char buf[1024 + 1];
578 register int filled; 583 register int filled;
579 register int pos; 584 register int pos;
580 register char *p, *end; 585 register char *p, *end;
581 Lisp_Object sym; 586 Lisp_Object sym;
582 char *name; 587 char *name;
588 int skip_file = 0;
583 589
584 CHECK_STRING (filename); 590 CHECK_STRING (filename);
585 591
586 if 592 if
587 #ifndef CANNOT_DUMP 593 #ifndef CANNOT_DUMP
599 name = (char *) alloca (SCHARS (filename) 605 name = (char *) alloca (SCHARS (filename)
600 + SCHARS (Vdoc_directory) + 1); 606 + SCHARS (Vdoc_directory) + 1);
601 strcpy (name, SDATA (Vdoc_directory)); 607 strcpy (name, SDATA (Vdoc_directory));
602 } 608 }
603 strcat (name, SDATA (filename)); /*** Add this line ***/ 609 strcat (name, SDATA (filename)); /*** Add this line ***/
604 #ifdef VMS 610 munge_doc_file_name (name);
605 #ifndef VMS4_4 611
606 /* For VMS versions with limited file name syntax, 612 /* Vbuild_files is nil when temacs is run, and non-nil after that. */
607 convert the name to something VMS will allow. */ 613 if (NILP (Vbuild_files))
608 p = name; 614 {
609 while (*p) 615 size_t cp_size = 0;
610 { 616 size_t to_read;
611 if (*p == '-') 617 int nr_read;
612 *p = '_'; 618 char *cp = NULL;
613 p++; 619 char *beg, *end;
614 } 620
615 #endif /* not VMS4_4 */ 621 fd = emacs_open ("buildobj.lst", O_RDONLY, 0);
616 #ifdef VMS4_4 622 if (fd < 0)
617 strcpy (name, sys_translate_unix (name)); 623 report_file_error ("Opening file buildobj.lst", Qnil);
618 #endif /* VMS4_4 */ 624
619 #endif /* VMS */ 625 filled = 0;
626 for (;;)
627 {
628 cp_size += 1024;
629 to_read = cp_size - 1 - filled;
630 cp = xrealloc (cp, cp_size);
631 nr_read = emacs_read (fd, &cp[filled], to_read);
632 filled += nr_read;
633 if (nr_read < to_read)
634 break;
635 }
636
637 emacs_close (fd);
638 cp[filled] = 0;
639
640 for (beg = cp; *beg; beg = end)
641 {
642 int len;
643
644 while (*beg && isspace (*beg)) ++beg;
645
646 for (end = beg; *end && ! isspace (*end); ++end)
647 if (*end == '/') beg = end+1; /* skip directory part */
648
649 len = end - beg;
650 if (len > 4 && end[-4] == '.' && end[-3] == 'o')
651 len -= 2; /* Just take .o if it ends in .obj */
652
653 if (len > 0)
654 Vbuild_files = Fcons (make_string (beg, len), Vbuild_files);
655 }
656
657 xfree (cp);
658 }
620 659
621 fd = emacs_open (name, O_RDONLY, 0); 660 fd = emacs_open (name, O_RDONLY, 0);
622 if (fd < 0) 661 if (fd < 0)
623 report_file_error ("Opening doc string file", 662 report_file_error ("Opening doc string file",
624 Fcons (build_string (name), Qnil)); 663 Fcons (build_string (name), Qnil));
638 while (p != end && *p != '\037') p++; 677 while (p != end && *p != '\037') p++;
639 /* p points to ^_Ffunctionname\n or ^_Vvarname\n. */ 678 /* p points to ^_Ffunctionname\n or ^_Vvarname\n. */
640 if (p != end) 679 if (p != end)
641 { 680 {
642 end = (char *) index (p, '\n'); 681 end = (char *) index (p, '\n');
682
683 /* See if this is a file name, and if it is a file in build-files. */
684 if (p[1] == 'S' && end - p > 4 && end[-2] == '.'
685 && (end[-1] == 'o' || end[-1] == 'c'))
686 {
687 int len = end - p - 2;
688 char *fromfile = alloca (len + 1);
689 strncpy (fromfile, &p[2], len);
690 fromfile[len] = 0;
691 if (fromfile[len-1] == 'c')
692 fromfile[len-1] = 'o';
693
694 if (EQ (Fmember (build_string (fromfile), Vbuild_files), Qnil))
695 skip_file = 1;
696 else
697 skip_file = 0;
698 }
699
643 sym = oblookup (Vobarray, p + 2, 700 sym = oblookup (Vobarray, p + 2,
644 multibyte_chars_in_text (p + 2, end - p - 2), 701 multibyte_chars_in_text (p + 2, end - p - 2),
645 end - p - 2); 702 end - p - 2);
646 if (SYMBOLP (sym)) 703 if (! skip_file && SYMBOLP (sym))
647 { 704 {
648 /* Attach a docstring to a variable? */ 705 /* Attach a docstring to a variable? */
649 if (p[1] == 'V') 706 if (p[1] == 'V')
650 { 707 {
651 /* Install file-position as variable-documentation property 708 /* Install file-position as variable-documentation property
658 715
659 /* Attach a docstring to a function? */ 716 /* Attach a docstring to a function? */
660 else if (p[1] == 'F') 717 else if (p[1] == 'F')
661 store_function_docstring (sym, pos + end + 1 - buf); 718 store_function_docstring (sym, pos + end + 1 - buf);
662 719
720 else if (p[1] == 'S')
721 ; /* Just a source file name boundary marker. Ignore it. */
722
663 else 723 else
664 error ("DOC file invalid at position %d", pos); 724 error ("DOC file invalid at position %d", pos);
665 } 725 }
666 } 726 }
667 pos += end - buf; 727 pos += end - buf;
673 } 733 }
674 734
675 DEFUN ("substitute-command-keys", Fsubstitute_command_keys, 735 DEFUN ("substitute-command-keys", Fsubstitute_command_keys,
676 Ssubstitute_command_keys, 1, 1, 0, 736 Ssubstitute_command_keys, 1, 1, 0,
677 doc: /* Substitute key descriptions for command names in STRING. 737 doc: /* Substitute key descriptions for command names in STRING.
678 Return a new string which is STRING with substrings of the form \\=\\[COMMAND] 738 Substrings of the form \\=\\[COMMAND] replaced by either: a keystroke
679 replaced by either: a keystroke sequence that will invoke COMMAND, 739 sequence that will invoke COMMAND, or "M-x COMMAND" if COMMAND is not
680 or "M-x COMMAND" if COMMAND is not on any keys. 740 on any keys.
681 Substrings of the form \\=\\{MAPVAR} are replaced by summaries 741 Substrings of the form \\=\\{MAPVAR} are replaced by summaries
682 \(made by describe-bindings) of the value of MAPVAR, taken as a keymap. 742 \(made by describe-bindings) of the value of MAPVAR, taken as a keymap.
683 Substrings of the form \\=\\<MAPVAR> specify to use the value of MAPVAR 743 Substrings of the form \\=\\<MAPVAR> specify to use the value of MAPVAR
684 as the keymap for future \\=\\[COMMAND] substrings. 744 as the keymap for future \\=\\[COMMAND] substrings.
685 \\=\\= quotes the following character and is discarded; 745 \\=\\= quotes the following character and is discarded;
686 thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ into the output. */) 746 thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ into the output.
747
748 Returns original STRING if no substitutions were made. Othwerwise,
749 a new string, without any text properties, is returned. */)
687 (string) 750 (string)
688 Lisp_Object string; 751 Lisp_Object string;
689 { 752 {
690 unsigned char *buf; 753 unsigned char *buf;
691 int changed = 0; 754 int changed = 0;
723 keymap = Voverriding_local_map; 786 keymap = Voverriding_local_map;
724 787
725 bsize = SBYTES (string); 788 bsize = SBYTES (string);
726 bufp = buf = (unsigned char *) xmalloc (bsize); 789 bufp = buf = (unsigned char *) xmalloc (bsize);
727 790
728 strp = (unsigned char *) SDATA (string); 791 strp = SDATA (string);
729 while (strp < SDATA (string) + SBYTES (string)) 792 while (strp < SDATA (string) + SBYTES (string))
730 { 793 {
731 if (strp[0] == '\\' && strp[1] == '=') 794 if (strp[0] == '\\' && strp[1] == '=')
732 { 795 {
733 /* \= quotes the next character; 796 /* \= quotes the next character;
751 else 814 else
752 *bufp++ = *strp++, nchars++; 815 *bufp++ = *strp++, nchars++;
753 } 816 }
754 else if (strp[0] == '\\' && strp[1] == '[') 817 else if (strp[0] == '\\' && strp[1] == '[')
755 { 818 {
756 Lisp_Object firstkey;
757 int start_idx; 819 int start_idx;
820 int follow_remap = 1;
758 821
759 changed = 1; 822 changed = 1;
760 strp += 2; /* skip \[ */ 823 strp += 2; /* skip \[ */
761 start = strp; 824 start = strp;
762 start_idx = start - SDATA (string); 825 start_idx = start - SDATA (string);
763 826
764 while ((strp - (unsigned char *) SDATA (string) 827 while ((strp - SDATA (string)
765 < SBYTES (string)) 828 < SBYTES (string))
766 && *strp != ']') 829 && *strp != ']')
767 strp++; 830 strp++;
768 length_byte = strp - start; 831 length_byte = strp - start;
769 832
770 strp++; /* skip ] */ 833 strp++; /* skip ] */
771 834
772 /* Save STRP in IDX. */ 835 /* Save STRP in IDX. */
773 idx = strp - (unsigned char *) SDATA (string); 836 idx = strp - SDATA (string);
774 tem = Fintern (make_string (start, length_byte), Qnil); 837 name = Fintern (make_string (start, length_byte), Qnil);
838
839 do_remap:
840 /* Ignore remappings unless there are no ordinary bindings. */
841 tem = Fwhere_is_internal (name, keymap, Qt, Qnil, Qt);
842 if (NILP (tem))
843 tem = Fwhere_is_internal (name, keymap, Qt, Qnil, Qnil);
844
845 if (VECTORP (tem) && XVECTOR (tem)->size > 1
846 && EQ (AREF (tem, 0), Qremap) && SYMBOLP (AREF (tem, 1))
847 && follow_remap)
848 {
849 name = AREF (tem, 1);
850 follow_remap = 0;
851 goto do_remap;
852 }
775 853
776 /* Note the Fwhere_is_internal can GC, so we have to take 854 /* Note the Fwhere_is_internal can GC, so we have to take
777 relocation of string contents into account. */ 855 relocation of string contents into account. */
778 tem = Fwhere_is_internal (tem, keymap, Qt, Qnil, Qnil);
779 strp = SDATA (string) + idx; 856 strp = SDATA (string) + idx;
780 start = SDATA (string) + start_idx; 857 start = SDATA (string) + start_idx;
781
782 /* Disregard menu bar bindings; it is positively annoying to
783 mention them when there's no menu bar, and it isn't terribly
784 useful even when there is a menu bar. */
785 if (!NILP (tem))
786 {
787 firstkey = Faref (tem, make_number (0));
788 if (EQ (firstkey, Qmenu_bar))
789 tem = Qnil;
790 }
791 858
792 if (NILP (tem)) /* but not on any keys */ 859 if (NILP (tem)) /* but not on any keys */
793 { 860 {
794 int offset = bufp - buf; 861 int offset = bufp - buf;
795 buf = (unsigned char *) xrealloc (buf, bsize += 4); 862 buf = (unsigned char *) xrealloc (buf, bsize += 4);
803 length = length_byte; 870 length = length_byte;
804 goto subst; 871 goto subst;
805 } 872 }
806 else 873 else
807 { /* function is on a key */ 874 { /* function is on a key */
808 tem = Fkey_description (tem); 875 tem = Fkey_description (tem, Qnil);
809 goto subst_string; 876 goto subst_string;
810 } 877 }
811 } 878 }
812 /* \{foo} is replaced with a summary of the keymap (symbol-value foo). 879 /* \{foo} is replaced with a summary of the keymap (symbol-value foo).
813 \<foo> just sets the keymap used for \[cmd]. */ 880 \<foo> just sets the keymap used for \[cmd]. */
814 else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<')) 881 else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<'))
815 { 882 {
816 struct buffer *oldbuf; 883 struct buffer *oldbuf;
817 int start_idx; 884 int start_idx;
885 /* This is for computing the SHADOWS arg for describe_map_tree. */
886 Lisp_Object active_maps = Fcurrent_active_maps (Qnil);
887 Lisp_Object earlier_maps;
818 888
819 changed = 1; 889 changed = 1;
820 strp += 2; /* skip \{ or \< */ 890 strp += 2; /* skip \{ or \< */
821 start = strp; 891 start = strp;
822 start_idx = start - SDATA (string); 892 start_idx = start - SDATA (string);
823 893
824 while ((strp - (unsigned char *) SDATA (string) 894 while ((strp - SDATA (string) < SBYTES (string))
825 < SCHARS (string))
826 && *strp != '}' && *strp != '>') 895 && *strp != '}' && *strp != '>')
827 strp++; 896 strp++;
828 897
829 length_byte = strp - start; 898 length_byte = strp - start;
830 strp++; /* skip } or > */ 899 strp++; /* skip } or > */
831 900
832 /* Save STRP in IDX. */ 901 /* Save STRP in IDX. */
833 idx = strp - (unsigned char *) SDATA (string); 902 idx = strp - SDATA (string);
834 903
835 /* Get the value of the keymap in TEM, or nil if undefined. 904 /* Get the value of the keymap in TEM, or nil if undefined.
836 Do this while still in the user's current buffer 905 Do this while still in the user's current buffer
837 in case it is a local variable. */ 906 in case it is a local variable. */
838 name = Fintern (make_string (start, length_byte), Qnil); 907 name = Fintern (make_string (start, length_byte), Qnil);
864 if (start[-1] == '<') keymap = Qnil; 933 if (start[-1] == '<') keymap = Qnil;
865 } 934 }
866 else if (start[-1] == '<') 935 else if (start[-1] == '<')
867 keymap = tem; 936 keymap = tem;
868 else 937 else
869 describe_map_tree (tem, 1, Qnil, Qnil, (char *)0, 1, 0, 0); 938 {
939 /* Get the list of active keymaps that precede this one.
940 If this one's not active, get nil. */
941 earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps)));
942 describe_map_tree (tem, 1, Fnreverse (earlier_maps),
943 Qnil, (char *)0, 1, 0, 0, 1);
944 }
870 tem = Fbuffer_string (); 945 tem = Fbuffer_string ();
871 Ferase_buffer (); 946 Ferase_buffer ();
872 set_buffer_internal (oldbuf); 947 set_buffer_internal (oldbuf);
873 948
874 subst_string: 949 subst_string:
921 996
922 DEFVAR_LISP ("internal-doc-file-name", &Vdoc_file_name, 997 DEFVAR_LISP ("internal-doc-file-name", &Vdoc_file_name,
923 doc: /* Name of file containing documentation strings of built-in symbols. */); 998 doc: /* Name of file containing documentation strings of built-in symbols. */);
924 Vdoc_file_name = Qnil; 999 Vdoc_file_name = Qnil;
925 1000
1001 DEFVAR_LISP ("build-files", &Vbuild_files,
1002 doc: /* A list of files used to build this Emacs binary. */);
1003 Vbuild_files = Qnil;
1004
926 defsubr (&Sdocumentation); 1005 defsubr (&Sdocumentation);
927 defsubr (&Sdocumentation_property); 1006 defsubr (&Sdocumentation_property);
928 defsubr (&Ssnarf_documentation); 1007 defsubr (&Ssnarf_documentation);
929 defsubr (&Ssubstitute_command_keys); 1008 defsubr (&Ssubstitute_command_keys);
930 } 1009 }
1010
1011 /* arch-tag: 56281d4d-6949-43e2-be2e-f6517de744ba
1012 (do not change this comment) */