Fix previous change.
[emacs.git] / lib-src / make-docfile.c
blobe502061b759db0ebf185d15c0f3126f490c4d736
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985, 86, 92, 93, 94, 97, 1999, 2000, 01, 2004
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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 #define NO_SHORTNAMES /* Tell config not to load remap.h */
38 #include <config.h>
40 /* defined to be emacs_main, sys_fopen, etc. in config.h */
41 #undef main
42 #undef fopen
43 #undef chdir
45 #include <stdio.h>
46 #ifdef MSDOS
47 #include <fcntl.h>
48 #endif /* MSDOS */
49 #ifdef WINDOWSNT
50 #include <stdlib.h>
51 #include <fcntl.h>
52 #include <direct.h>
53 #endif /* WINDOWSNT */
55 #ifdef DOS_NT
56 #define READ_TEXT "rt"
57 #define READ_BINARY "rb"
58 #else /* not DOS_NT */
59 #define READ_TEXT "r"
60 #define READ_BINARY "r"
61 #endif /* not DOS_NT */
63 #ifndef IS_DIRECTORY_SEP
64 #define IS_DIRECTORY_SEP(_c_) ((_c_) == '/')
65 #endif
67 int scan_file ();
68 int scan_lisp_file ();
69 int scan_c_file ();
71 #ifdef MSDOS
72 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
73 file where that function is defined. */
74 #undef chdir
75 #endif
77 #ifdef HAVE_UNISTD_H
78 #include <unistd.h>
79 #endif
81 /* Stdio stream for output to the DOC file. */
82 FILE *outfile;
84 /* Name this program was invoked with. */
85 char *progname;
87 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
89 /* VARARGS1 */
90 void
91 error (s1, s2)
92 char *s1, *s2;
94 fprintf (stderr, "%s: ", progname);
95 fprintf (stderr, s1, s2);
96 fprintf (stderr, "\n");
99 /* Print error message and exit. */
101 /* VARARGS1 */
102 void
103 fatal (s1, s2)
104 char *s1, *s2;
106 error (s1, s2);
107 exit (EXIT_FAILURE);
110 /* Like malloc but get fatal error if memory is exhausted. */
112 void *
113 xmalloc (size)
114 unsigned int size;
116 void *result = (void *) malloc (size);
117 if (result == NULL)
118 fatal ("virtual memory exhausted", 0);
119 return result;
123 main (argc, argv)
124 int argc;
125 char **argv;
127 int i;
128 int err_count = 0;
129 int first_infile;
131 progname = argv[0];
133 outfile = stdout;
135 /* Don't put CRs in the DOC file. */
136 #ifdef MSDOS
137 _fmode = O_BINARY;
138 #if 0 /* Suspicion is that this causes hanging.
139 So instead we require people to use -o on MSDOS. */
140 (stdout)->_flag &= ~_IOTEXT;
141 _setmode (fileno (stdout), O_BINARY);
142 #endif
143 outfile = 0;
144 #endif /* MSDOS */
145 #ifdef WINDOWSNT
146 _fmode = O_BINARY;
147 _setmode (fileno (stdout), O_BINARY);
148 #endif /* WINDOWSNT */
150 /* If first two args are -o FILE, output to FILE. */
151 i = 1;
152 if (argc > i + 1 && !strcmp (argv[i], "-o"))
154 outfile = fopen (argv[i + 1], "w");
155 i += 2;
157 if (argc > i + 1 && !strcmp (argv[i], "-a"))
159 outfile = fopen (argv[i + 1], "a");
160 i += 2;
162 if (argc > i + 1 && !strcmp (argv[i], "-d"))
164 chdir (argv[i + 1]);
165 i += 2;
168 if (outfile == 0)
169 fatal ("No output file specified", "");
171 first_infile = i;
172 for (; i < argc; i++)
174 int j;
175 /* Don't process one file twice. */
176 for (j = first_infile; j < i; j++)
177 if (! strcmp (argv[i], argv[j]))
178 break;
179 if (j == i)
180 err_count += scan_file (argv[i]);
182 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
185 /* Add a source file name boundary marker in the output file. */
186 void
187 put_filename (filename)
188 char *filename;
190 char *tmp;
192 for (tmp = filename; *tmp; tmp++)
194 if (IS_DIRECTORY_SEP(*tmp))
195 filename = tmp + 1;
198 putc (037, outfile);
199 putc ('S', outfile);
200 fprintf (outfile, "%s\n", filename);
203 /* Read file FILENAME and output its doc strings to outfile. */
204 /* Return 1 if file is not found, 0 if it is found. */
207 scan_file (filename)
208 char *filename;
210 int len = strlen (filename);
212 put_filename (filename);
213 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
214 return scan_lisp_file (filename, READ_BINARY);
215 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
216 return scan_lisp_file (filename, READ_TEXT);
217 else
218 return scan_c_file (filename, READ_TEXT);
221 char buf[128];
223 /* Some state during the execution of `read_c_string_or_comment'. */
224 struct rcsoc_state
226 /* A count of spaces and newlines that have been read, but not output. */
227 unsigned pending_spaces, pending_newlines;
229 /* Where we're reading from. */
230 FILE *in_file;
232 /* If non-zero, a buffer into which to copy characters. */
233 char *buf_ptr;
234 /* If non-zero, a file into which to copy characters. */
235 FILE *out_file;
237 /* A keyword we look for at the beginning of lines. If found, it is
238 not copied, and SAW_KEYWORD is set to true. */
239 char *keyword;
240 /* The current point we've reached in an occurance of KEYWORD in
241 the input stream. */
242 char *cur_keyword_ptr;
243 /* Set to true if we saw an occurance of KEYWORD. */
244 int saw_keyword;
247 /* Output CH to the file or buffer in STATE. Any pending newlines or
248 spaces are output first. */
250 static INLINE void
251 put_char (ch, state)
252 int ch;
253 struct rcsoc_state *state;
255 int out_ch;
258 if (state->pending_newlines > 0)
260 state->pending_newlines--;
261 out_ch = '\n';
263 else if (state->pending_spaces > 0)
265 state->pending_spaces--;
266 out_ch = ' ';
268 else
269 out_ch = ch;
271 if (state->out_file)
272 putc (out_ch, state->out_file);
273 if (state->buf_ptr)
274 *state->buf_ptr++ = out_ch;
276 while (out_ch != ch);
279 /* If in the middle of scanning a keyword, continue scanning with
280 character CH, otherwise output CH to the file or buffer in STATE.
281 Any pending newlines or spaces are output first, as well as any
282 previously scanned characters that were thought to be part of a
283 keyword, but were in fact not. */
285 static void
286 scan_keyword_or_put_char (ch, state)
287 int ch;
288 struct rcsoc_state *state;
290 if (state->keyword
291 && *state->cur_keyword_ptr == ch
292 && (state->cur_keyword_ptr > state->keyword
293 || state->pending_newlines > 0))
294 /* We might be looking at STATE->keyword at some point.
295 Keep looking until we know for sure. */
297 if (*++state->cur_keyword_ptr == '\0')
298 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
300 state->saw_keyword = 1;
302 /* Reset the scanning pointer. */
303 state->cur_keyword_ptr = state->keyword;
305 /* Canonicalize whitespace preceding a usage string. */
306 state->pending_newlines = 2;
307 state->pending_spaces = 0;
309 /* Skip any whitespace between the keyword and the
310 usage string. */
312 ch = getc (state->in_file);
313 while (ch == ' ' || ch == '\n');
315 /* Output the open-paren we just read. */
316 put_char (ch, state);
318 /* Skip the function name and replace it with `fn'. */
320 ch = getc (state->in_file);
321 while (ch != ' ' && ch != ')');
322 put_char ('f', state);
323 put_char ('n', state);
325 /* Put back the last character. */
326 ungetc (ch, state->in_file);
329 else
331 if (state->keyword && state->cur_keyword_ptr > state->keyword)
332 /* We scanned the beginning of a potential usage
333 keyword, but it was a false alarm. Output the
334 part we scanned. */
336 char *p;
338 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
339 put_char (*p, state);
341 state->cur_keyword_ptr = state->keyword;
344 put_char (ch, state);
349 /* Skip a C string or C-style comment from INFILE, and return the
350 character that follows. COMMENT non-zero means skip a comment. If
351 PRINTFLAG is positive, output string contents to outfile. If it is
352 negative, store contents in buf. Convert escape sequences \n and
353 \t to newline and tab; discard \ followed by newline.
354 If SAW_USAGE is non-zero, then any occurances of the string `usage:'
355 at the beginning of a line will be removed, and *SAW_USAGE set to
356 true if any were encountered. */
359 read_c_string_or_comment (infile, printflag, comment, saw_usage)
360 FILE *infile;
361 int printflag;
362 int *saw_usage;
363 int comment;
365 register int c;
366 struct rcsoc_state state;
368 state.in_file = infile;
369 state.buf_ptr = (printflag < 0 ? buf : 0);
370 state.out_file = (printflag > 0 ? outfile : 0);
371 state.pending_spaces = 0;
372 state.pending_newlines = 0;
373 state.keyword = (saw_usage ? "usage:" : 0);
374 state.cur_keyword_ptr = state.keyword;
375 state.saw_keyword = 0;
377 c = getc (infile);
378 if (comment)
379 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
380 c = getc (infile);
382 while (c != EOF)
384 while (c != EOF && (comment ? c != '*' : c != '"'))
386 if (c == '\\')
388 c = getc (infile);
389 if (c == '\n' || c == '\r')
391 c = getc (infile);
392 continue;
394 if (c == 'n')
395 c = '\n';
396 if (c == 't')
397 c = '\t';
400 if (c == ' ')
401 state.pending_spaces++;
402 else if (c == '\n')
404 state.pending_newlines++;
405 state.pending_spaces = 0;
407 else
408 scan_keyword_or_put_char (c, &state);
410 c = getc (infile);
413 if (c != EOF)
414 c = getc (infile);
416 if (comment)
418 if (c == '/')
420 c = getc (infile);
421 break;
424 scan_keyword_or_put_char ('*', &state);
426 else
428 if (c != '"')
429 break;
431 /* If we had a "", concatenate the two strings. */
432 c = getc (infile);
436 if (printflag < 0)
437 *state.buf_ptr = 0;
439 if (saw_usage)
440 *saw_usage = state.saw_keyword;
442 return c;
447 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
448 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
450 void
451 write_c_args (out, func, buf, minargs, maxargs)
452 FILE *out;
453 char *func, *buf;
454 int minargs, maxargs;
456 register char *p;
457 int in_ident = 0;
458 int just_spaced = 0;
459 int need_space = 1;
461 fprintf (out, "(fn");
463 if (*buf == '(')
464 ++buf;
466 for (p = buf; *p; p++)
468 char c = *p;
469 int ident_start = 0;
471 /* Notice when we start printing a new identifier. */
472 if ((('A' <= c && c <= 'Z')
473 || ('a' <= c && c <= 'z')
474 || ('0' <= c && c <= '9')
475 || c == '_')
476 != in_ident)
478 if (!in_ident)
480 in_ident = 1;
481 ident_start = 1;
483 if (need_space)
484 putc (' ', out);
486 if (minargs == 0 && maxargs > 0)
487 fprintf (out, "&optional ");
488 just_spaced = 1;
490 minargs--;
491 maxargs--;
493 else
494 in_ident = 0;
497 /* Print the C argument list as it would appear in lisp:
498 print underscores as hyphens, and print commas and newlines
499 as spaces. Collapse adjacent spaces into one. */
500 if (c == '_')
501 c = '-';
502 else if (c == ',' || c == '\n')
503 c = ' ';
505 /* In C code, `default' is a reserved word, so we spell it
506 `defalt'; unmangle that here. */
507 if (ident_start
508 && strncmp (p, "defalt", 6) == 0
509 && ! (('A' <= p[6] && p[6] <= 'Z')
510 || ('a' <= p[6] && p[6] <= 'z')
511 || ('0' <= p[6] && p[6] <= '9')
512 || p[6] == '_'))
514 fprintf (out, "DEFAULT");
515 p += 5;
516 in_ident = 0;
517 just_spaced = 0;
519 else if (c != ' ' || !just_spaced)
521 if (c >= 'a' && c <= 'z')
522 /* Upcase the letter. */
523 c += 'A' - 'a';
524 putc (c, out);
527 just_spaced = c == ' ';
528 need_space = 0;
532 /* Read through a c file. If a .o file is named,
533 the corresponding .c file is read instead.
534 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
535 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
538 scan_c_file (filename, mode)
539 char *filename, *mode;
541 FILE *infile;
542 register int c;
543 register int commas;
544 register int defunflag;
545 register int defvarperbufferflag;
546 register int defvarflag;
547 int minargs, maxargs;
548 int extension = filename[strlen (filename) - 1];
550 if (extension == 'o')
551 filename[strlen (filename) - 1] = 'c';
553 infile = fopen (filename, mode);
555 /* No error if non-ex input file */
556 if (infile == NULL)
558 perror (filename);
559 return 0;
562 /* Reset extension to be able to detect duplicate files. */
563 filename[strlen (filename) - 1] = extension;
565 c = '\n';
566 while (!feof (infile))
568 int doc_keyword = 0;
570 if (c != '\n' && c != '\r')
572 c = getc (infile);
573 continue;
575 c = getc (infile);
576 if (c == ' ')
578 while (c == ' ')
579 c = getc (infile);
580 if (c != 'D')
581 continue;
582 c = getc (infile);
583 if (c != 'E')
584 continue;
585 c = getc (infile);
586 if (c != 'F')
587 continue;
588 c = getc (infile);
589 if (c != 'V')
590 continue;
591 c = getc (infile);
592 if (c != 'A')
593 continue;
594 c = getc (infile);
595 if (c != 'R')
596 continue;
597 c = getc (infile);
598 if (c != '_')
599 continue;
601 defvarflag = 1;
602 defunflag = 0;
604 c = getc (infile);
605 defvarperbufferflag = (c == 'P');
607 c = getc (infile);
609 else if (c == 'D')
611 c = getc (infile);
612 if (c != 'E')
613 continue;
614 c = getc (infile);
615 if (c != 'F')
616 continue;
617 c = getc (infile);
618 defunflag = c == 'U';
619 defvarflag = 0;
620 defvarperbufferflag = 0;
622 else continue;
624 while (c != '(')
626 if (c < 0)
627 goto eof;
628 c = getc (infile);
631 /* Lisp variable or function name. */
632 c = getc (infile);
633 if (c != '"')
634 continue;
635 c = read_c_string_or_comment (infile, -1, 0, 0);
637 /* DEFVAR_LISP ("name", addr, "doc")
638 DEFVAR_LISP ("name", addr /\* doc *\/)
639 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
641 if (defunflag)
642 commas = 5;
643 else if (defvarperbufferflag)
644 commas = 2;
645 else if (defvarflag)
646 commas = 1;
647 else /* For DEFSIMPLE and DEFPRED */
648 commas = 2;
650 while (commas)
652 if (c == ',')
654 commas--;
656 if (defunflag && (commas == 1 || commas == 2))
659 c = getc (infile);
660 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
661 if (c < 0)
662 goto eof;
663 ungetc (c, infile);
664 if (commas == 2) /* pick up minargs */
665 fscanf (infile, "%d", &minargs);
666 else /* pick up maxargs */
667 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
668 maxargs = -1;
669 else
670 fscanf (infile, "%d", &maxargs);
674 if (c == EOF)
675 goto eof;
676 c = getc (infile);
679 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
680 c = getc (infile);
682 if (c == '"')
683 c = read_c_string_or_comment (infile, 0, 0, 0);
685 while (c != EOF && c != ',' && c != '/')
686 c = getc (infile);
687 if (c == ',')
689 c = getc (infile);
690 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
691 c = getc (infile);
692 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
693 c = getc (infile);
694 if (c == ':')
696 doc_keyword = 1;
697 c = getc (infile);
698 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
699 c = getc (infile);
703 if (c == '"'
704 || (c == '/'
705 && (c = getc (infile),
706 ungetc (c, infile),
707 c == '*')))
709 int comment = c != '"';
710 int saw_usage;
712 putc (037, outfile);
713 putc (defvarflag ? 'V' : 'F', outfile);
714 fprintf (outfile, "%s\n", buf);
716 if (comment)
717 getc (infile); /* Skip past `*' */
718 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
720 /* If this is a defun, find the arguments and print them. If
721 this function takes MANY or UNEVALLED args, then the C source
722 won't give the names of the arguments, so we shouldn't bother
723 trying to find them.
725 Various doc-string styles:
726 0: DEFUN (..., "DOC") (args) [!comment]
727 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
728 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
730 if (defunflag && maxargs != -1 && !saw_usage)
732 char argbuf[1024], *p = argbuf;
734 if (!comment || doc_keyword)
735 while (c != ')')
737 if (c < 0)
738 goto eof;
739 c = getc (infile);
742 /* Skip into arguments. */
743 while (c != '(')
745 if (c < 0)
746 goto eof;
747 c = getc (infile);
749 /* Copy arguments into ARGBUF. */
750 *p++ = c;
752 *p++ = c = getc (infile);
753 while (c != ')');
754 *p = '\0';
755 /* Output them. */
756 fprintf (outfile, "\n\n");
757 write_c_args (outfile, buf, argbuf, minargs, maxargs);
759 else if (defunflag && maxargs == -1 && !saw_usage)
760 /* The DOC should provide the usage form. */
761 fprintf (stderr, "Missing `usage' for function `%s'.\n", buf);
764 eof:
765 fclose (infile);
766 return 0;
769 /* Read a file of Lisp code, compiled or interpreted.
770 Looks for
771 (defun NAME ARGS DOCSTRING ...)
772 (defmacro NAME ARGS DOCSTRING ...)
773 (defsubst NAME ARGS DOCSTRING ...)
774 (autoload (quote NAME) FILE DOCSTRING ...)
775 (defvar NAME VALUE DOCSTRING)
776 (defconst NAME VALUE DOCSTRING)
777 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
778 (fset (quote NAME) #[... DOCSTRING ...])
779 (defalias (quote NAME) #[... DOCSTRING ...])
780 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
781 starting in column zero.
782 (quote NAME) may appear as 'NAME as well.
784 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
785 When we find that, we save it for the following defining-form,
786 and we use that instead of reading a doc string within that defining-form.
788 For defvar, defconst, and fset we skip to the docstring with a kludgy
789 formatting convention: all docstrings must appear on the same line as the
790 initial open-paren (the one in column zero) and must contain a backslash
791 and a newline immediately after the initial double-quote. No newlines
792 must appear between the beginning of the form and the first double-quote.
793 For defun, defmacro, and autoload, we know how to skip over the
794 arglist, but the doc string must still have a backslash and newline
795 immediately after the double quote.
796 The only source files that must follow this convention are preloaded
797 uncompiled ones like loaddefs.el and bindings.el; aside
798 from that, it is always the .elc file that we look at, and they are no
799 problem because byte-compiler output follows this convention.
800 The NAME and DOCSTRING are output.
801 NAME is preceded by `F' for a function or `V' for a variable.
802 An entry is output only if DOCSTRING has \ newline just after the opening "
805 void
806 skip_white (infile)
807 FILE *infile;
809 char c = ' ';
810 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
811 c = getc (infile);
812 ungetc (c, infile);
815 void
816 read_lisp_symbol (infile, buffer)
817 FILE *infile;
818 char *buffer;
820 char c;
821 char *fillp = buffer;
823 skip_white (infile);
824 while (1)
826 c = getc (infile);
827 if (c == '\\')
828 *(++fillp) = getc (infile);
829 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
831 ungetc (c, infile);
832 *fillp = 0;
833 break;
835 else
836 *fillp++ = c;
839 if (! buffer[0])
840 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
842 skip_white (infile);
846 scan_lisp_file (filename, mode)
847 char *filename, *mode;
849 FILE *infile;
850 register int c;
851 char *saved_string = 0;
853 infile = fopen (filename, mode);
854 if (infile == NULL)
856 perror (filename);
857 return 0; /* No error */
860 c = '\n';
861 while (!feof (infile))
863 char buffer[BUFSIZ];
864 char type;
866 /* If not at end of line, skip till we get to one. */
867 if (c != '\n' && c != '\r')
869 c = getc (infile);
870 continue;
872 /* Skip the line break. */
873 while (c == '\n' || c == '\r')
874 c = getc (infile);
875 /* Detect a dynamic doc string and save it for the next expression. */
876 if (c == '#')
878 c = getc (infile);
879 if (c == '@')
881 int length = 0;
882 int i;
884 /* Read the length. */
885 while ((c = getc (infile),
886 c >= '0' && c <= '9'))
888 length *= 10;
889 length += c - '0';
892 /* The next character is a space that is counted in the length
893 but not part of the doc string.
894 We already read it, so just ignore it. */
895 length--;
897 /* Read in the contents. */
898 if (saved_string != 0)
899 free (saved_string);
900 saved_string = (char *) malloc (length);
901 for (i = 0; i < length; i++)
902 saved_string[i] = getc (infile);
903 /* The last character is a ^_.
904 That is needed in the .elc file
905 but it is redundant in DOC. So get rid of it here. */
906 saved_string[length - 1] = 0;
907 /* Skip the line break. */
908 while (c == '\n' && c == '\r')
909 c = getc (infile);
910 /* Skip the following line. */
911 while (c != '\n' && c != '\r')
912 c = getc (infile);
914 continue;
917 if (c != '(')
918 continue;
920 read_lisp_symbol (infile, buffer);
922 if (! strcmp (buffer, "defun")
923 || ! strcmp (buffer, "defmacro")
924 || ! strcmp (buffer, "defsubst"))
926 type = 'F';
927 read_lisp_symbol (infile, buffer);
929 /* Skip the arguments: either "nil" or a list in parens */
931 c = getc (infile);
932 if (c == 'n') /* nil */
934 if ((c = getc (infile)) != 'i'
935 || (c = getc (infile)) != 'l')
937 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
938 buffer, filename);
939 continue;
942 else if (c != '(')
944 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
945 buffer, filename);
946 continue;
948 else
949 while (c != ')')
950 c = getc (infile);
951 skip_white (infile);
953 /* If the next three characters aren't `dquote bslash newline'
954 then we're not reading a docstring.
956 if ((c = getc (infile)) != '"'
957 || (c = getc (infile)) != '\\'
958 || ((c = getc (infile)) != '\n' && c != '\r'))
960 #ifdef DEBUG
961 fprintf (stderr, "## non-docstring in %s (%s)\n",
962 buffer, filename);
963 #endif
964 continue;
968 else if (! strcmp (buffer, "defvar")
969 || ! strcmp (buffer, "defconst"))
971 char c1 = 0, c2 = 0;
972 type = 'V';
973 read_lisp_symbol (infile, buffer);
975 if (saved_string == 0)
978 /* Skip until the end of line; remember two previous chars. */
979 while (c != '\n' && c != '\r' && c >= 0)
981 c2 = c1;
982 c1 = c;
983 c = getc (infile);
986 /* If two previous characters were " and \,
987 this is a doc string. Otherwise, there is none. */
988 if (c2 != '"' || c1 != '\\')
990 #ifdef DEBUG
991 fprintf (stderr, "## non-docstring in %s (%s)\n",
992 buffer, filename);
993 #endif
994 continue;
999 else if (! strcmp (buffer, "custom-declare-variable"))
1001 char c1 = 0, c2 = 0;
1002 type = 'V';
1004 c = getc (infile);
1005 if (c == '\'')
1006 read_lisp_symbol (infile, buffer);
1007 else
1009 if (c != '(')
1011 fprintf (stderr,
1012 "## unparsable name in custom-declare-variable in %s\n",
1013 filename);
1014 continue;
1016 read_lisp_symbol (infile, buffer);
1017 if (strcmp (buffer, "quote"))
1019 fprintf (stderr,
1020 "## unparsable name in custom-declare-variable in %s\n",
1021 filename);
1022 continue;
1024 read_lisp_symbol (infile, buffer);
1025 c = getc (infile);
1026 if (c != ')')
1028 fprintf (stderr,
1029 "## unparsable quoted name in custom-declare-variable in %s\n",
1030 filename);
1031 continue;
1035 if (saved_string == 0)
1037 /* Skip to end of line; remember the two previous chars. */
1038 while (c != '\n' && c != '\r' && c >= 0)
1040 c2 = c1;
1041 c1 = c;
1042 c = getc (infile);
1045 /* If two previous characters were " and \,
1046 this is a doc string. Otherwise, there is none. */
1047 if (c2 != '"' || c1 != '\\')
1049 #ifdef DEBUG
1050 fprintf (stderr, "## non-docstring in %s (%s)\n",
1051 buffer, filename);
1052 #endif
1053 continue;
1058 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1060 char c1 = 0, c2 = 0;
1061 type = 'F';
1063 c = getc (infile);
1064 if (c == '\'')
1065 read_lisp_symbol (infile, buffer);
1066 else
1068 if (c != '(')
1070 fprintf (stderr, "## unparsable name in fset in %s\n",
1071 filename);
1072 continue;
1074 read_lisp_symbol (infile, buffer);
1075 if (strcmp (buffer, "quote"))
1077 fprintf (stderr, "## unparsable name in fset in %s\n",
1078 filename);
1079 continue;
1081 read_lisp_symbol (infile, buffer);
1082 c = getc (infile);
1083 if (c != ')')
1085 fprintf (stderr,
1086 "## unparsable quoted name in fset in %s\n",
1087 filename);
1088 continue;
1092 if (saved_string == 0)
1094 /* Skip to end of line; remember the two previous chars. */
1095 while (c != '\n' && c != '\r' && c >= 0)
1097 c2 = c1;
1098 c1 = c;
1099 c = getc (infile);
1102 /* If two previous characters were " and \,
1103 this is a doc string. Otherwise, there is none. */
1104 if (c2 != '"' || c1 != '\\')
1106 #ifdef DEBUG
1107 fprintf (stderr, "## non-docstring in %s (%s)\n",
1108 buffer, filename);
1109 #endif
1110 continue;
1115 else if (! strcmp (buffer, "autoload"))
1117 type = 'F';
1118 c = getc (infile);
1119 if (c == '\'')
1120 read_lisp_symbol (infile, buffer);
1121 else
1123 if (c != '(')
1125 fprintf (stderr, "## unparsable name in autoload in %s\n",
1126 filename);
1127 continue;
1129 read_lisp_symbol (infile, buffer);
1130 if (strcmp (buffer, "quote"))
1132 fprintf (stderr, "## unparsable name in autoload in %s\n",
1133 filename);
1134 continue;
1136 read_lisp_symbol (infile, buffer);
1137 c = getc (infile);
1138 if (c != ')')
1140 fprintf (stderr,
1141 "## unparsable quoted name in autoload in %s\n",
1142 filename);
1143 continue;
1146 skip_white (infile);
1147 if ((c = getc (infile)) != '\"')
1149 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1150 buffer, filename);
1151 continue;
1153 read_c_string_or_comment (infile, 0, 0, 0);
1154 skip_white (infile);
1156 if (saved_string == 0)
1158 /* If the next three characters aren't `dquote bslash newline'
1159 then we're not reading a docstring. */
1160 if ((c = getc (infile)) != '"'
1161 || (c = getc (infile)) != '\\'
1162 || ((c = getc (infile)) != '\n' && c != '\r'))
1164 #ifdef DEBUG
1165 fprintf (stderr, "## non-docstring in %s (%s)\n",
1166 buffer, filename);
1167 #endif
1168 continue;
1173 #ifdef DEBUG
1174 else if (! strcmp (buffer, "if")
1175 || ! strcmp (buffer, "byte-code"))
1177 #endif
1179 else
1181 #ifdef DEBUG
1182 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
1183 buffer, filename);
1184 #endif
1185 continue;
1188 /* At this point, we should either use the previous
1189 dynamic doc string in saved_string
1190 or gobble a doc string from the input file.
1192 In the latter case, the opening quote (and leading
1193 backslash-newline) have already been read. */
1195 putc (037, outfile);
1196 putc (type, outfile);
1197 fprintf (outfile, "%s\n", buffer);
1198 if (saved_string)
1200 fputs (saved_string, outfile);
1201 /* Don't use one dynamic doc string twice. */
1202 free (saved_string);
1203 saved_string = 0;
1205 else
1206 read_c_string_or_comment (infile, 1, 0, 0);
1208 fclose (infile);
1209 return 0;
1212 /* arch-tag: f7203aaf-991a-4238-acb5-601db56f2894
1213 (do not change this comment) */
1215 /* make-docfile.c ends here */