]> code.delx.au - gnu-emacs/blob - lib-src/make-docfile.c
(scan_lisp_file): Fix typo causing infloop.
[gnu-emacs] / lib-src / make-docfile.c
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985, 1986, 92, 93, 94, 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 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 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 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 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* The arguments given to this program are all the C and Lisp source files
22 of GNU Emacs. .elc and .el and .c files are allowed.
23 A .o file can also be specified; the .c file it was made from is used.
24 This helps the makefile pass the correct list of files.
25
26 The results, which go to standard output or to a file
27 specified with -a or -o (-a to append, -o to start from nothing),
28 are entries containing function or variable names and their documentation.
29 Each entry starts with a ^_ character.
30 Then comes F for a function or V for a variable.
31 Then comes the function or variable name, terminated with a newline.
32 Then comes the documentation for that function or variable.
33 */
34
35 #define NO_SHORTNAMES /* Tell config not to load remap.h */
36 #include <config.h>
37
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>
44 #ifdef MSDOS
45 #include <fcntl.h>
46 #endif /* MSDOS */
47 #ifdef WINDOWSNT
48 #include <stdlib.h>
49 #include <fcntl.h>
50 #include <direct.h>
51 #endif /* WINDOWSNT */
52
53 #ifdef DOS_NT
54 #define READ_TEXT "rt"
55 #define READ_BINARY "rb"
56 #else /* not DOS_NT */
57 #define READ_TEXT "r"
58 #define READ_BINARY "r"
59 #endif /* not DOS_NT */
60
61 int scan_file ();
62 int scan_lisp_file ();
63 int scan_c_file ();
64
65 #ifdef MSDOS
66 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
67 file where that function is defined. */
68 #undef chdir
69 #endif
70
71 #ifdef HAVE_UNISTD_H
72 #include <unistd.h>
73 #endif
74
75 #ifdef STDC_HEADERS
76 #include <stdlib.h>
77 #endif
78
79 /* Stdio stream for output to the DOC file. */
80 FILE *outfile;
81
82 /* Name this program was invoked with. */
83 char *progname;
84
85 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
86
87 /* VARARGS1 */
88 void
89 error (s1, s2)
90 char *s1, *s2;
91 {
92 fprintf (stderr, "%s: ", progname);
93 fprintf (stderr, s1, s2);
94 fprintf (stderr, "\n");
95 }
96
97 /* Print error message and exit. */
98
99 /* VARARGS1 */
100 void
101 fatal (s1, s2)
102 char *s1, *s2;
103 {
104 error (s1, s2);
105 exit (1);
106 }
107
108 /* Like malloc but get fatal error if memory is exhausted. */
109
110 long *
111 xmalloc (size)
112 unsigned int size;
113 {
114 long *result = (long *) malloc (size);
115 if (result == NULL)
116 fatal ("virtual memory exhausted", 0);
117 return result;
118 }
119 \f
120 int
121 main (argc, argv)
122 int argc;
123 char **argv;
124 {
125 int i;
126 int err_count = 0;
127 int first_infile;
128
129 progname = argv[0];
130
131 outfile = stdout;
132
133 /* Don't put CRs in the DOC file. */
134 #ifdef MSDOS
135 _fmode = O_BINARY;
136 #if 0 /* Suspicion is that this causes hanging.
137 So instead we require people to use -o on MSDOS. */
138 (stdout)->_flag &= ~_IOTEXT;
139 _setmode (fileno (stdout), O_BINARY);
140 #endif
141 outfile = 0;
142 #endif /* MSDOS */
143 #ifdef WINDOWSNT
144 _fmode = O_BINARY;
145 _setmode (fileno (stdout), O_BINARY);
146 #endif /* WINDOWSNT */
147
148 /* If first two args are -o FILE, output to FILE. */
149 i = 1;
150 if (argc > i + 1 && !strcmp (argv[i], "-o"))
151 {
152 outfile = fopen (argv[i + 1], "w");
153 i += 2;
154 }
155 if (argc > i + 1 && !strcmp (argv[i], "-a"))
156 {
157 outfile = fopen (argv[i + 1], "a");
158 i += 2;
159 }
160 if (argc > i + 1 && !strcmp (argv[i], "-d"))
161 {
162 chdir (argv[i + 1]);
163 i += 2;
164 }
165
166 if (outfile == 0)
167 fatal ("No output file specified", "");
168
169 first_infile = i;
170 for (; i < argc; i++)
171 {
172 int j;
173 /* Don't process one file twice. */
174 for (j = first_infile; j < i; j++)
175 if (! strcmp (argv[i], argv[j]))
176 break;
177 if (j == i)
178 err_count += scan_file (argv[i]);
179 }
180 #ifndef VMS
181 exit (err_count > 0);
182 #endif /* VMS */
183 return err_count > 0;
184 }
185
186 /* Read file FILENAME and output its doc strings to outfile. */
187 /* Return 1 if file is not found, 0 if it is found. */
188
189 int
190 scan_file (filename)
191 char *filename;
192 {
193 int len = strlen (filename);
194 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
195 return scan_lisp_file (filename, READ_BINARY);
196 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
197 return scan_lisp_file (filename, READ_TEXT);
198 else
199 return scan_c_file (filename, READ_TEXT);
200 }
201 \f
202 char buf[128];
203
204 /* Skip a C string from INFILE,
205 and return the character that follows the closing ".
206 If printflag is positive, output string contents to outfile.
207 If it is negative, store contents in buf.
208 Convert escape sequences \n and \t to newline and tab;
209 discard \ followed by newline. */
210
211 int
212 read_c_string (infile, printflag)
213 FILE *infile;
214 int printflag;
215 {
216 register int c;
217 char *p = buf;
218
219 c = getc (infile);
220 while (c != EOF)
221 {
222 while (c != '"' && c != EOF)
223 {
224 if (c == '\\')
225 {
226 c = getc (infile);
227 if (c == '\n' || c == '\r')
228 {
229 c = getc (infile);
230 continue;
231 }
232 if (c == 'n')
233 c = '\n';
234 if (c == 't')
235 c = '\t';
236 }
237 if (printflag > 0)
238 putc (c, outfile);
239 else if (printflag < 0)
240 *p++ = c;
241 c = getc (infile);
242 }
243 c = getc (infile);
244 if (c != '"')
245 break;
246 /* If we had a "", concatenate the two strings. */
247 c = getc (infile);
248 }
249
250 if (printflag < 0)
251 *p = 0;
252
253 return c;
254 }
255 \f
256 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
257 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
258
259 void
260 write_c_args (out, func, buf, minargs, maxargs)
261 FILE *out;
262 char *func, *buf;
263 int minargs, maxargs;
264 {
265 register char *p;
266 int in_ident = 0;
267 int just_spaced = 0;
268 int need_space = 1;
269
270 fprintf (out, "(%s", func);
271
272 if (*buf == '(')
273 ++buf;
274
275 for (p = buf; *p; p++)
276 {
277 char c = *p;
278 int ident_start = 0;
279
280 /* Notice when we start printing a new identifier. */
281 if ((('A' <= c && c <= 'Z')
282 || ('a' <= c && c <= 'z')
283 || ('0' <= c && c <= '9')
284 || c == '_')
285 != in_ident)
286 {
287 if (!in_ident)
288 {
289 in_ident = 1;
290 ident_start = 1;
291
292 if (need_space)
293 putc (' ', out);
294
295 if (minargs == 0 && maxargs > 0)
296 fprintf (out, "&optional ");
297 just_spaced = 1;
298
299 minargs--;
300 maxargs--;
301 }
302 else
303 in_ident = 0;
304 }
305
306 /* Print the C argument list as it would appear in lisp:
307 print underscores as hyphens, and print commas as spaces.
308 Collapse adjacent spaces into one. */
309 if (c == '_') c = '-';
310 if (c == ',') c = ' ';
311
312 /* In C code, `default' is a reserved word, so we spell it
313 `defalt'; unmangle that here. */
314 if (ident_start
315 && strncmp (p, "defalt", 6) == 0
316 && ! (('A' <= p[6] && p[6] <= 'Z')
317 || ('a' <= p[6] && p[6] <= 'z')
318 || ('0' <= p[6] && p[6] <= '9')
319 || p[6] == '_'))
320 {
321 fprintf (out, "DEFAULT");
322 p += 5;
323 in_ident = 0;
324 just_spaced = 0;
325 }
326 else if (c != ' ' || ! just_spaced)
327 {
328 if (c >= 'a' && c <= 'z')
329 /* Upcase the letter. */
330 c += 'A' - 'a';
331 putc (c, out);
332 }
333
334 just_spaced = (c == ' ');
335 need_space = 0;
336 }
337 }
338 \f
339 /* Read through a c file. If a .o file is named,
340 the corresponding .c file is read instead.
341 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
342 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
343
344 int
345 scan_c_file (filename, mode)
346 char *filename, *mode;
347 {
348 FILE *infile;
349 register int c;
350 register int commas;
351 register int defunflag;
352 register int defvarperbufferflag;
353 register int defvarflag;
354 int minargs, maxargs;
355 int extension = filename[strlen (filename) - 1];
356
357 if (extension == 'o')
358 filename[strlen (filename) - 1] = 'c';
359
360 infile = fopen (filename, mode);
361
362 /* No error if non-ex input file */
363 if (infile == NULL)
364 {
365 perror (filename);
366 return 0;
367 }
368
369 /* Reset extension to be able to detect duplicate files. */
370 filename[strlen (filename) - 1] = extension;
371
372 c = '\n';
373 while (!feof (infile))
374 {
375 if (c != '\n' && c != '\r')
376 {
377 c = getc (infile);
378 continue;
379 }
380 c = getc (infile);
381 if (c == ' ')
382 {
383 while (c == ' ')
384 c = getc (infile);
385 if (c != 'D')
386 continue;
387 c = getc (infile);
388 if (c != 'E')
389 continue;
390 c = getc (infile);
391 if (c != 'F')
392 continue;
393 c = getc (infile);
394 if (c != 'V')
395 continue;
396 c = getc (infile);
397 if (c != 'A')
398 continue;
399 c = getc (infile);
400 if (c != 'R')
401 continue;
402 c = getc (infile);
403 if (c != '_')
404 continue;
405
406 defvarflag = 1;
407 defunflag = 0;
408
409 c = getc (infile);
410 defvarperbufferflag = (c == 'P');
411
412 c = getc (infile);
413 }
414 else if (c == 'D')
415 {
416 c = getc (infile);
417 if (c != 'E')
418 continue;
419 c = getc (infile);
420 if (c != 'F')
421 continue;
422 c = getc (infile);
423 defunflag = c == 'U';
424 defvarflag = 0;
425 }
426 else continue;
427
428 while (c != '(')
429 {
430 if (c < 0)
431 goto eof;
432 c = getc (infile);
433 }
434
435 c = getc (infile);
436 if (c != '"')
437 continue;
438 c = read_c_string (infile, -1);
439
440 if (defunflag)
441 commas = 5;
442 else if (defvarperbufferflag)
443 commas = 2;
444 else if (defvarflag)
445 commas = 1;
446 else /* For DEFSIMPLE and DEFPRED */
447 commas = 2;
448
449 while (commas)
450 {
451 if (c == ',')
452 {
453 commas--;
454 if (defunflag && (commas == 1 || commas == 2))
455 {
456 do
457 c = getc (infile);
458 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
459 if (c < 0)
460 goto eof;
461 ungetc (c, infile);
462 if (commas == 2) /* pick up minargs */
463 fscanf (infile, "%d", &minargs);
464 else /* pick up maxargs */
465 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
466 maxargs = -1;
467 else
468 fscanf (infile, "%d", &maxargs);
469 }
470 }
471 if (c < 0)
472 goto eof;
473 c = getc (infile);
474 }
475 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
476 c = getc (infile);
477 if (c == '"')
478 c = read_c_string (infile, 0);
479 while (c != ',')
480 c = getc (infile);
481 c = getc (infile);
482 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
483 c = getc (infile);
484
485 if (c == '"')
486 {
487 putc (037, outfile);
488 putc (defvarflag ? 'V' : 'F', outfile);
489 fprintf (outfile, "%s\n", buf);
490 c = read_c_string (infile, 1);
491
492 /* If this is a defun, find the arguments and print them. If
493 this function takes MANY or UNEVALLED args, then the C source
494 won't give the names of the arguments, so we shouldn't bother
495 trying to find them. */
496 if (defunflag && maxargs != -1)
497 {
498 char argbuf[1024], *p = argbuf;
499 while (c != ')')
500 {
501 if (c < 0)
502 goto eof;
503 c = getc (infile);
504 }
505 /* Skip into arguments. */
506 while (c != '(')
507 {
508 if (c < 0)
509 goto eof;
510 c = getc (infile);
511 }
512 /* Copy arguments into ARGBUF. */
513 *p++ = c;
514 do
515 *p++ = c = getc (infile);
516 while (c != ')');
517 *p = '\0';
518 /* Output them. */
519 fprintf (outfile, "\n\n");
520 write_c_args (outfile, buf, argbuf, minargs, maxargs);
521 }
522 }
523 }
524 eof:
525 fclose (infile);
526 return 0;
527 }
528 \f
529 /* Read a file of Lisp code, compiled or interpreted.
530 Looks for
531 (defun NAME ARGS DOCSTRING ...)
532 (defmacro NAME ARGS DOCSTRING ...)
533 (autoload (quote NAME) FILE DOCSTRING ...)
534 (defvar NAME VALUE DOCSTRING)
535 (defconst NAME VALUE DOCSTRING)
536 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
537 (fset (quote NAME) #[... DOCSTRING ...])
538 (defalias (quote NAME) #[... DOCSTRING ...])
539 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
540 starting in column zero.
541 (quote NAME) may appear as 'NAME as well.
542
543 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
544 When we find that, we save it for the following defining-form,
545 and we use that instead of reading a doc string within that defining-form.
546
547 For defvar, defconst, and fset we skip to the docstring with a kludgy
548 formatting convention: all docstrings must appear on the same line as the
549 initial open-paren (the one in column zero) and must contain a backslash
550 and a newline immediately after the initial double-quote. No newlines
551 must appear between the beginning of the form and the first double-quote.
552 For defun, defmacro, and autoload, we know how to skip over the
553 arglist, but the doc string must still have a backslash and newline
554 immediately after the double quote.
555 The only source files that must follow this convention are preloaded
556 uncompiled ones like loaddefs.el and bindings.el; aside
557 from that, it is always the .elc file that we look at, and they are no
558 problem because byte-compiler output follows this convention.
559 The NAME and DOCSTRING are output.
560 NAME is preceded by `F' for a function or `V' for a variable.
561 An entry is output only if DOCSTRING has \ newline just after the opening "
562 */
563
564 void
565 skip_white (infile)
566 FILE *infile;
567 {
568 char c = ' ';
569 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
570 c = getc (infile);
571 ungetc (c, infile);
572 }
573
574 void
575 read_lisp_symbol (infile, buffer)
576 FILE *infile;
577 char *buffer;
578 {
579 char c;
580 char *fillp = buffer;
581
582 skip_white (infile);
583 while (1)
584 {
585 c = getc (infile);
586 if (c == '\\')
587 *(++fillp) = getc (infile);
588 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
589 {
590 ungetc (c, infile);
591 *fillp = 0;
592 break;
593 }
594 else
595 *fillp++ = c;
596 }
597
598 if (! buffer[0])
599 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
600
601 skip_white (infile);
602 }
603
604 int
605 scan_lisp_file (filename, mode)
606 char *filename, *mode;
607 {
608 FILE *infile;
609 register int c;
610 char *saved_string = 0;
611
612 infile = fopen (filename, mode);
613 if (infile == NULL)
614 {
615 perror (filename);
616 return 0; /* No error */
617 }
618
619 c = '\n';
620 while (!feof (infile))
621 {
622 char buffer[BUFSIZ];
623 char type;
624
625 /* If not at end of line, skip till we get to one. */
626 if (c != '\n' && c != '\r')
627 {
628 c = getc (infile);
629 continue;
630 }
631 /* Skip the line break. */
632 while (c == '\n' || c == '\r')
633 c = getc (infile);
634 /* Detect a dynamic doc string and save it for the next expression. */
635 if (c == '#')
636 {
637 c = getc (infile);
638 if (c == '@')
639 {
640 int length = 0;
641 int i;
642
643 /* Read the length. */
644 while ((c = getc (infile),
645 c >= '0' && c <= '9'))
646 {
647 length *= 10;
648 length += c - '0';
649 }
650
651 /* The next character is a space that is counted in the length
652 but not part of the doc string.
653 We already read it, so just ignore it. */
654 length--;
655
656 /* Read in the contents. */
657 if (saved_string != 0)
658 free (saved_string);
659 saved_string = (char *) malloc (length);
660 for (i = 0; i < length; i++)
661 saved_string[i] = getc (infile);
662 /* The last character is a ^_.
663 That is needed in the .elc file
664 but it is redundant in DOC. So get rid of it here. */
665 saved_string[length - 1] = 0;
666 /* Skip the line break. */
667 while (c == '\n' && c == '\r')
668 c = getc (infile);
669 /* Skip the following line. */
670 while (c != '\n' && c != '\r')
671 c = getc (infile);
672 }
673 continue;
674 }
675
676 if (c != '(')
677 continue;
678
679 read_lisp_symbol (infile, buffer);
680
681 if (! strcmp (buffer, "defun")
682 || ! strcmp (buffer, "defmacro"))
683 {
684 type = 'F';
685 read_lisp_symbol (infile, buffer);
686
687 /* Skip the arguments: either "nil" or a list in parens */
688
689 c = getc (infile);
690 if (c == 'n') /* nil */
691 {
692 if ((c = getc (infile)) != 'i'
693 || (c = getc (infile)) != 'l')
694 {
695 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
696 buffer, filename);
697 continue;
698 }
699 }
700 else if (c != '(')
701 {
702 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
703 buffer, filename);
704 continue;
705 }
706 else
707 while (c != ')')
708 c = getc (infile);
709 skip_white (infile);
710
711 /* If the next three characters aren't `dquote bslash newline'
712 then we're not reading a docstring.
713 */
714 if ((c = getc (infile)) != '"'
715 || (c = getc (infile)) != '\\'
716 || ((c = getc (infile)) != '\n' && c != '\r'))
717 {
718 #ifdef DEBUG
719 fprintf (stderr, "## non-docstring in %s (%s)\n",
720 buffer, filename);
721 #endif
722 continue;
723 }
724 }
725
726 else if (! strcmp (buffer, "defvar")
727 || ! strcmp (buffer, "defconst"))
728 {
729 char c1 = 0, c2 = 0;
730 type = 'V';
731 read_lisp_symbol (infile, buffer);
732
733 if (saved_string == 0)
734 {
735
736 /* Skip until the end of line; remember two previous chars. */
737 while (c != '\n' && c != '\r' && c >= 0)
738 {
739 c2 = c1;
740 c1 = c;
741 c = getc (infile);
742 }
743
744 /* If two previous characters were " and \,
745 this is a doc string. Otherwise, there is none. */
746 if (c2 != '"' || c1 != '\\')
747 {
748 #ifdef DEBUG
749 fprintf (stderr, "## non-docstring in %s (%s)\n",
750 buffer, filename);
751 #endif
752 continue;
753 }
754 }
755 }
756
757 else if (! strcmp (buffer, "custom-declare-variable"))
758 {
759 char c1 = 0, c2 = 0;
760 type = 'V';
761
762 c = getc (infile);
763 if (c == '\'')
764 read_lisp_symbol (infile, buffer);
765 else
766 {
767 if (c != '(')
768 {
769 fprintf (stderr,
770 "## unparsable name in custom-declare-variable in %s\n",
771 filename);
772 continue;
773 }
774 read_lisp_symbol (infile, buffer);
775 if (strcmp (buffer, "quote"))
776 {
777 fprintf (stderr,
778 "## unparsable name in custom-declare-variable in %s\n",
779 filename);
780 continue;
781 }
782 read_lisp_symbol (infile, buffer);
783 c = getc (infile);
784 if (c != ')')
785 {
786 fprintf (stderr,
787 "## unparsable quoted name in custom-declare-variable in %s\n",
788 filename);
789 continue;
790 }
791 }
792
793 if (saved_string == 0)
794 {
795 /* Skip to end of line; remember the two previous chars. */
796 while (c != '\n' && c != '\r' && c >= 0)
797 {
798 c2 = c1;
799 c1 = c;
800 c = getc (infile);
801 }
802
803 /* If two previous characters were " and \,
804 this is a doc string. Otherwise, there is none. */
805 if (c2 != '"' || c1 != '\\')
806 {
807 #ifdef DEBUG
808 fprintf (stderr, "## non-docstring in %s (%s)\n",
809 buffer, filename);
810 #endif
811 continue;
812 }
813 }
814 }
815
816 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
817 {
818 char c1 = 0, c2 = 0;
819 type = 'F';
820
821 c = getc (infile);
822 if (c == '\'')
823 read_lisp_symbol (infile, buffer);
824 else
825 {
826 if (c != '(')
827 {
828 fprintf (stderr, "## unparsable name in fset in %s\n",
829 filename);
830 continue;
831 }
832 read_lisp_symbol (infile, buffer);
833 if (strcmp (buffer, "quote"))
834 {
835 fprintf (stderr, "## unparsable name in fset in %s\n",
836 filename);
837 continue;
838 }
839 read_lisp_symbol (infile, buffer);
840 c = getc (infile);
841 if (c != ')')
842 {
843 fprintf (stderr,
844 "## unparsable quoted name in fset in %s\n",
845 filename);
846 continue;
847 }
848 }
849
850 if (saved_string == 0)
851 {
852 /* Skip to end of line; remember the two previous chars. */
853 while (c != '\n' && c != '\r' && c >= 0)
854 {
855 c2 = c1;
856 c1 = c;
857 c = getc (infile);
858 }
859
860 /* If two previous characters were " and \,
861 this is a doc string. Otherwise, there is none. */
862 if (c2 != '"' || c1 != '\\')
863 {
864 #ifdef DEBUG
865 fprintf (stderr, "## non-docstring in %s (%s)\n",
866 buffer, filename);
867 #endif
868 continue;
869 }
870 }
871 }
872
873 else if (! strcmp (buffer, "autoload"))
874 {
875 type = 'F';
876 c = getc (infile);
877 if (c == '\'')
878 read_lisp_symbol (infile, buffer);
879 else
880 {
881 if (c != '(')
882 {
883 fprintf (stderr, "## unparsable name in autoload in %s\n",
884 filename);
885 continue;
886 }
887 read_lisp_symbol (infile, buffer);
888 if (strcmp (buffer, "quote"))
889 {
890 fprintf (stderr, "## unparsable name in autoload in %s\n",
891 filename);
892 continue;
893 }
894 read_lisp_symbol (infile, buffer);
895 c = getc (infile);
896 if (c != ')')
897 {
898 fprintf (stderr,
899 "## unparsable quoted name in autoload in %s\n",
900 filename);
901 continue;
902 }
903 }
904 skip_white (infile);
905 if ((c = getc (infile)) != '\"')
906 {
907 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
908 buffer, filename);
909 continue;
910 }
911 read_c_string (infile, 0);
912 skip_white (infile);
913
914 if (saved_string == 0)
915 {
916 /* If the next three characters aren't `dquote bslash newline'
917 then we're not reading a docstring. */
918 if ((c = getc (infile)) != '"'
919 || (c = getc (infile)) != '\\'
920 || ((c = getc (infile)) != '\n' && c != '\r'))
921 {
922 #ifdef DEBUG
923 fprintf (stderr, "## non-docstring in %s (%s)\n",
924 buffer, filename);
925 #endif
926 continue;
927 }
928 }
929 }
930
931 #ifdef DEBUG
932 else if (! strcmp (buffer, "if")
933 || ! strcmp (buffer, "byte-code"))
934 ;
935 #endif
936
937 else
938 {
939 #ifdef DEBUG
940 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
941 buffer, filename);
942 #endif
943 continue;
944 }
945
946 /* At this point, we should either use the previous
947 dynamic doc string in saved_string
948 or gobble a doc string from the input file.
949
950 In the latter case, the opening quote (and leading
951 backslash-newline) have already been read. */
952
953 putc (037, outfile);
954 putc (type, outfile);
955 fprintf (outfile, "%s\n", buffer);
956 if (saved_string)
957 {
958 fputs (saved_string, outfile);
959 /* Don't use one dynamic doc string twice. */
960 free (saved_string);
961 saved_string = 0;
962 }
963 else
964 read_c_string (infile, 1);
965 }
966 fclose (infile);
967 return 0;
968 }