Revert last fix; subset of last fix recommitted.
[emacs.git] / lib-src / make-docfile.c
blob1564aca5bbea67e686f3c6267b6e8801aceda701
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985, 1986, 1992, 1993, 1994, 1997, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* The arguments given to this program are all the C and Lisp source files
24 of GNU Emacs. .elc and .el and .c files are allowed.
25 A .o file can also be specified; the .c file it was made from is used.
26 This helps the makefile pass the correct list of files.
27 Option -d DIR means change to DIR before looking for files.
29 The results, which go to standard output or to a file
30 specified with -a or -o (-a to append, -o to start from nothing),
31 are entries containing function or variable names and their documentation.
32 Each entry starts with a ^_ character.
33 Then comes F for a function or V for a variable.
34 Then comes the function or variable name, terminated with a newline.
35 Then comes the documentation for that function or variable.
38 #define NO_SHORTNAMES /* Tell config not to load remap.h */
39 #include <config.h>
41 /* defined to be emacs_main, sys_fopen, etc. in config.h */
42 #undef main
43 #undef fopen
44 #undef chdir
46 #include <stdio.h>
47 #ifdef MSDOS
48 #include <fcntl.h>
49 #endif /* MSDOS */
50 #ifdef WINDOWSNT
51 #include <stdlib.h>
52 #include <fcntl.h>
53 #include <direct.h>
54 #endif /* WINDOWSNT */
56 #ifdef DOS_NT
57 #define READ_TEXT "rt"
58 #define READ_BINARY "rb"
59 #else /* not DOS_NT */
60 #define READ_TEXT "r"
61 #define READ_BINARY "r"
62 #endif /* not DOS_NT */
64 #ifndef DIRECTORY_SEP
65 #ifdef MAC_OS8
66 #define DIRECTORY_SEP ':'
67 #else /* not MAC_OS8 */
68 #define DIRECTORY_SEP '/'
69 #endif /* not MAC_OS8 */
70 #endif
72 #ifndef IS_DIRECTORY_SEP
73 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
74 #endif
76 int scan_file ();
77 int scan_lisp_file ();
78 int scan_c_file ();
80 #ifdef MSDOS
81 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
82 file where that function is defined. */
83 #undef chdir
84 #endif
86 #ifdef HAVE_UNISTD_H
87 #include <unistd.h>
88 #endif
90 /* Stdio stream for output to the DOC file. */
91 FILE *outfile;
93 /* Name this program was invoked with. */
94 char *progname;
96 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
98 /* VARARGS1 */
99 void
100 error (s1, s2)
101 char *s1, *s2;
103 fprintf (stderr, "%s: ", progname);
104 fprintf (stderr, s1, s2);
105 fprintf (stderr, "\n");
108 /* Print error message and exit. */
110 /* VARARGS1 */
111 void
112 fatal (s1, s2)
113 char *s1, *s2;
115 error (s1, s2);
116 exit (EXIT_FAILURE);
119 /* Like malloc but get fatal error if memory is exhausted. */
121 void *
122 xmalloc (size)
123 unsigned int size;
125 void *result = (void *) malloc (size);
126 if (result == NULL)
127 fatal ("virtual memory exhausted", 0);
128 return result;
132 main (argc, argv)
133 int argc;
134 char **argv;
136 int i;
137 int err_count = 0;
138 int first_infile;
140 progname = argv[0];
142 outfile = stdout;
144 /* Don't put CRs in the DOC file. */
145 #ifdef MSDOS
146 _fmode = O_BINARY;
147 #if 0 /* Suspicion is that this causes hanging.
148 So instead we require people to use -o on MSDOS. */
149 (stdout)->_flag &= ~_IOTEXT;
150 _setmode (fileno (stdout), O_BINARY);
151 #endif
152 outfile = 0;
153 #endif /* MSDOS */
154 #ifdef WINDOWSNT
155 _fmode = O_BINARY;
156 _setmode (fileno (stdout), O_BINARY);
157 #endif /* WINDOWSNT */
159 /* If first two args are -o FILE, output to FILE. */
160 i = 1;
161 if (argc > i + 1 && !strcmp (argv[i], "-o"))
163 outfile = fopen (argv[i + 1], "w");
164 i += 2;
166 if (argc > i + 1 && !strcmp (argv[i], "-a"))
168 outfile = fopen (argv[i + 1], "a");
169 i += 2;
171 if (argc > i + 1 && !strcmp (argv[i], "-d"))
173 chdir (argv[i + 1]);
174 i += 2;
177 if (outfile == 0)
178 fatal ("No output file specified", "");
180 first_infile = i;
181 for (; i < argc; i++)
183 int j;
184 /* Don't process one file twice. */
185 for (j = first_infile; j < i; j++)
186 if (! strcmp (argv[i], argv[j]))
187 break;
188 if (j == i)
189 err_count += scan_file (argv[i]);
191 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
194 /* Add a source file name boundary marker in the output file. */
195 void
196 put_filename (filename)
197 char *filename;
199 char *tmp;
201 for (tmp = filename; *tmp; tmp++)
203 if (IS_DIRECTORY_SEP(*tmp))
204 filename = tmp + 1;
207 putc (037, outfile);
208 putc ('S', outfile);
209 fprintf (outfile, "%s\n", filename);
212 /* Read file FILENAME and output its doc strings to outfile. */
213 /* Return 1 if file is not found, 0 if it is found. */
216 scan_file (filename)
217 char *filename;
219 int len = strlen (filename);
221 put_filename (filename);
222 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
223 return scan_lisp_file (filename, READ_BINARY);
224 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
225 return scan_lisp_file (filename, READ_TEXT);
226 else
227 return scan_c_file (filename, READ_TEXT);
230 char buf[128];
232 /* Some state during the execution of `read_c_string_or_comment'. */
233 struct rcsoc_state
235 /* A count of spaces and newlines that have been read, but not output. */
236 unsigned pending_spaces, pending_newlines;
238 /* Where we're reading from. */
239 FILE *in_file;
241 /* If non-zero, a buffer into which to copy characters. */
242 char *buf_ptr;
243 /* If non-zero, a file into which to copy characters. */
244 FILE *out_file;
246 /* A keyword we look for at the beginning of lines. If found, it is
247 not copied, and SAW_KEYWORD is set to true. */
248 char *keyword;
249 /* The current point we've reached in an occurance of KEYWORD in
250 the input stream. */
251 char *cur_keyword_ptr;
252 /* Set to true if we saw an occurance of KEYWORD. */
253 int saw_keyword;
256 /* Output CH to the file or buffer in STATE. Any pending newlines or
257 spaces are output first. */
259 static INLINE void
260 put_char (ch, state)
261 int ch;
262 struct rcsoc_state *state;
264 int out_ch;
267 if (state->pending_newlines > 0)
269 state->pending_newlines--;
270 out_ch = '\n';
272 else if (state->pending_spaces > 0)
274 state->pending_spaces--;
275 out_ch = ' ';
277 else
278 out_ch = ch;
280 if (state->out_file)
281 putc (out_ch, state->out_file);
282 if (state->buf_ptr)
283 *state->buf_ptr++ = out_ch;
285 while (out_ch != ch);
288 /* If in the middle of scanning a keyword, continue scanning with
289 character CH, otherwise output CH to the file or buffer in STATE.
290 Any pending newlines or spaces are output first, as well as any
291 previously scanned characters that were thought to be part of a
292 keyword, but were in fact not. */
294 static void
295 scan_keyword_or_put_char (ch, state)
296 int ch;
297 struct rcsoc_state *state;
299 if (state->keyword
300 && *state->cur_keyword_ptr == ch
301 && (state->cur_keyword_ptr > state->keyword
302 || state->pending_newlines > 0))
303 /* We might be looking at STATE->keyword at some point.
304 Keep looking until we know for sure. */
306 if (*++state->cur_keyword_ptr == '\0')
307 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
309 state->saw_keyword = 1;
311 /* Reset the scanning pointer. */
312 state->cur_keyword_ptr = state->keyword;
314 /* Canonicalize whitespace preceding a usage string. */
315 state->pending_newlines = 2;
316 state->pending_spaces = 0;
318 /* Skip any whitespace between the keyword and the
319 usage string. */
321 ch = getc (state->in_file);
322 while (ch == ' ' || ch == '\n');
324 /* Output the open-paren we just read. */
325 put_char (ch, state);
327 /* Skip the function name and replace it with `fn'. */
329 ch = getc (state->in_file);
330 while (ch != ' ' && ch != ')');
331 put_char ('f', state);
332 put_char ('n', state);
334 /* Put back the last character. */
335 ungetc (ch, state->in_file);
338 else
340 if (state->keyword && state->cur_keyword_ptr > state->keyword)
341 /* We scanned the beginning of a potential usage
342 keyword, but it was a false alarm. Output the
343 part we scanned. */
345 char *p;
347 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
348 put_char (*p, state);
350 state->cur_keyword_ptr = state->keyword;
353 put_char (ch, state);
358 /* Skip a C string or C-style comment from INFILE, and return the
359 character that follows. COMMENT non-zero means skip a comment. If
360 PRINTFLAG is positive, output string contents to outfile. If it is
361 negative, store contents in buf. Convert escape sequences \n and
362 \t to newline and tab; discard \ followed by newline.
363 If SAW_USAGE is non-zero, then any occurances of the string `usage:'
364 at the beginning of a line will be removed, and *SAW_USAGE set to
365 true if any were encountered. */
368 read_c_string_or_comment (infile, printflag, comment, saw_usage)
369 FILE *infile;
370 int printflag;
371 int *saw_usage;
372 int comment;
374 register int c;
375 struct rcsoc_state state;
377 state.in_file = infile;
378 state.buf_ptr = (printflag < 0 ? buf : 0);
379 state.out_file = (printflag > 0 ? outfile : 0);
380 state.pending_spaces = 0;
381 state.pending_newlines = 0;
382 state.keyword = (saw_usage ? "usage:" : 0);
383 state.cur_keyword_ptr = state.keyword;
384 state.saw_keyword = 0;
386 c = getc (infile);
387 if (comment)
388 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
389 c = getc (infile);
391 while (c != EOF)
393 while (c != EOF && (comment ? c != '*' : c != '"'))
395 if (c == '\\')
397 c = getc (infile);
398 if (c == '\n' || c == '\r')
400 c = getc (infile);
401 continue;
403 if (c == 'n')
404 c = '\n';
405 if (c == 't')
406 c = '\t';
409 if (c == ' ')
410 state.pending_spaces++;
411 else if (c == '\n')
413 state.pending_newlines++;
414 state.pending_spaces = 0;
416 else
417 scan_keyword_or_put_char (c, &state);
419 c = getc (infile);
422 if (c != EOF)
423 c = getc (infile);
425 if (comment)
427 if (c == '/')
429 c = getc (infile);
430 break;
433 scan_keyword_or_put_char ('*', &state);
435 else
437 if (c != '"')
438 break;
440 /* If we had a "", concatenate the two strings. */
441 c = getc (infile);
445 if (printflag < 0)
446 *state.buf_ptr = 0;
448 if (saw_usage)
449 *saw_usage = state.saw_keyword;
451 return c;
456 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
457 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
459 void
460 write_c_args (out, func, buf, minargs, maxargs)
461 FILE *out;
462 char *func, *buf;
463 int minargs, maxargs;
465 register char *p;
466 int in_ident = 0;
467 int just_spaced = 0;
468 int need_space = 1;
470 fprintf (out, "(fn");
472 if (*buf == '(')
473 ++buf;
475 for (p = buf; *p; p++)
477 char c = *p;
478 int ident_start = 0;
480 /* Notice when we start printing a new identifier. */
481 if ((('A' <= c && c <= 'Z')
482 || ('a' <= c && c <= 'z')
483 || ('0' <= c && c <= '9')
484 || c == '_')
485 != in_ident)
487 if (!in_ident)
489 in_ident = 1;
490 ident_start = 1;
492 if (need_space)
493 putc (' ', out);
495 if (minargs == 0 && maxargs > 0)
496 fprintf (out, "&optional ");
497 just_spaced = 1;
499 minargs--;
500 maxargs--;
502 else
503 in_ident = 0;
506 /* Print the C argument list as it would appear in lisp:
507 print underscores as hyphens, and print commas and newlines
508 as spaces. Collapse adjacent spaces into one. */
509 if (c == '_')
510 c = '-';
511 else if (c == ',' || c == '\n')
512 c = ' ';
514 /* In C code, `default' is a reserved word, so we spell it
515 `defalt'; unmangle that here. */
516 if (ident_start
517 && strncmp (p, "defalt", 6) == 0
518 && ! (('A' <= p[6] && p[6] <= 'Z')
519 || ('a' <= p[6] && p[6] <= 'z')
520 || ('0' <= p[6] && p[6] <= '9')
521 || p[6] == '_'))
523 fprintf (out, "DEFAULT");
524 p += 5;
525 in_ident = 0;
526 just_spaced = 0;
528 else if (c != ' ' || !just_spaced)
530 if (c >= 'a' && c <= 'z')
531 /* Upcase the letter. */
532 c += 'A' - 'a';
533 putc (c, out);
536 just_spaced = c == ' ';
537 need_space = 0;
541 /* Read through a c file. If a .o file is named,
542 the corresponding .c file is read instead.
543 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
544 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
547 scan_c_file (filename, mode)
548 char *filename, *mode;
550 FILE *infile;
551 register int c;
552 register int commas;
553 register int defunflag;
554 register int defvarperbufferflag;
555 register int defvarflag;
556 int minargs, maxargs;
557 int extension = filename[strlen (filename) - 1];
559 if (extension == 'o')
560 filename[strlen (filename) - 1] = 'c';
562 infile = fopen (filename, mode);
564 /* No error if non-ex input file */
565 if (infile == NULL)
567 perror (filename);
568 return 0;
571 /* Reset extension to be able to detect duplicate files. */
572 filename[strlen (filename) - 1] = extension;
574 c = '\n';
575 while (!feof (infile))
577 int doc_keyword = 0;
579 if (c != '\n' && c != '\r')
581 c = getc (infile);
582 continue;
584 c = getc (infile);
585 if (c == ' ')
587 while (c == ' ')
588 c = getc (infile);
589 if (c != 'D')
590 continue;
591 c = getc (infile);
592 if (c != 'E')
593 continue;
594 c = getc (infile);
595 if (c != 'F')
596 continue;
597 c = getc (infile);
598 if (c != 'V')
599 continue;
600 c = getc (infile);
601 if (c != 'A')
602 continue;
603 c = getc (infile);
604 if (c != 'R')
605 continue;
606 c = getc (infile);
607 if (c != '_')
608 continue;
610 defvarflag = 1;
611 defunflag = 0;
613 c = getc (infile);
614 defvarperbufferflag = (c == 'P');
616 c = getc (infile);
618 else if (c == 'D')
620 c = getc (infile);
621 if (c != 'E')
622 continue;
623 c = getc (infile);
624 if (c != 'F')
625 continue;
626 c = getc (infile);
627 defunflag = c == 'U';
628 defvarflag = 0;
629 defvarperbufferflag = 0;
631 else continue;
633 while (c != '(')
635 if (c < 0)
636 goto eof;
637 c = getc (infile);
640 /* Lisp variable or function name. */
641 c = getc (infile);
642 if (c != '"')
643 continue;
644 c = read_c_string_or_comment (infile, -1, 0, 0);
646 /* DEFVAR_LISP ("name", addr, "doc")
647 DEFVAR_LISP ("name", addr /\* doc *\/)
648 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
650 if (defunflag)
651 commas = 5;
652 else if (defvarperbufferflag)
653 commas = 2;
654 else if (defvarflag)
655 commas = 1;
656 else /* For DEFSIMPLE and DEFPRED */
657 commas = 2;
659 while (commas)
661 if (c == ',')
663 commas--;
665 if (defunflag && (commas == 1 || commas == 2))
668 c = getc (infile);
669 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
670 if (c < 0)
671 goto eof;
672 ungetc (c, infile);
673 if (commas == 2) /* pick up minargs */
674 fscanf (infile, "%d", &minargs);
675 else /* pick up maxargs */
676 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
677 maxargs = -1;
678 else
679 fscanf (infile, "%d", &maxargs);
683 if (c == EOF)
684 goto eof;
685 c = getc (infile);
688 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
689 c = getc (infile);
691 if (c == '"')
692 c = read_c_string_or_comment (infile, 0, 0, 0);
694 while (c != EOF && c != ',' && c != '/')
695 c = getc (infile);
696 if (c == ',')
698 c = getc (infile);
699 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
700 c = getc (infile);
701 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
702 c = getc (infile);
703 if (c == ':')
705 doc_keyword = 1;
706 c = getc (infile);
707 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
708 c = getc (infile);
712 if (c == '"'
713 || (c == '/'
714 && (c = getc (infile),
715 ungetc (c, infile),
716 c == '*')))
718 int comment = c != '"';
719 int saw_usage;
721 putc (037, outfile);
722 putc (defvarflag ? 'V' : 'F', outfile);
723 fprintf (outfile, "%s\n", buf);
725 if (comment)
726 getc (infile); /* Skip past `*' */
727 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
729 /* If this is a defun, find the arguments and print them. If
730 this function takes MANY or UNEVALLED args, then the C source
731 won't give the names of the arguments, so we shouldn't bother
732 trying to find them.
734 Various doc-string styles:
735 0: DEFUN (..., "DOC") (args) [!comment]
736 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
737 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
739 if (defunflag && maxargs != -1 && !saw_usage)
741 char argbuf[1024], *p = argbuf;
743 if (!comment || doc_keyword)
744 while (c != ')')
746 if (c < 0)
747 goto eof;
748 c = getc (infile);
751 /* Skip into arguments. */
752 while (c != '(')
754 if (c < 0)
755 goto eof;
756 c = getc (infile);
758 /* Copy arguments into ARGBUF. */
759 *p++ = c;
761 *p++ = c = getc (infile);
762 while (c != ')');
763 *p = '\0';
764 /* Output them. */
765 fprintf (outfile, "\n\n");
766 write_c_args (outfile, buf, argbuf, minargs, maxargs);
768 else if (defunflag && maxargs == -1 && !saw_usage)
769 /* The DOC should provide the usage form. */
770 fprintf (stderr, "Missing `usage' for function `%s'.\n", buf);
773 eof:
774 fclose (infile);
775 return 0;
778 /* Read a file of Lisp code, compiled or interpreted.
779 Looks for
780 (defun NAME ARGS DOCSTRING ...)
781 (defmacro NAME ARGS DOCSTRING ...)
782 (defsubst NAME ARGS DOCSTRING ...)
783 (autoload (quote NAME) FILE DOCSTRING ...)
784 (defvar NAME VALUE DOCSTRING)
785 (defconst NAME VALUE DOCSTRING)
786 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
787 (fset (quote NAME) #[... DOCSTRING ...])
788 (defalias (quote NAME) #[... DOCSTRING ...])
789 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
790 starting in column zero.
791 (quote NAME) may appear as 'NAME as well.
793 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
794 When we find that, we save it for the following defining-form,
795 and we use that instead of reading a doc string within that defining-form.
797 For defvar, defconst, and fset we skip to the docstring with a kludgy
798 formatting convention: all docstrings must appear on the same line as the
799 initial open-paren (the one in column zero) and must contain a backslash
800 and a newline immediately after the initial double-quote. No newlines
801 must appear between the beginning of the form and the first double-quote.
802 For defun, defmacro, and autoload, we know how to skip over the
803 arglist, but the doc string must still have a backslash and newline
804 immediately after the double quote.
805 The only source files that must follow this convention are preloaded
806 uncompiled ones like loaddefs.el and bindings.el; aside
807 from that, it is always the .elc file that we look at, and they are no
808 problem because byte-compiler output follows this convention.
809 The NAME and DOCSTRING are output.
810 NAME is preceded by `F' for a function or `V' for a variable.
811 An entry is output only if DOCSTRING has \ newline just after the opening "
814 void
815 skip_white (infile)
816 FILE *infile;
818 char c = ' ';
819 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
820 c = getc (infile);
821 ungetc (c, infile);
824 void
825 read_lisp_symbol (infile, buffer)
826 FILE *infile;
827 char *buffer;
829 char c;
830 char *fillp = buffer;
832 skip_white (infile);
833 while (1)
835 c = getc (infile);
836 if (c == '\\')
837 *(++fillp) = getc (infile);
838 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
840 ungetc (c, infile);
841 *fillp = 0;
842 break;
844 else
845 *fillp++ = c;
848 if (! buffer[0])
849 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
851 skip_white (infile);
855 scan_lisp_file (filename, mode)
856 char *filename, *mode;
858 FILE *infile;
859 register int c;
860 char *saved_string = 0;
862 infile = fopen (filename, mode);
863 if (infile == NULL)
865 perror (filename);
866 return 0; /* No error */
869 c = '\n';
870 while (!feof (infile))
872 char buffer[BUFSIZ];
873 char type;
875 /* If not at end of line, skip till we get to one. */
876 if (c != '\n' && c != '\r')
878 c = getc (infile);
879 continue;
881 /* Skip the line break. */
882 while (c == '\n' || c == '\r')
883 c = getc (infile);
884 /* Detect a dynamic doc string and save it for the next expression. */
885 if (c == '#')
887 c = getc (infile);
888 if (c == '@')
890 int length = 0;
891 int i;
893 /* Read the length. */
894 while ((c = getc (infile),
895 c >= '0' && c <= '9'))
897 length *= 10;
898 length += c - '0';
901 /* The next character is a space that is counted in the length
902 but not part of the doc string.
903 We already read it, so just ignore it. */
904 length--;
906 /* Read in the contents. */
907 if (saved_string != 0)
908 free (saved_string);
909 saved_string = (char *) malloc (length);
910 for (i = 0; i < length; i++)
911 saved_string[i] = getc (infile);
912 /* The last character is a ^_.
913 That is needed in the .elc file
914 but it is redundant in DOC. So get rid of it here. */
915 saved_string[length - 1] = 0;
916 /* Skip the line break. */
917 while (c == '\n' && c == '\r')
918 c = getc (infile);
919 /* Skip the following line. */
920 while (c != '\n' && c != '\r')
921 c = getc (infile);
923 continue;
926 if (c != '(')
927 continue;
929 read_lisp_symbol (infile, buffer);
931 if (! strcmp (buffer, "defun")
932 || ! strcmp (buffer, "defmacro")
933 || ! strcmp (buffer, "defsubst"))
935 type = 'F';
936 read_lisp_symbol (infile, buffer);
938 /* Skip the arguments: either "nil" or a list in parens */
940 c = getc (infile);
941 if (c == 'n') /* nil */
943 if ((c = getc (infile)) != 'i'
944 || (c = getc (infile)) != 'l')
946 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
947 buffer, filename);
948 continue;
951 else if (c != '(')
953 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
954 buffer, filename);
955 continue;
957 else
958 while (c != ')')
959 c = getc (infile);
960 skip_white (infile);
962 /* If the next three characters aren't `dquote bslash newline'
963 then we're not reading a docstring.
965 if ((c = getc (infile)) != '"'
966 || (c = getc (infile)) != '\\'
967 || ((c = getc (infile)) != '\n' && c != '\r'))
969 #ifdef DEBUG
970 fprintf (stderr, "## non-docstring in %s (%s)\n",
971 buffer, filename);
972 #endif
973 continue;
977 else if (! strcmp (buffer, "defvar")
978 || ! strcmp (buffer, "defconst"))
980 char c1 = 0, c2 = 0;
981 type = 'V';
982 read_lisp_symbol (infile, buffer);
984 if (saved_string == 0)
987 /* Skip until the end of line; remember two previous chars. */
988 while (c != '\n' && c != '\r' && c >= 0)
990 c2 = c1;
991 c1 = c;
992 c = getc (infile);
995 /* If two previous characters were " and \,
996 this is a doc string. Otherwise, there is none. */
997 if (c2 != '"' || c1 != '\\')
999 #ifdef DEBUG
1000 fprintf (stderr, "## non-docstring in %s (%s)\n",
1001 buffer, filename);
1002 #endif
1003 continue;
1008 else if (! strcmp (buffer, "custom-declare-variable"))
1010 char c1 = 0, c2 = 0;
1011 type = 'V';
1013 c = getc (infile);
1014 if (c == '\'')
1015 read_lisp_symbol (infile, buffer);
1016 else
1018 if (c != '(')
1020 fprintf (stderr,
1021 "## unparsable name in custom-declare-variable in %s\n",
1022 filename);
1023 continue;
1025 read_lisp_symbol (infile, buffer);
1026 if (strcmp (buffer, "quote"))
1028 fprintf (stderr,
1029 "## unparsable name in custom-declare-variable in %s\n",
1030 filename);
1031 continue;
1033 read_lisp_symbol (infile, buffer);
1034 c = getc (infile);
1035 if (c != ')')
1037 fprintf (stderr,
1038 "## unparsable quoted name in custom-declare-variable in %s\n",
1039 filename);
1040 continue;
1044 if (saved_string == 0)
1046 /* Skip to end of line; remember the two previous chars. */
1047 while (c != '\n' && c != '\r' && c >= 0)
1049 c2 = c1;
1050 c1 = c;
1051 c = getc (infile);
1054 /* If two previous characters were " and \,
1055 this is a doc string. Otherwise, there is none. */
1056 if (c2 != '"' || c1 != '\\')
1058 #ifdef DEBUG
1059 fprintf (stderr, "## non-docstring in %s (%s)\n",
1060 buffer, filename);
1061 #endif
1062 continue;
1067 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1069 char c1 = 0, c2 = 0;
1070 type = 'F';
1072 c = getc (infile);
1073 if (c == '\'')
1074 read_lisp_symbol (infile, buffer);
1075 else
1077 if (c != '(')
1079 fprintf (stderr, "## unparsable name in fset in %s\n",
1080 filename);
1081 continue;
1083 read_lisp_symbol (infile, buffer);
1084 if (strcmp (buffer, "quote"))
1086 fprintf (stderr, "## unparsable name in fset in %s\n",
1087 filename);
1088 continue;
1090 read_lisp_symbol (infile, buffer);
1091 c = getc (infile);
1092 if (c != ')')
1094 fprintf (stderr,
1095 "## unparsable quoted name in fset in %s\n",
1096 filename);
1097 continue;
1101 if (saved_string == 0)
1103 /* Skip to end of line; remember the two previous chars. */
1104 while (c != '\n' && c != '\r' && c >= 0)
1106 c2 = c1;
1107 c1 = c;
1108 c = getc (infile);
1111 /* If two previous characters were " and \,
1112 this is a doc string. Otherwise, there is none. */
1113 if (c2 != '"' || c1 != '\\')
1115 #ifdef DEBUG
1116 fprintf (stderr, "## non-docstring in %s (%s)\n",
1117 buffer, filename);
1118 #endif
1119 continue;
1124 else if (! strcmp (buffer, "autoload"))
1126 type = 'F';
1127 c = getc (infile);
1128 if (c == '\'')
1129 read_lisp_symbol (infile, buffer);
1130 else
1132 if (c != '(')
1134 fprintf (stderr, "## unparsable name in autoload in %s\n",
1135 filename);
1136 continue;
1138 read_lisp_symbol (infile, buffer);
1139 if (strcmp (buffer, "quote"))
1141 fprintf (stderr, "## unparsable name in autoload in %s\n",
1142 filename);
1143 continue;
1145 read_lisp_symbol (infile, buffer);
1146 c = getc (infile);
1147 if (c != ')')
1149 fprintf (stderr,
1150 "## unparsable quoted name in autoload in %s\n",
1151 filename);
1152 continue;
1155 skip_white (infile);
1156 if ((c = getc (infile)) != '\"')
1158 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1159 buffer, filename);
1160 continue;
1162 read_c_string_or_comment (infile, 0, 0, 0);
1163 skip_white (infile);
1165 if (saved_string == 0)
1167 /* If the next three characters aren't `dquote bslash newline'
1168 then we're not reading a docstring. */
1169 if ((c = getc (infile)) != '"'
1170 || (c = getc (infile)) != '\\'
1171 || ((c = getc (infile)) != '\n' && c != '\r'))
1173 #ifdef DEBUG
1174 fprintf (stderr, "## non-docstring in %s (%s)\n",
1175 buffer, filename);
1176 #endif
1177 continue;
1182 #ifdef DEBUG
1183 else if (! strcmp (buffer, "if")
1184 || ! strcmp (buffer, "byte-code"))
1186 #endif
1188 else
1190 #ifdef DEBUG
1191 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
1192 buffer, filename);
1193 #endif
1194 continue;
1197 /* At this point, we should either use the previous
1198 dynamic doc string in saved_string
1199 or gobble a doc string from the input file.
1201 In the latter case, the opening quote (and leading
1202 backslash-newline) have already been read. */
1204 putc (037, outfile);
1205 putc (type, outfile);
1206 fprintf (outfile, "%s\n", buffer);
1207 if (saved_string)
1209 fputs (saved_string, outfile);
1210 /* Don't use one dynamic doc string twice. */
1211 free (saved_string);
1212 saved_string = 0;
1214 else
1215 read_c_string_or_comment (infile, 1, 0, 0);
1217 fclose (infile);
1218 return 0;
1221 /* arch-tag: f7203aaf-991a-4238-acb5-601db56f2894
1222 (do not change this comment) */
1224 /* make-docfile.c ends here */