aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src/make-docfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src/make-docfile.c')
-rw-r--r--lib-src/make-docfile.c351
1 files changed, 197 insertions, 154 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 1ec365f3446..68e7029ee85 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -1,6 +1,7 @@
1/* Generate doc-string file for GNU Emacs from source files. 1/* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2011 2
3 Free Software Foundation, Inc. 3Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2012
4 Free Software Foundation, Inc.
4 5
5This file is part of GNU Emacs. 6This file is part of GNU Emacs.
6 7
@@ -35,57 +36,41 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35 36
36#include <config.h> 37#include <config.h>
37 38
38/* defined to be emacs_main, sys_fopen, etc. in config.h */
39#undef main
40#undef fopen
41#undef chdir
42
43#include <stdio.h> 39#include <stdio.h>
44#include <stdlib.h> 40#include <stdlib.h> /* config.h unconditionally includes this anyway */
45#ifdef MSDOS 41#ifdef MSDOS
46#include <fcntl.h> 42#include <fcntl.h>
47#endif /* MSDOS */ 43#endif /* MSDOS */
48#ifdef WINDOWSNT 44#ifdef WINDOWSNT
45/* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
46 is really just insurance. */
47#undef fopen
49#include <fcntl.h> 48#include <fcntl.h>
50#include <direct.h> 49#include <direct.h>
51#endif /* WINDOWSNT */ 50#endif /* WINDOWSNT */
52 51
53#ifdef DOS_NT 52#ifdef DOS_NT
53/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
54 is really just insurance.
55
56 Similarly, msdos defines this as sys_chdir, but we're not linking with the
57 file where that function is defined. */
58#undef chdir
54#define READ_TEXT "rt" 59#define READ_TEXT "rt"
55#define READ_BINARY "rb" 60#define READ_BINARY "rb"
61#define IS_SLASH(c) ((c) == '/' || (c) == '\\' || (c) == ':')
56#else /* not DOS_NT */ 62#else /* not DOS_NT */
57#define READ_TEXT "r" 63#define READ_TEXT "r"
58#define READ_BINARY "r" 64#define READ_BINARY "r"
65#define IS_SLASH(c) ((c) == '/')
59#endif /* not DOS_NT */ 66#endif /* not DOS_NT */
60 67
61#ifndef DIRECTORY_SEP
62#define DIRECTORY_SEP '/'
63#endif
64
65#ifndef IS_DIRECTORY_SEP
66#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
67#endif
68
69/* Use this to suppress gcc's `...may be used before initialized' warnings. */
70#ifdef lint
71# define IF_LINT(Code) Code
72#else
73# define IF_LINT(Code) /* empty */
74#endif
75
76static int scan_file (char *filename); 68static int scan_file (char *filename);
77static int scan_lisp_file (const char *filename, const char *mode); 69static int scan_lisp_file (const char *filename, const char *mode);
78static int scan_c_file (char *filename, const char *mode); 70static int scan_c_file (char *filename, const char *mode);
79static void fatal (const char *s1, const char *s2) NO_RETURN;
80static void start_globals (void); 71static void start_globals (void);
81static void write_globals (void); 72static void write_globals (void);
82 73
83#ifdef MSDOS
84/* s/msdos.h defines this as sys_chdir, but we're not linking with the
85 file where that function is defined. */
86#undef chdir
87#endif
88
89#include <unistd.h> 74#include <unistd.h>
90 75
91/* Stdio stream for output to the DOC file. */ 76/* Stdio stream for output to the DOC file. */
@@ -111,7 +96,7 @@ error (const char *s1, const char *s2)
111/* Print error message and exit. */ 96/* Print error message and exit. */
112 97
113/* VARARGS1 */ 98/* VARARGS1 */
114static void 99static _Noreturn void
115fatal (const char *s1, const char *s2) 100fatal (const char *s1, const char *s2)
116{ 101{
117 error (s1, s2); 102 error (s1, s2);
@@ -226,7 +211,7 @@ put_filename (char *filename)
226 211
227 for (tmp = filename; *tmp; tmp++) 212 for (tmp = filename; *tmp; tmp++)
228 { 213 {
229 if (IS_DIRECTORY_SEP(*tmp)) 214 if (IS_DIRECTORY_SEP (*tmp))
230 filename = tmp + 1; 215 filename = tmp + 1;
231 } 216 }
232 217
@@ -541,8 +526,8 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
541 maxargs--; 526 maxargs--;
542 527
543 /* In C code, `default' is a reserved word, so we spell it 528 /* In C code, `default' is a reserved word, so we spell it
544 `defalt'; unmangle that here. */ 529 `defalt'; demangle that here. */
545 if (ident_length == 6 && strncmp (ident_start, "defalt", 6) == 0) 530 if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0)
546 fprintf (out, "DEFAULT"); 531 fprintf (out, "DEFAULT");
547 else 532 else
548 while (ident_length-- > 0) 533 while (ident_length-- > 0)
@@ -562,13 +547,15 @@ write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
562 putc (')', out); 547 putc (')', out);
563} 548}
564 549
565/* The types of globals. */ 550/* The types of globals. These are sorted roughly in decreasing alignment
551 order to avoid allocation gaps, except that functions are last. */
566enum global_type 552enum global_type
567{ 553{
554 INVALID,
555 LISP_OBJECT,
568 EMACS_INTEGER, 556 EMACS_INTEGER,
569 BOOLEAN, 557 BOOLEAN,
570 LISP_OBJECT, 558 FUNCTION,
571 INVALID
572}; 559};
573 560
574/* A single global. */ 561/* A single global. */
@@ -576,6 +563,7 @@ struct global
576{ 563{
577 enum global_type type; 564 enum global_type type;
578 char *name; 565 char *name;
566 int value;
579}; 567};
580 568
581/* All the variable names we saw while scanning C sources in `-g' 569/* All the variable names we saw while scanning C sources in `-g'
@@ -585,7 +573,7 @@ int num_globals_allocated;
585struct global *globals; 573struct global *globals;
586 574
587static void 575static void
588add_global (enum global_type type, char *name) 576add_global (enum global_type type, char *name, int value)
589{ 577{
590 /* Ignore the one non-symbol that can occur. */ 578 /* Ignore the one non-symbol that can occur. */
591 if (strcmp (name, "...")) 579 if (strcmp (name, "..."))
@@ -606,6 +594,7 @@ add_global (enum global_type type, char *name)
606 594
607 globals[num_globals - 1].type = type; 595 globals[num_globals - 1].type = type;
608 globals[num_globals - 1].name = name; 596 globals[num_globals - 1].name = name;
597 globals[num_globals - 1].value = value;
609 } 598 }
610} 599}
611 600
@@ -614,13 +603,24 @@ compare_globals (const void *a, const void *b)
614{ 603{
615 const struct global *ga = a; 604 const struct global *ga = a;
616 const struct global *gb = b; 605 const struct global *gb = b;
606
607 if (ga->type != gb->type)
608 return ga->type - gb->type;
609
617 return strcmp (ga->name, gb->name); 610 return strcmp (ga->name, gb->name);
618} 611}
619 612
620static void 613static void
614close_emacs_globals (void)
615{
616 fprintf (outfile, "};\n");
617 fprintf (outfile, "extern struct emacs_globals globals;\n");
618}
619
620static void
621write_globals (void) 621write_globals (void)
622{ 622{
623 int i; 623 int i, seen_defun = 0;
624 qsort (globals, num_globals, sizeof (struct global), compare_globals); 624 qsort (globals, num_globals, sizeof (struct global), compare_globals);
625 for (i = 0; i < num_globals; ++i) 625 for (i = 0; i < num_globals; ++i)
626 { 626 {
@@ -632,25 +632,62 @@ write_globals (void)
632 type = "EMACS_INT"; 632 type = "EMACS_INT";
633 break; 633 break;
634 case BOOLEAN: 634 case BOOLEAN:
635 type = "int"; 635 type = "bool";
636 break; 636 break;
637 case LISP_OBJECT: 637 case LISP_OBJECT:
638 type = "Lisp_Object"; 638 type = "Lisp_Object";
639 break; 639 break;
640 case FUNCTION:
641 if (!seen_defun)
642 {
643 close_emacs_globals ();
644 fprintf (outfile, "\n");
645 seen_defun = 1;
646 }
647 break;
640 default: 648 default:
641 fatal ("not a recognized DEFVAR_", 0); 649 fatal ("not a recognized DEFVAR_", 0);
642 } 650 }
643 651
644 fprintf (outfile, " %s f_%s;\n", type, globals[i].name); 652 if (globals[i].type != FUNCTION)
645 fprintf (outfile, "#define %s globals.f_%s\n", 653 {
646 globals[i].name, globals[i].name); 654 fprintf (outfile, " %s f_%s;\n", type, globals[i].name);
655 fprintf (outfile, "#define %s globals.f_%s\n",
656 globals[i].name, globals[i].name);
657 }
658 else
659 {
660 /* It would be nice to have a cleaner way to deal with these
661 special hacks. */
662 if (strcmp (globals[i].name, "Fthrow") == 0
663 || strcmp (globals[i].name, "Ftop_level") == 0
664 || strcmp (globals[i].name, "Fkill_emacs") == 0
665 || strcmp (globals[i].name, "Fexit_recursive_edit") == 0
666 || strcmp (globals[i].name, "Fabort_recursive_edit") == 0)
667 fprintf (outfile, "_Noreturn ");
668 fprintf (outfile, "EXFUN (%s, ", globals[i].name);
669 if (globals[i].value == -1)
670 fprintf (outfile, "MANY");
671 else if (globals[i].value == -2)
672 fprintf (outfile, "UNEVALLED");
673 else
674 fprintf (outfile, "%d", globals[i].value);
675 fprintf (outfile, ");\n");
676 }
677
647 while (i + 1 < num_globals 678 while (i + 1 < num_globals
648 && !strcmp (globals[i].name, globals[i + 1].name)) 679 && !strcmp (globals[i].name, globals[i + 1].name))
649 ++i; 680 {
681 if (globals[i].type == FUNCTION
682 && globals[i].value != globals[i + 1].value)
683 error ("function '%s' defined twice with differing signatures",
684 globals[i].name);
685 ++i;
686 }
650 } 687 }
651 688
652 fprintf (outfile, "};\n"); 689 if (!seen_defun)
653 fprintf (outfile, "extern struct emacs_globals globals;\n"); 690 close_emacs_globals ();
654} 691}
655 692
656 693
@@ -675,14 +712,14 @@ scan_c_file (char *filename, const char *mode)
675 712
676 if (infile == NULL && extension == 'o') 713 if (infile == NULL && extension == 'o')
677 { 714 {
678 /* try .m */ 715 /* Try .m. */
679 filename[strlen (filename) - 1] = 'm'; 716 filename[strlen (filename) - 1] = 'm';
680 infile = fopen (filename, mode); 717 infile = fopen (filename, mode);
681 if (infile == NULL) 718 if (infile == NULL)
682 filename[strlen (filename) - 1] = 'c'; /* don't confuse people */ 719 filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */
683 } 720 }
684 721
685 /* No error if non-ex input file */ 722 /* No error if non-ex input file. */
686 if (infile == NULL) 723 if (infile == NULL)
687 { 724 {
688 perror (filename); 725 perror (filename);
@@ -700,6 +737,7 @@ scan_c_file (char *filename, const char *mode)
700 int defvarperbufferflag = 0; 737 int defvarperbufferflag = 0;
701 int defvarflag = 0; 738 int defvarflag = 0;
702 enum global_type type = INVALID; 739 enum global_type type = INVALID;
740 char *name IF_LINT (= 0);
703 741
704 if (c != '\n' && c != '\r') 742 if (c != '\n' && c != '\r')
705 { 743 {
@@ -765,8 +803,9 @@ scan_c_file (char *filename, const char *mode)
765 } 803 }
766 else continue; 804 else continue;
767 805
768 if (generate_globals && (!defvarflag || defvarperbufferflag 806 if (generate_globals
769 || type == INVALID)) 807 && (!defvarflag || defvarperbufferflag || type == INVALID)
808 && !defunflag)
770 continue; 809 continue;
771 810
772 while (c != '(') 811 while (c != '(')
@@ -785,7 +824,6 @@ scan_c_file (char *filename, const char *mode)
785 if (generate_globals) 824 if (generate_globals)
786 { 825 {
787 int i = 0; 826 int i = 0;
788 char *name;
789 827
790 /* Skip "," and whitespace. */ 828 /* Skip "," and whitespace. */
791 do 829 do
@@ -800,14 +838,18 @@ scan_c_file (char *filename, const char *mode)
800 input_buffer[i++] = c; 838 input_buffer[i++] = c;
801 c = getc (infile); 839 c = getc (infile);
802 } 840 }
803 while (! (c == ',' || c == ' ' || c == '\t' || 841 while (! (c == ',' || c == ' ' || c == '\t'
804 c == '\n' || c == '\r')); 842 || c == '\n' || c == '\r'));
805 input_buffer[i] = '\0'; 843 input_buffer[i] = '\0';
806 844
807 name = xmalloc (i + 1); 845 name = xmalloc (i + 1);
808 memcpy (name, input_buffer, i + 1); 846 memcpy (name, input_buffer, i + 1);
809 add_global (type, name); 847
810 continue; 848 if (!defunflag)
849 {
850 add_global (type, name, 0);
851 continue;
852 }
811 } 853 }
812 854
813 /* DEFVAR_LISP ("name", addr, "doc") 855 /* DEFVAR_LISP ("name", addr, "doc")
@@ -815,12 +857,12 @@ scan_c_file (char *filename, const char *mode)
815 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */ 857 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
816 858
817 if (defunflag) 859 if (defunflag)
818 commas = 5; 860 commas = generate_globals ? 4 : 5;
819 else if (defvarperbufferflag) 861 else if (defvarperbufferflag)
820 commas = 3; 862 commas = 3;
821 else if (defvarflag) 863 else if (defvarflag)
822 commas = 1; 864 commas = 1;
823 else /* For DEFSIMPLE and DEFPRED */ 865 else /* For DEFSIMPLE and DEFPRED. */
824 commas = 2; 866 commas = 2;
825 867
826 while (commas) 868 while (commas)
@@ -838,11 +880,16 @@ scan_c_file (char *filename, const char *mode)
838 if (c < 0) 880 if (c < 0)
839 goto eof; 881 goto eof;
840 ungetc (c, infile); 882 ungetc (c, infile);
841 if (commas == 2) /* pick up minargs */ 883 if (commas == 2) /* Pick up minargs. */
842 scanned = fscanf (infile, "%d", &minargs); 884 scanned = fscanf (infile, "%d", &minargs);
843 else /* pick up maxargs */ 885 else /* Pick up maxargs. */
844 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */ 886 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
845 maxargs = -1; 887 {
888 if (generate_globals)
889 maxargs = (c == 'M') ? -1 : -2;
890 else
891 maxargs = -1;
892 }
846 else 893 else
847 scanned = fscanf (infile, "%d", &maxargs); 894 scanned = fscanf (infile, "%d", &maxargs);
848 if (scanned < 0) 895 if (scanned < 0)
@@ -855,6 +902,12 @@ scan_c_file (char *filename, const char *mode)
855 c = getc (infile); 902 c = getc (infile);
856 } 903 }
857 904
905 if (generate_globals)
906 {
907 add_global (FUNCTION, name, maxargs);
908 continue;
909 }
910
858 while (c == ' ' || c == '\n' || c == '\r' || c == '\t') 911 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
859 c = getc (infile); 912 c = getc (infile);
860 913
@@ -893,7 +946,7 @@ scan_c_file (char *filename, const char *mode)
893 fprintf (outfile, "%s\n", input_buffer); 946 fprintf (outfile, "%s\n", input_buffer);
894 947
895 if (comment) 948 if (comment)
896 getc (infile); /* Skip past `*' */ 949 getc (infile); /* Skip past `*'. */
897 c = read_c_string_or_comment (infile, 1, comment, &saw_usage); 950 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
898 951
899 /* If this is a defun, find the arguments and print them. If 952 /* If this is a defun, find the arguments and print them. If
@@ -974,12 +1027,12 @@ scan_c_file (char *filename, const char *mode)
974 arglist, but the doc string must still have a backslash and newline 1027 arglist, but the doc string must still have a backslash and newline
975 immediately after the double quote. 1028 immediately after the double quote.
976 The only source files that must follow this convention are preloaded 1029 The only source files that must follow this convention are preloaded
977 uncompiled ones like loaddefs.el and bindings.el; aside 1030 uncompiled ones like loaddefs.el; aside from that, it is always the .elc
978 from that, it is always the .elc file that we look at, and they are no 1031 file that we should look at, and they are no problem because byte-compiler
979 problem because byte-compiler output follows this convention. 1032 output follows this convention.
980 The NAME and DOCSTRING are output. 1033 The NAME and DOCSTRING are output.
981 NAME is preceded by `F' for a function or `V' for a variable. 1034 NAME is preceded by `F' for a function or `V' for a variable.
982 An entry is output only if DOCSTRING has \ newline just after the opening " 1035 An entry is output only if DOCSTRING has \ newline just after the opening ".
983 */ 1036 */
984 1037
985static void 1038static void
@@ -1020,20 +1073,83 @@ read_lisp_symbol (FILE *infile, char *buffer)
1020} 1073}
1021 1074
1022static int 1075static int
1076search_lisp_doc_at_eol (FILE *infile)
1077{
1078 char c = 0, c1 = 0, c2 = 0;
1079
1080 /* Skip until the end of line; remember two previous chars. */
1081 while (c != '\n' && c != '\r' && c != EOF)
1082 {
1083 c2 = c1;
1084 c1 = c;
1085 c = getc (infile);
1086 }
1087
1088 /* If two previous characters were " and \,
1089 this is a doc string. Otherwise, there is none. */
1090 if (c2 != '"' || c1 != '\\')
1091 {
1092#ifdef DEBUG
1093 fprintf (stderr, "## non-docstring in %s (%s)\n",
1094 buffer, filename);
1095#endif
1096 if (c != EOF)
1097 ungetc (c, infile);
1098 return 0;
1099 }
1100 return 1;
1101}
1102
1103#define DEF_ELISP_FILE(fn) { #fn, sizeof(#fn) - 1 }
1104
1105static int
1023scan_lisp_file (const char *filename, const char *mode) 1106scan_lisp_file (const char *filename, const char *mode)
1024{ 1107{
1025 FILE *infile; 1108 FILE *infile;
1026 register int c; 1109 register int c;
1027 char *saved_string = 0; 1110 char *saved_string = 0;
1111 /* These are the only files that are loaded uncompiled, and must
1112 follow the conventions of the doc strings expected by this
1113 function. These conventions are automatically followed by the
1114 byte compiler when it produces the .elc files. */
1115 static struct {
1116 const char *fn;
1117 size_t fl;
1118 } const uncompiled[] = {
1119 DEF_ELISP_FILE (loaddefs.el),
1120 DEF_ELISP_FILE (loadup.el),
1121 DEF_ELISP_FILE (charprop.el),
1122 DEF_ELISP_FILE (cp51932.el),
1123 DEF_ELISP_FILE (eucjp-ms.el)
1124 };
1125 int i, match;
1126 size_t flen = strlen (filename);
1028 1127
1029 if (generate_globals) 1128 if (generate_globals)
1030 fatal ("scanning lisp file when -g specified", 0); 1129 fatal ("scanning lisp file when -g specified", 0);
1130 if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
1131 {
1132 for (i = 0, match = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]);
1133 i++)
1134 {
1135 if (uncompiled[i].fl <= flen
1136 && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
1137 && (flen == uncompiled[i].fl
1138 || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
1139 {
1140 match = 1;
1141 break;
1142 }
1143 }
1144 if (!match)
1145 fatal ("uncompiled lisp file %s is not supported", filename);
1146 }
1031 1147
1032 infile = fopen (filename, mode); 1148 infile = fopen (filename, mode);
1033 if (infile == NULL) 1149 if (infile == NULL)
1034 { 1150 {
1035 perror (filename); 1151 perror (filename);
1036 return 0; /* No error */ 1152 return 0; /* No error. */
1037 } 1153 }
1038 1154
1039 c = '\n'; 1155 c = '\n';
@@ -1110,7 +1226,7 @@ scan_lisp_file (const char *filename, const char *mode)
1110 type = 'F'; 1226 type = 'F';
1111 read_lisp_symbol (infile, buffer); 1227 read_lisp_symbol (infile, buffer);
1112 1228
1113 /* Skip the arguments: either "nil" or a list in parens */ 1229 /* Skip the arguments: either "nil" or a list in parens. */
1114 1230
1115 c = getc (infile); 1231 c = getc (infile);
1116 if (c == 'n') /* nil */ 1232 if (c == 'n') /* nil */
@@ -1154,39 +1270,18 @@ scan_lisp_file (const char *filename, const char *mode)
1154 || ! strcmp (buffer, "defconst") 1270 || ! strcmp (buffer, "defconst")
1155 || ! strcmp (buffer, "defcustom")) 1271 || ! strcmp (buffer, "defcustom"))
1156 { 1272 {
1157 char c1 = 0, c2 = 0;
1158 type = 'V'; 1273 type = 'V';
1159 read_lisp_symbol (infile, buffer); 1274 read_lisp_symbol (infile, buffer);
1160 1275
1161 if (saved_string == 0) 1276 if (saved_string == 0)
1162 { 1277 if (!search_lisp_doc_at_eol (infile))
1163 1278 continue;
1164 /* Skip until the end of line; remember two previous chars. */
1165 while (c != '\n' && c != '\r' && c >= 0)
1166 {
1167 c2 = c1;
1168 c1 = c;
1169 c = getc (infile);
1170 }
1171
1172 /* If two previous characters were " and \,
1173 this is a doc string. Otherwise, there is none. */
1174 if (c2 != '"' || c1 != '\\')
1175 {
1176#ifdef DEBUG
1177 fprintf (stderr, "## non-docstring in %s (%s)\n",
1178 buffer, filename);
1179#endif
1180 continue;
1181 }
1182 }
1183 } 1279 }
1184 1280
1185 else if (! strcmp (buffer, "custom-declare-variable") 1281 else if (! strcmp (buffer, "custom-declare-variable")
1186 || ! strcmp (buffer, "defvaralias") 1282 || ! strcmp (buffer, "defvaralias")
1187 ) 1283 )
1188 { 1284 {
1189 char c1 = 0, c2 = 0;
1190 type = 'V'; 1285 type = 'V';
1191 1286
1192 c = getc (infile); 1287 c = getc (infile);
@@ -1221,31 +1316,12 @@ scan_lisp_file (const char *filename, const char *mode)
1221 } 1316 }
1222 1317
1223 if (saved_string == 0) 1318 if (saved_string == 0)
1224 { 1319 if (!search_lisp_doc_at_eol (infile))
1225 /* Skip to end of line; remember the two previous chars. */ 1320 continue;
1226 while (c != '\n' && c != '\r' && c >= 0)
1227 {
1228 c2 = c1;
1229 c1 = c;
1230 c = getc (infile);
1231 }
1232
1233 /* If two previous characters were " and \,
1234 this is a doc string. Otherwise, there is none. */
1235 if (c2 != '"' || c1 != '\\')
1236 {
1237#ifdef DEBUG
1238 fprintf (stderr, "## non-docstring in %s (%s)\n",
1239 buffer, filename);
1240#endif
1241 continue;
1242 }
1243 }
1244 } 1321 }
1245 1322
1246 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) 1323 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1247 { 1324 {
1248 char c1 = 0, c2 = 0;
1249 type = 'F'; 1325 type = 'F';
1250 1326
1251 c = getc (infile); 1327 c = getc (infile);
@@ -1278,26 +1354,8 @@ scan_lisp_file (const char *filename, const char *mode)
1278 } 1354 }
1279 1355
1280 if (saved_string == 0) 1356 if (saved_string == 0)
1281 { 1357 if (!search_lisp_doc_at_eol (infile))
1282 /* Skip to end of line; remember the two previous chars. */ 1358 continue;
1283 while (c != '\n' && c != '\r' && c >= 0)
1284 {
1285 c2 = c1;
1286 c1 = c;
1287 c = getc (infile);
1288 }
1289
1290 /* If two previous characters were " and \,
1291 this is a doc string. Otherwise, there is none. */
1292 if (c2 != '"' || c1 != '\\')
1293 {
1294#ifdef DEBUG
1295 fprintf (stderr, "## non-docstring in %s (%s)\n",
1296 buffer, filename);
1297#endif
1298 continue;
1299 }
1300 }
1301 } 1359 }
1302 1360
1303 else if (! strcmp (buffer, "autoload")) 1361 else if (! strcmp (buffer, "autoload"))
@@ -1339,29 +1397,16 @@ scan_lisp_file (const char *filename, const char *mode)
1339 continue; 1397 continue;
1340 } 1398 }
1341 read_c_string_or_comment (infile, 0, 0, 0); 1399 read_c_string_or_comment (infile, 0, 0, 0);
1342 skip_white (infile);
1343 1400
1344 if (saved_string == 0) 1401 if (saved_string == 0)
1345 { 1402 if (!search_lisp_doc_at_eol (infile))
1346 /* If the next three characters aren't `dquote bslash newline' 1403 continue;
1347 then we're not reading a docstring. */
1348 if ((c = getc (infile)) != '"'
1349 || (c = getc (infile)) != '\\'
1350 || ((c = getc (infile)) != '\n' && c != '\r'))
1351 {
1352#ifdef DEBUG
1353 fprintf (stderr, "## non-docstring in %s (%s)\n",
1354 buffer, filename);
1355#endif
1356 continue;
1357 }
1358 }
1359 } 1404 }
1360 1405
1361#ifdef DEBUG 1406#ifdef DEBUG
1362 else if (! strcmp (buffer, "if") 1407 else if (! strcmp (buffer, "if")
1363 || ! strcmp (buffer, "byte-code")) 1408 || ! strcmp (buffer, "byte-code"))
1364 ; 1409 continue;
1365#endif 1410#endif
1366 1411
1367 else 1412 else
@@ -1373,12 +1418,10 @@ scan_lisp_file (const char *filename, const char *mode)
1373 continue; 1418 continue;
1374 } 1419 }
1375 1420
1376 /* At this point, we should either use the previous 1421 /* At this point, we should either use the previous dynamic doc string in
1377 dynamic doc string in saved_string 1422 saved_string or gobble a doc string from the input file.
1378 or gobble a doc string from the input file. 1423 In the latter case, the opening quote (and leading backslash-newline)
1379 1424 have already been read. */
1380 In the latter case, the opening quote (and leading
1381 backslash-newline) have already been read. */
1382 1425
1383 putc (037, outfile); 1426 putc (037, outfile);
1384 putc (type, outfile); 1427 putc (type, outfile);