* make-docfile.c (write_c_args): Restructure scanning loop.
[emacs.git] / lib-src / make-docfile.c
blob51c30f91d8fbb380722419b5beddd00d6ca2df3d
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, 2009, 2010
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 of the License, or
11 (at your option) 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. If not, see <http://www.gnu.org/licenses/>. */
22 /* The arguments given to this program are all the C and Lisp source files
23 of GNU Emacs. .elc and .el and .c files are allowed.
24 A .o file can also be specified; the .c file it was made from is used.
25 This helps the makefile pass the correct list of files.
26 Option -d DIR means change to DIR before looking for files.
28 The results, which go to standard output or to a file
29 specified with -a or -o (-a to append, -o to start from nothing),
30 are entries containing function or variable names and their documentation.
31 Each entry starts with a ^_ character.
32 Then comes F for a function or V for a variable.
33 Then comes the function or variable name, terminated with a newline.
34 Then comes the documentation for that function or variable.
37 #include <config.h>
39 /* defined to be emacs_main, sys_fopen, etc. in config.h */
40 #undef main
41 #undef fopen
42 #undef chdir
44 #include <stdio.h>
45 #ifdef MSDOS
46 #include <fcntl.h>
47 #endif /* MSDOS */
48 #ifdef WINDOWSNT
49 #include <stdlib.h>
50 #include <fcntl.h>
51 #include <direct.h>
52 #endif /* WINDOWSNT */
54 #ifdef DOS_NT
55 #define READ_TEXT "rt"
56 #define READ_BINARY "rb"
57 #else /* not DOS_NT */
58 #define READ_TEXT "r"
59 #define READ_BINARY "r"
60 #endif /* not DOS_NT */
62 #ifndef DIRECTORY_SEP
63 #define DIRECTORY_SEP '/'
64 #endif
66 #ifndef IS_DIRECTORY_SEP
67 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
68 #endif
70 int scan_file (char *filename);
71 int scan_lisp_file (char *filename, char *mode);
72 int scan_c_file (char *filename, char *mode);
74 #ifdef MSDOS
75 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
76 file where that function is defined. */
77 #undef chdir
78 #endif
80 #ifdef HAVE_UNISTD_H
81 #include <unistd.h>
82 #endif
84 /* Stdio stream for output to the DOC file. */
85 FILE *outfile;
87 /* Name this program was invoked with. */
88 char *progname;
90 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
92 /* VARARGS1 */
93 void
94 error (char *s1, char *s2)
96 fprintf (stderr, "%s: ", progname);
97 fprintf (stderr, s1, s2);
98 fprintf (stderr, "\n");
101 /* Print error message and exit. */
103 /* VARARGS1 */
104 void
105 fatal (char *s1, char *s2)
107 error (s1, s2);
108 exit (EXIT_FAILURE);
111 /* Like malloc but get fatal error if memory is exhausted. */
113 void *
114 xmalloc (unsigned int size)
116 void *result = (void *) malloc (size);
117 if (result == NULL)
118 fatal ("virtual memory exhausted", 0);
119 return result;
123 main (int argc, char **argv)
125 int i;
126 int err_count = 0;
127 int first_infile;
129 progname = argv[0];
131 outfile = stdout;
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 */
148 /* If first two args are -o FILE, output to FILE. */
149 i = 1;
150 if (argc > i + 1 && !strcmp (argv[i], "-o"))
152 outfile = fopen (argv[i + 1], "w");
153 i += 2;
155 if (argc > i + 1 && !strcmp (argv[i], "-a"))
157 outfile = fopen (argv[i + 1], "a");
158 i += 2;
160 if (argc > i + 1 && !strcmp (argv[i], "-d"))
162 chdir (argv[i + 1]);
163 i += 2;
166 if (outfile == 0)
167 fatal ("No output file specified", "");
169 first_infile = i;
170 for (; i < argc; i++)
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]);
180 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
183 /* Add a source file name boundary marker in the output file. */
184 void
185 put_filename (char *filename)
187 char *tmp;
189 for (tmp = filename; *tmp; tmp++)
191 if (IS_DIRECTORY_SEP(*tmp))
192 filename = tmp + 1;
195 putc (037, outfile);
196 putc ('S', outfile);
197 fprintf (outfile, "%s\n", filename);
200 /* Read file FILENAME and output its doc strings to outfile. */
201 /* Return 1 if file is not found, 0 if it is found. */
204 scan_file (char *filename)
206 int len = strlen (filename);
208 put_filename (filename);
209 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
210 return scan_lisp_file (filename, READ_BINARY);
211 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
212 return scan_lisp_file (filename, READ_TEXT);
213 else
214 return scan_c_file (filename, READ_TEXT);
217 char buf[128];
219 /* Some state during the execution of `read_c_string_or_comment'. */
220 struct rcsoc_state
222 /* A count of spaces and newlines that have been read, but not output. */
223 unsigned pending_spaces, pending_newlines;
225 /* Where we're reading from. */
226 FILE *in_file;
228 /* If non-zero, a buffer into which to copy characters. */
229 char *buf_ptr;
230 /* If non-zero, a file into which to copy characters. */
231 FILE *out_file;
233 /* A keyword we look for at the beginning of lines. If found, it is
234 not copied, and SAW_KEYWORD is set to true. */
235 char *keyword;
236 /* The current point we've reached in an occurrence of KEYWORD in
237 the input stream. */
238 char *cur_keyword_ptr;
239 /* Set to true if we saw an occurrence of KEYWORD. */
240 int saw_keyword;
243 /* Output CH to the file or buffer in STATE. Any pending newlines or
244 spaces are output first. */
246 static INLINE void
247 put_char (int ch, struct rcsoc_state *state)
249 int out_ch;
252 if (state->pending_newlines > 0)
254 state->pending_newlines--;
255 out_ch = '\n';
257 else if (state->pending_spaces > 0)
259 state->pending_spaces--;
260 out_ch = ' ';
262 else
263 out_ch = ch;
265 if (state->out_file)
266 putc (out_ch, state->out_file);
267 if (state->buf_ptr)
268 *state->buf_ptr++ = out_ch;
270 while (out_ch != ch);
273 /* If in the middle of scanning a keyword, continue scanning with
274 character CH, otherwise output CH to the file or buffer in STATE.
275 Any pending newlines or spaces are output first, as well as any
276 previously scanned characters that were thought to be part of a
277 keyword, but were in fact not. */
279 static void
280 scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
282 if (state->keyword
283 && *state->cur_keyword_ptr == ch
284 && (state->cur_keyword_ptr > state->keyword
285 || state->pending_newlines > 0))
286 /* We might be looking at STATE->keyword at some point.
287 Keep looking until we know for sure. */
289 if (*++state->cur_keyword_ptr == '\0')
290 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
292 state->saw_keyword = 1;
294 /* Reset the scanning pointer. */
295 state->cur_keyword_ptr = state->keyword;
297 /* Canonicalize whitespace preceding a usage string. */
298 state->pending_newlines = 2;
299 state->pending_spaces = 0;
301 /* Skip any whitespace between the keyword and the
302 usage string. */
304 ch = getc (state->in_file);
305 while (ch == ' ' || ch == '\n');
307 /* Output the open-paren we just read. */
308 put_char (ch, state);
310 /* Skip the function name and replace it with `fn'. */
312 ch = getc (state->in_file);
313 while (ch != ' ' && ch != ')');
314 put_char ('f', state);
315 put_char ('n', state);
317 /* Put back the last character. */
318 ungetc (ch, state->in_file);
321 else
323 if (state->keyword && state->cur_keyword_ptr > state->keyword)
324 /* We scanned the beginning of a potential usage
325 keyword, but it was a false alarm. Output the
326 part we scanned. */
328 char *p;
330 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
331 put_char (*p, state);
333 state->cur_keyword_ptr = state->keyword;
336 put_char (ch, state);
341 /* Skip a C string or C-style comment from INFILE, and return the
342 character that follows. COMMENT non-zero means skip a comment. If
343 PRINTFLAG is positive, output string contents to outfile. If it is
344 negative, store contents in buf. Convert escape sequences \n and
345 \t to newline and tab; discard \ followed by newline.
346 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
347 at the beginning of a line will be removed, and *SAW_USAGE set to
348 true if any were encountered. */
351 read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
353 register int c;
354 struct rcsoc_state state;
356 state.in_file = infile;
357 state.buf_ptr = (printflag < 0 ? buf : 0);
358 state.out_file = (printflag > 0 ? outfile : 0);
359 state.pending_spaces = 0;
360 state.pending_newlines = 0;
361 state.keyword = (saw_usage ? "usage:" : 0);
362 state.cur_keyword_ptr = state.keyword;
363 state.saw_keyword = 0;
365 c = getc (infile);
366 if (comment)
367 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
368 c = getc (infile);
370 while (c != EOF)
372 while (c != EOF && (comment ? c != '*' : c != '"'))
374 if (c == '\\')
376 c = getc (infile);
377 if (c == '\n' || c == '\r')
379 c = getc (infile);
380 continue;
382 if (c == 'n')
383 c = '\n';
384 if (c == 't')
385 c = '\t';
388 if (c == ' ')
389 state.pending_spaces++;
390 else if (c == '\n')
392 state.pending_newlines++;
393 state.pending_spaces = 0;
395 else
396 scan_keyword_or_put_char (c, &state);
398 c = getc (infile);
401 if (c != EOF)
402 c = getc (infile);
404 if (comment)
406 if (c == '/')
408 c = getc (infile);
409 break;
412 scan_keyword_or_put_char ('*', &state);
414 else
416 if (c != '"')
417 break;
419 /* If we had a "", concatenate the two strings. */
420 c = getc (infile);
424 if (printflag < 0)
425 *state.buf_ptr = 0;
427 if (saw_usage)
428 *saw_usage = state.saw_keyword;
430 return c;
435 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
436 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
438 void
439 write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
441 register char *p;
442 int in_ident = 0;
443 char *ident_start;
444 int ident_length;
446 fprintf (out, "(fn");
448 if (*buf == '(')
449 ++buf;
451 for (p = buf; *p; p++)
453 char c = *p;
455 /* Notice when a new identifier starts. */
456 if ((('A' <= c && c <= 'Z')
457 || ('a' <= c && c <= 'z')
458 || ('0' <= c && c <= '9')
459 || c == '_')
460 != in_ident)
462 if (!in_ident)
464 in_ident = 1;
465 ident_start = p;
467 else
469 in_ident = 0;
470 ident_length = p - ident_start;
474 /* Found the end of an argument, write out the last seen
475 identifier. */
476 if (c == ',' || c == ')')
478 if (strncmp (ident_start, "void", ident_length) == 0)
479 continue;
481 putc (' ', out);
483 if (minargs == 0 && maxargs > 0)
484 fprintf (out, "&optional ");
486 minargs--;
487 maxargs--;
489 /* In C code, `default' is a reserved word, so we spell it
490 `defalt'; unmangle that here. */
491 if (strncmp (ident_start, "defalt", ident_length) == 0)
492 fprintf (out, "DEFAULT");
493 else
494 while (ident_length-- > 0)
496 c = *ident_start++;
497 if (c >= 'a' && c <= 'z')
498 /* Upcase the letter. */
499 c += 'A' - 'a';
500 else if (c == '_')
501 /* Print underscore as hyphen. */
502 c = '-';
503 putc (c, out);
508 putc (')', out);
511 /* Read through a c file. If a .o file is named,
512 the corresponding .c or .m file is read instead.
513 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
514 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
517 scan_c_file (char *filename, char *mode)
519 FILE *infile;
520 register int c;
521 register int commas;
522 register int defunflag;
523 register int defvarperbufferflag;
524 register int defvarflag;
525 int minargs, maxargs;
526 int extension = filename[strlen (filename) - 1];
528 if (extension == 'o')
529 filename[strlen (filename) - 1] = 'c';
531 infile = fopen (filename, mode);
533 if (infile == NULL && extension == 'o')
535 /* try .m */
536 filename[strlen (filename) - 1] = 'm';
537 infile = fopen (filename, mode);
538 if (infile == NULL)
539 filename[strlen (filename) - 1] = 'c'; /* don't confuse people */
542 /* No error if non-ex input file */
543 if (infile == NULL)
545 perror (filename);
546 return 0;
549 /* Reset extension to be able to detect duplicate files. */
550 filename[strlen (filename) - 1] = extension;
552 c = '\n';
553 while (!feof (infile))
555 int doc_keyword = 0;
557 if (c != '\n' && c != '\r')
559 c = getc (infile);
560 continue;
562 c = getc (infile);
563 if (c == ' ')
565 while (c == ' ')
566 c = getc (infile);
567 if (c != 'D')
568 continue;
569 c = getc (infile);
570 if (c != 'E')
571 continue;
572 c = getc (infile);
573 if (c != 'F')
574 continue;
575 c = getc (infile);
576 if (c != 'V')
577 continue;
578 c = getc (infile);
579 if (c != 'A')
580 continue;
581 c = getc (infile);
582 if (c != 'R')
583 continue;
584 c = getc (infile);
585 if (c != '_')
586 continue;
588 defvarflag = 1;
589 defunflag = 0;
591 c = getc (infile);
592 defvarperbufferflag = (c == 'P');
594 c = getc (infile);
596 else if (c == 'D')
598 c = getc (infile);
599 if (c != 'E')
600 continue;
601 c = getc (infile);
602 if (c != 'F')
603 continue;
604 c = getc (infile);
605 defunflag = c == 'U';
606 defvarflag = 0;
607 defvarperbufferflag = 0;
609 else continue;
611 while (c != '(')
613 if (c < 0)
614 goto eof;
615 c = getc (infile);
618 /* Lisp variable or function name. */
619 c = getc (infile);
620 if (c != '"')
621 continue;
622 c = read_c_string_or_comment (infile, -1, 0, 0);
624 /* DEFVAR_LISP ("name", addr, "doc")
625 DEFVAR_LISP ("name", addr /\* doc *\/)
626 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
628 if (defunflag)
629 commas = 5;
630 else if (defvarperbufferflag)
631 commas = 2;
632 else if (defvarflag)
633 commas = 1;
634 else /* For DEFSIMPLE and DEFPRED */
635 commas = 2;
637 while (commas)
639 if (c == ',')
641 commas--;
643 if (defunflag && (commas == 1 || commas == 2))
646 c = getc (infile);
647 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
648 if (c < 0)
649 goto eof;
650 ungetc (c, infile);
651 if (commas == 2) /* pick up minargs */
652 fscanf (infile, "%d", &minargs);
653 else /* pick up maxargs */
654 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
655 maxargs = -1;
656 else
657 fscanf (infile, "%d", &maxargs);
661 if (c == EOF)
662 goto eof;
663 c = getc (infile);
666 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
667 c = getc (infile);
669 if (c == '"')
670 c = read_c_string_or_comment (infile, 0, 0, 0);
672 while (c != EOF && c != ',' && c != '/')
673 c = getc (infile);
674 if (c == ',')
676 c = getc (infile);
677 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
678 c = getc (infile);
679 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
680 c = getc (infile);
681 if (c == ':')
683 doc_keyword = 1;
684 c = getc (infile);
685 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
686 c = getc (infile);
690 if (c == '"'
691 || (c == '/'
692 && (c = getc (infile),
693 ungetc (c, infile),
694 c == '*')))
696 int comment = c != '"';
697 int saw_usage;
699 putc (037, outfile);
700 putc (defvarflag ? 'V' : 'F', outfile);
701 fprintf (outfile, "%s\n", buf);
703 if (comment)
704 getc (infile); /* Skip past `*' */
705 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
707 /* If this is a defun, find the arguments and print them. If
708 this function takes MANY or UNEVALLED args, then the C source
709 won't give the names of the arguments, so we shouldn't bother
710 trying to find them.
712 Various doc-string styles:
713 0: DEFUN (..., "DOC") (args) [!comment]
714 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
715 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
717 if (defunflag && maxargs != -1 && !saw_usage)
719 char argbuf[1024], *p = argbuf;
721 if (!comment || doc_keyword)
722 while (c != ')')
724 if (c < 0)
725 goto eof;
726 c = getc (infile);
729 /* Skip into arguments. */
730 while (c != '(')
732 if (c < 0)
733 goto eof;
734 c = getc (infile);
736 /* Copy arguments into ARGBUF. */
737 *p++ = c;
739 *p++ = c = getc (infile);
740 while (c != ')');
741 *p = '\0';
742 /* Output them. */
743 fprintf (outfile, "\n\n");
744 write_c_args (outfile, buf, argbuf, minargs, maxargs);
746 else if (defunflag && maxargs == -1 && !saw_usage)
747 /* The DOC should provide the usage form. */
748 fprintf (stderr, "Missing `usage' for function `%s'.\n", buf);
751 eof:
752 fclose (infile);
753 return 0;
756 /* Read a file of Lisp code, compiled or interpreted.
757 Looks for
758 (defun NAME ARGS DOCSTRING ...)
759 (defmacro NAME ARGS DOCSTRING ...)
760 (defsubst NAME ARGS DOCSTRING ...)
761 (autoload (quote NAME) FILE DOCSTRING ...)
762 (defvar NAME VALUE DOCSTRING)
763 (defconst NAME VALUE DOCSTRING)
764 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
765 (fset (quote NAME) #[... DOCSTRING ...])
766 (defalias (quote NAME) #[... DOCSTRING ...])
767 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
768 starting in column zero.
769 (quote NAME) may appear as 'NAME as well.
771 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
772 When we find that, we save it for the following defining-form,
773 and we use that instead of reading a doc string within that defining-form.
775 For defvar, defconst, and fset we skip to the docstring with a kludgy
776 formatting convention: all docstrings must appear on the same line as the
777 initial open-paren (the one in column zero) and must contain a backslash
778 and a newline immediately after the initial double-quote. No newlines
779 must appear between the beginning of the form and the first double-quote.
780 For defun, defmacro, and autoload, we know how to skip over the
781 arglist, but the doc string must still have a backslash and newline
782 immediately after the double quote.
783 The only source files that must follow this convention are preloaded
784 uncompiled ones like loaddefs.el and bindings.el; aside
785 from that, it is always the .elc file that we look at, and they are no
786 problem because byte-compiler output follows this convention.
787 The NAME and DOCSTRING are output.
788 NAME is preceded by `F' for a function or `V' for a variable.
789 An entry is output only if DOCSTRING has \ newline just after the opening "
792 void
793 skip_white (FILE *infile)
795 char c = ' ';
796 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
797 c = getc (infile);
798 ungetc (c, infile);
801 void
802 read_lisp_symbol (FILE *infile, char *buffer)
804 char c;
805 char *fillp = buffer;
807 skip_white (infile);
808 while (1)
810 c = getc (infile);
811 if (c == '\\')
812 *(++fillp) = getc (infile);
813 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
815 ungetc (c, infile);
816 *fillp = 0;
817 break;
819 else
820 *fillp++ = c;
823 if (! buffer[0])
824 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
826 skip_white (infile);
830 scan_lisp_file (char *filename, char *mode)
832 FILE *infile;
833 register int c;
834 char *saved_string = 0;
836 infile = fopen (filename, mode);
837 if (infile == NULL)
839 perror (filename);
840 return 0; /* No error */
843 c = '\n';
844 while (!feof (infile))
846 char buffer[BUFSIZ];
847 char type;
849 /* If not at end of line, skip till we get to one. */
850 if (c != '\n' && c != '\r')
852 c = getc (infile);
853 continue;
855 /* Skip the line break. */
856 while (c == '\n' || c == '\r')
857 c = getc (infile);
858 /* Detect a dynamic doc string and save it for the next expression. */
859 if (c == '#')
861 c = getc (infile);
862 if (c == '@')
864 int length = 0;
865 int i;
867 /* Read the length. */
868 while ((c = getc (infile),
869 c >= '0' && c <= '9'))
871 length *= 10;
872 length += c - '0';
875 /* The next character is a space that is counted in the length
876 but not part of the doc string.
877 We already read it, so just ignore it. */
878 length--;
880 /* Read in the contents. */
881 free (saved_string);
882 saved_string = (char *) xmalloc (length);
883 for (i = 0; i < length; i++)
884 saved_string[i] = getc (infile);
885 /* The last character is a ^_.
886 That is needed in the .elc file
887 but it is redundant in DOC. So get rid of it here. */
888 saved_string[length - 1] = 0;
889 /* Skip the line break. */
890 while (c == '\n' && c == '\r')
891 c = getc (infile);
892 /* Skip the following line. */
893 while (c != '\n' && c != '\r')
894 c = getc (infile);
896 continue;
899 if (c != '(')
900 continue;
902 read_lisp_symbol (infile, buffer);
904 if (! strcmp (buffer, "defun")
905 || ! strcmp (buffer, "defmacro")
906 || ! strcmp (buffer, "defsubst"))
908 type = 'F';
909 read_lisp_symbol (infile, buffer);
911 /* Skip the arguments: either "nil" or a list in parens */
913 c = getc (infile);
914 if (c == 'n') /* nil */
916 if ((c = getc (infile)) != 'i'
917 || (c = getc (infile)) != 'l')
919 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
920 buffer, filename);
921 continue;
924 else if (c != '(')
926 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
927 buffer, filename);
928 continue;
930 else
931 while (c != ')')
932 c = getc (infile);
933 skip_white (infile);
935 /* If the next three characters aren't `dquote bslash newline'
936 then we're not reading a docstring.
938 if ((c = getc (infile)) != '"'
939 || (c = getc (infile)) != '\\'
940 || ((c = getc (infile)) != '\n' && c != '\r'))
942 #ifdef DEBUG
943 fprintf (stderr, "## non-docstring in %s (%s)\n",
944 buffer, filename);
945 #endif
946 continue;
950 else if (! strcmp (buffer, "defvar")
951 || ! strcmp (buffer, "defconst"))
953 char c1 = 0, c2 = 0;
954 type = 'V';
955 read_lisp_symbol (infile, buffer);
957 if (saved_string == 0)
960 /* Skip until the end of line; remember two previous chars. */
961 while (c != '\n' && c != '\r' && c >= 0)
963 c2 = c1;
964 c1 = c;
965 c = getc (infile);
968 /* If two previous characters were " and \,
969 this is a doc string. Otherwise, there is none. */
970 if (c2 != '"' || c1 != '\\')
972 #ifdef DEBUG
973 fprintf (stderr, "## non-docstring in %s (%s)\n",
974 buffer, filename);
975 #endif
976 continue;
981 else if (! strcmp (buffer, "custom-declare-variable")
982 || ! strcmp (buffer, "defvaralias")
985 char c1 = 0, c2 = 0;
986 type = 'V';
988 c = getc (infile);
989 if (c == '\'')
990 read_lisp_symbol (infile, buffer);
991 else
993 if (c != '(')
995 fprintf (stderr,
996 "## unparsable name in custom-declare-variable in %s\n",
997 filename);
998 continue;
1000 read_lisp_symbol (infile, buffer);
1001 if (strcmp (buffer, "quote"))
1003 fprintf (stderr,
1004 "## unparsable name in custom-declare-variable in %s\n",
1005 filename);
1006 continue;
1008 read_lisp_symbol (infile, buffer);
1009 c = getc (infile);
1010 if (c != ')')
1012 fprintf (stderr,
1013 "## unparsable quoted name in custom-declare-variable in %s\n",
1014 filename);
1015 continue;
1019 if (saved_string == 0)
1021 /* Skip to end of line; remember the two previous chars. */
1022 while (c != '\n' && c != '\r' && c >= 0)
1024 c2 = c1;
1025 c1 = c;
1026 c = getc (infile);
1029 /* If two previous characters were " and \,
1030 this is a doc string. Otherwise, there is none. */
1031 if (c2 != '"' || c1 != '\\')
1033 #ifdef DEBUG
1034 fprintf (stderr, "## non-docstring in %s (%s)\n",
1035 buffer, filename);
1036 #endif
1037 continue;
1042 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1044 char c1 = 0, c2 = 0;
1045 type = 'F';
1047 c = getc (infile);
1048 if (c == '\'')
1049 read_lisp_symbol (infile, buffer);
1050 else
1052 if (c != '(')
1054 fprintf (stderr, "## unparsable name in fset in %s\n",
1055 filename);
1056 continue;
1058 read_lisp_symbol (infile, buffer);
1059 if (strcmp (buffer, "quote"))
1061 fprintf (stderr, "## unparsable name in fset in %s\n",
1062 filename);
1063 continue;
1065 read_lisp_symbol (infile, buffer);
1066 c = getc (infile);
1067 if (c != ')')
1069 fprintf (stderr,
1070 "## unparsable quoted name in fset in %s\n",
1071 filename);
1072 continue;
1076 if (saved_string == 0)
1078 /* Skip to end of line; remember the two previous chars. */
1079 while (c != '\n' && c != '\r' && c >= 0)
1081 c2 = c1;
1082 c1 = c;
1083 c = getc (infile);
1086 /* If two previous characters were " and \,
1087 this is a doc string. Otherwise, there is none. */
1088 if (c2 != '"' || c1 != '\\')
1090 #ifdef DEBUG
1091 fprintf (stderr, "## non-docstring in %s (%s)\n",
1092 buffer, filename);
1093 #endif
1094 continue;
1099 else if (! strcmp (buffer, "autoload"))
1101 type = 'F';
1102 c = getc (infile);
1103 if (c == '\'')
1104 read_lisp_symbol (infile, buffer);
1105 else
1107 if (c != '(')
1109 fprintf (stderr, "## unparsable name in autoload in %s\n",
1110 filename);
1111 continue;
1113 read_lisp_symbol (infile, buffer);
1114 if (strcmp (buffer, "quote"))
1116 fprintf (stderr, "## unparsable name in autoload in %s\n",
1117 filename);
1118 continue;
1120 read_lisp_symbol (infile, buffer);
1121 c = getc (infile);
1122 if (c != ')')
1124 fprintf (stderr,
1125 "## unparsable quoted name in autoload in %s\n",
1126 filename);
1127 continue;
1130 skip_white (infile);
1131 if ((c = getc (infile)) != '\"')
1133 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1134 buffer, filename);
1135 continue;
1137 read_c_string_or_comment (infile, 0, 0, 0);
1138 skip_white (infile);
1140 if (saved_string == 0)
1142 /* If the next three characters aren't `dquote bslash newline'
1143 then we're not reading a docstring. */
1144 if ((c = getc (infile)) != '"'
1145 || (c = getc (infile)) != '\\'
1146 || ((c = getc (infile)) != '\n' && c != '\r'))
1148 #ifdef DEBUG
1149 fprintf (stderr, "## non-docstring in %s (%s)\n",
1150 buffer, filename);
1151 #endif
1152 continue;
1157 #ifdef DEBUG
1158 else if (! strcmp (buffer, "if")
1159 || ! strcmp (buffer, "byte-code"))
1161 #endif
1163 else
1165 #ifdef DEBUG
1166 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1167 buffer, filename);
1168 #endif
1169 continue;
1172 /* At this point, we should either use the previous
1173 dynamic doc string in saved_string
1174 or gobble a doc string from the input file.
1176 In the latter case, the opening quote (and leading
1177 backslash-newline) have already been read. */
1179 putc (037, outfile);
1180 putc (type, outfile);
1181 fprintf (outfile, "%s\n", buffer);
1182 if (saved_string)
1184 fputs (saved_string, outfile);
1185 /* Don't use one dynamic doc string twice. */
1186 free (saved_string);
1187 saved_string = 0;
1189 else
1190 read_c_string_or_comment (infile, 1, 0, 0);
1192 fclose (infile);
1193 return 0;
1196 /* arch-tag: f7203aaf-991a-4238-acb5-601db56f2894
1197 (do not change this comment) */
1199 /* make-docfile.c ends here */