Mercurial > emacs
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) */ |