(x_connection_closed): Consolidate identical tests.
[emacs.git] / lib-src / make-docfile.c
blob6e22eb857e363efbafbb9c6c0771e7f837b4c638
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 #define DIRECTORY_SEP '/'
66 #endif
68 #ifndef IS_DIRECTORY_SEP
69 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
70 #endif
72 int scan_file ();
73 int scan_lisp_file ();
74 int scan_c_file ();
76 #ifdef MSDOS
77 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
78 file where that function is defined. */
79 #undef chdir
80 #endif
82 #ifdef HAVE_UNISTD_H
83 #include <unistd.h>
84 #endif
86 /* Stdio stream for output to the DOC file. */
87 FILE *outfile;
89 /* Name this program was invoked with. */
90 char *progname;
92 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
94 /* VARARGS1 */
95 void
96 error (s1, s2)
97 char *s1, *s2;
99 fprintf (stderr, "%s: ", progname);
100 fprintf (stderr, s1, s2);
101 fprintf (stderr, "\n");
104 /* Print error message and exit. */
106 /* VARARGS1 */
107 void
108 fatal (s1, s2)
109 char *s1, *s2;
111 error (s1, s2);
112 exit (EXIT_FAILURE);
115 /* Like malloc but get fatal error if memory is exhausted. */
117 void *
118 xmalloc (size)
119 unsigned int size;
121 void *result = (void *) malloc (size);
122 if (result == NULL)
123 fatal ("virtual memory exhausted", 0);
124 return result;
128 main (argc, argv)
129 int argc;
130 char **argv;
132 int i;
133 int err_count = 0;
134 int first_infile;
136 progname = argv[0];
138 outfile = stdout;
140 /* Don't put CRs in the DOC file. */
141 #ifdef MSDOS
142 _fmode = O_BINARY;
143 #if 0 /* Suspicion is that this causes hanging.
144 So instead we require people to use -o on MSDOS. */
145 (stdout)->_flag &= ~_IOTEXT;
146 _setmode (fileno (stdout), O_BINARY);
147 #endif
148 outfile = 0;
149 #endif /* MSDOS */
150 #ifdef WINDOWSNT
151 _fmode = O_BINARY;
152 _setmode (fileno (stdout), O_BINARY);
153 #endif /* WINDOWSNT */
155 /* If first two args are -o FILE, output to FILE. */
156 i = 1;
157 if (argc > i + 1 && !strcmp (argv[i], "-o"))
159 outfile = fopen (argv[i + 1], "w");
160 i += 2;
162 if (argc > i + 1 && !strcmp (argv[i], "-a"))
164 outfile = fopen (argv[i + 1], "a");
165 i += 2;
167 if (argc > i + 1 && !strcmp (argv[i], "-d"))
169 chdir (argv[i + 1]);
170 i += 2;
173 if (outfile == 0)
174 fatal ("No output file specified", "");
176 first_infile = i;
177 for (; i < argc; i++)
179 int j;
180 /* Don't process one file twice. */
181 for (j = first_infile; j < i; j++)
182 if (! strcmp (argv[i], argv[j]))
183 break;
184 if (j == i)
185 err_count += scan_file (argv[i]);
187 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
190 /* Add a source file name boundary marker in the output file. */
191 void
192 put_filename (filename)
193 char *filename;
195 char *tmp;
197 for (tmp = filename; *tmp; tmp++)
199 if (IS_DIRECTORY_SEP(*tmp))
200 filename = tmp + 1;
203 putc (037, outfile);
204 putc ('S', outfile);
205 fprintf (outfile, "%s\n", filename);
208 /* Read file FILENAME and output its doc strings to outfile. */
209 /* Return 1 if file is not found, 0 if it is found. */
212 scan_file (filename)
213 char *filename;
215 int len = strlen (filename);
217 put_filename (filename);
218 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
219 return scan_lisp_file (filename, READ_BINARY);
220 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
221 return scan_lisp_file (filename, READ_TEXT);
222 else
223 return scan_c_file (filename, READ_TEXT);
226 char buf[128];
228 /* Some state during the execution of `read_c_string_or_comment'. */
229 struct rcsoc_state
231 /* A count of spaces and newlines that have been read, but not output. */
232 unsigned pending_spaces, pending_newlines;
234 /* Where we're reading from. */
235 FILE *in_file;
237 /* If non-zero, a buffer into which to copy characters. */
238 char *buf_ptr;
239 /* If non-zero, a file into which to copy characters. */
240 FILE *out_file;
242 /* A keyword we look for at the beginning of lines. If found, it is
243 not copied, and SAW_KEYWORD is set to true. */
244 char *keyword;
245 /* The current point we've reached in an occurance of KEYWORD in
246 the input stream. */
247 char *cur_keyword_ptr;
248 /* Set to true if we saw an occurance of KEYWORD. */
249 int saw_keyword;
252 /* Output CH to the file or buffer in STATE. Any pending newlines or
253 spaces are output first. */
255 static INLINE void
256 put_char (ch, state)
257 int ch;
258 struct rcsoc_state *state;
260 int out_ch;
263 if (state->pending_newlines > 0)
265 state->pending_newlines--;
266 out_ch = '\n';
268 else if (state->pending_spaces > 0)
270 state->pending_spaces--;
271 out_ch = ' ';
273 else
274 out_ch = ch;
276 if (state->out_file)
277 putc (out_ch, state->out_file);
278 if (state->buf_ptr)
279 *state->buf_ptr++ = out_ch;
281 while (out_ch != ch);
284 /* If in the middle of scanning a keyword, continue scanning with
285 character CH, otherwise output CH to the file or buffer in STATE.
286 Any pending newlines or spaces are output first, as well as any
287 previously scanned characters that were thought to be part of a
288 keyword, but were in fact not. */
290 static void
291 scan_keyword_or_put_char (ch, state)
292 int ch;
293 struct rcsoc_state *state;
295 if (state->keyword
296 && *state->cur_keyword_ptr == ch
297 && (state->cur_keyword_ptr > state->keyword
298 || state->pending_newlines > 0))
299 /* We might be looking at STATE->keyword at some point.
300 Keep looking until we know for sure. */
302 if (*++state->cur_keyword_ptr == '\0')
303 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
305 state->saw_keyword = 1;
307 /* Reset the scanning pointer. */
308 state->cur_keyword_ptr = state->keyword;
310 /* Canonicalize whitespace preceding a usage string. */
311 state->pending_newlines = 2;
312 state->pending_spaces = 0;
314 /* Skip any whitespace between the keyword and the
315 usage string. */
317 ch = getc (state->in_file);
318 while (ch == ' ' || ch == '\n');
320 /* Output the open-paren we just read. */
321 put_char (ch, state);
323 /* Skip the function name and replace it with `fn'. */
325 ch = getc (state->in_file);
326 while (ch != ' ' && ch != ')');
327 put_char ('f', state);
328 put_char ('n', state);
330 /* Put back the last character. */
331 ungetc (ch, state->in_file);
334 else
336 if (state->keyword && state->cur_keyword_ptr > state->keyword)
337 /* We scanned the beginning of a potential usage
338 keyword, but it was a false alarm. Output the
339 part we scanned. */
341 char *p;
343 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
344 put_char (*p, state);
346 state->cur_keyword_ptr = state->keyword;
349 put_char (ch, state);
354 /* Skip a C string or C-style comment from INFILE, and return the
355 character that follows. COMMENT non-zero means skip a comment. If
356 PRINTFLAG is positive, output string contents to outfile. If it is
357 negative, store contents in buf. Convert escape sequences \n and
358 \t to newline and tab; discard \ followed by newline.
359 If SAW_USAGE is non-zero, then any occurances of the string `usage:'
360 at the beginning of a line will be removed, and *SAW_USAGE set to
361 true if any were encountered. */
364 read_c_string_or_comment (infile, printflag, comment, saw_usage)
365 FILE *infile;
366 int printflag;
367 int *saw_usage;
368 int comment;
370 register int c;
371 struct rcsoc_state state;
373 state.in_file = infile;
374 state.buf_ptr = (printflag < 0 ? buf : 0);
375 state.out_file = (printflag > 0 ? outfile : 0);
376 state.pending_spaces = 0;
377 state.pending_newlines = 0;
378 state.keyword = (saw_usage ? "usage:" : 0);
379 state.cur_keyword_ptr = state.keyword;
380 state.saw_keyword = 0;
382 c = getc (infile);
383 if (comment)
384 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
385 c = getc (infile);
387 while (c != EOF)
389 while (c != EOF && (comment ? c != '*' : c != '"'))
391 if (c == '\\')
393 c = getc (infile);
394 if (c == '\n' || c == '\r')
396 c = getc (infile);
397 continue;
399 if (c == 'n')
400 c = '\n';
401 if (c == 't')
402 c = '\t';
405 if (c == ' ')
406 state.pending_spaces++;
407 else if (c == '\n')
409 state.pending_newlines++;
410 state.pending_spaces = 0;
412 else
413 scan_keyword_or_put_char (c, &state);
415 c = getc (infile);
418 if (c != EOF)
419 c = getc (infile);
421 if (comment)
423 if (c == '/')
425 c = getc (infile);
426 break;
429 scan_keyword_or_put_char ('*', &state);
431 else
433 if (c != '"')
434 break;
436 /* If we had a "", concatenate the two strings. */
437 c = getc (infile);
441 if (printflag < 0)
442 *state.buf_ptr = 0;
444 if (saw_usage)
445 *saw_usage = state.saw_keyword;
447 return c;
452 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
453 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
455 void
456 write_c_args (out, func, buf, minargs, maxargs)
457 FILE *out;
458 char *func, *buf;
459 int minargs, maxargs;
461 register char *p;
462 int in_ident = 0;
463 int just_spaced = 0;
464 int need_space = 1;
466 fprintf (out, "(fn");
468 if (*buf == '(')
469 ++buf;
471 for (p = buf; *p; p++)
473 char c = *p;
474 int ident_start = 0;
476 /* Notice when we start printing a new identifier. */
477 if ((('A' <= c && c <= 'Z')
478 || ('a' <= c && c <= 'z')
479 || ('0' <= c && c <= '9')
480 || c == '_')
481 != in_ident)
483 if (!in_ident)
485 in_ident = 1;
486 ident_start = 1;
488 if (need_space)
489 putc (' ', out);
491 if (minargs == 0 && maxargs > 0)
492 fprintf (out, "&optional ");
493 just_spaced = 1;
495 minargs--;
496 maxargs--;
498 else
499 in_ident = 0;
502 /* Print the C argument list as it would appear in lisp:
503 print underscores as hyphens, and print commas and newlines
504 as spaces. Collapse adjacent spaces into one. */
505 if (c == '_')
506 c = '-';
507 else if (c == ',' || c == '\n')
508 c = ' ';
510 /* In C code, `default' is a reserved word, so we spell it
511 `defalt'; unmangle that here. */
512 if (ident_start
513 && strncmp (p, "defalt", 6) == 0
514 && ! (('A' <= p[6] && p[6] <= 'Z')
515 || ('a' <= p[6] && p[6] <= 'z')
516 || ('0' <= p[6] && p[6] <= '9')
517 || p[6] == '_'))
519 fprintf (out, "DEFAULT");
520 p += 5;
521 in_ident = 0;
522 just_spaced = 0;
524 else if (c != ' ' || !just_spaced)
526 if (c >= 'a' && c <= 'z')
527 /* Upcase the letter. */
528 c += 'A' - 'a';
529 putc (c, out);
532 just_spaced = c == ' ';
533 need_space = 0;
537 /* Read through a c file. If a .o file is named,
538 the corresponding .c file is read instead.
539 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
540 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
543 scan_c_file (filename, mode)
544 char *filename, *mode;
546 FILE *infile;
547 register int c;
548 register int commas;
549 register int defunflag;
550 register int defvarperbufferflag;
551 register int defvarflag;
552 int minargs, maxargs;
553 int extension = filename[strlen (filename) - 1];
555 if (extension == 'o')
556 filename[strlen (filename) - 1] = 'c';
558 infile = fopen (filename, mode);
560 /* No error if non-ex input file */
561 if (infile == NULL)
563 perror (filename);
564 return 0;
567 /* Reset extension to be able to detect duplicate files. */
568 filename[strlen (filename) - 1] = extension;
570 c = '\n';
571 while (!feof (infile))
573 int doc_keyword = 0;
575 if (c != '\n' && c != '\r')
577 c = getc (infile);
578 continue;
580 c = getc (infile);
581 if (c == ' ')
583 while (c == ' ')
584 c = getc (infile);
585 if (c != 'D')
586 continue;
587 c = getc (infile);
588 if (c != 'E')
589 continue;
590 c = getc (infile);
591 if (c != 'F')
592 continue;
593 c = getc (infile);
594 if (c != 'V')
595 continue;
596 c = getc (infile);
597 if (c != 'A')
598 continue;
599 c = getc (infile);
600 if (c != 'R')
601 continue;
602 c = getc (infile);
603 if (c != '_')
604 continue;
606 defvarflag = 1;
607 defunflag = 0;
609 c = getc (infile);
610 defvarperbufferflag = (c == 'P');
612 c = getc (infile);
614 else if (c == 'D')
616 c = getc (infile);
617 if (c != 'E')
618 continue;
619 c = getc (infile);
620 if (c != 'F')
621 continue;
622 c = getc (infile);
623 defunflag = c == 'U';
624 defvarflag = 0;
625 defvarperbufferflag = 0;
627 else continue;
629 while (c != '(')
631 if (c < 0)
632 goto eof;
633 c = getc (infile);
636 /* Lisp variable or function name. */
637 c = getc (infile);
638 if (c != '"')
639 continue;
640 c = read_c_string_or_comment (infile, -1, 0, 0);
642 /* DEFVAR_LISP ("name", addr, "doc")
643 DEFVAR_LISP ("name", addr /\* doc *\/)
644 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
646 if (defunflag)
647 commas = 5;
648 else if (defvarperbufferflag)
649 commas = 2;
650 else if (defvarflag)
651 commas = 1;
652 else /* For DEFSIMPLE and DEFPRED */
653 commas = 2;
655 while (commas)
657 if (c == ',')
659 commas--;
661 if (defunflag && (commas == 1 || commas == 2))
664 c = getc (infile);
665 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
666 if (c < 0)
667 goto eof;
668 ungetc (c, infile);
669 if (commas == 2) /* pick up minargs */
670 fscanf (infile, "%d", &minargs);
671 else /* pick up maxargs */
672 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
673 maxargs = -1;
674 else
675 fscanf (infile, "%d", &maxargs);
679 if (c == EOF)
680 goto eof;
681 c = getc (infile);
684 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
685 c = getc (infile);
687 if (c == '"')
688 c = read_c_string_or_comment (infile, 0, 0, 0);
690 while (c != EOF && c != ',' && c != '/')
691 c = getc (infile);
692 if (c == ',')
694 c = getc (infile);
695 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
696 c = getc (infile);
697 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
698 c = getc (infile);
699 if (c == ':')
701 doc_keyword = 1;
702 c = getc (infile);
703 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
704 c = getc (infile);
708 if (c == '"'
709 || (c == '/'
710 && (c = getc (infile),
711 ungetc (c, infile),
712 c == '*')))
714 int comment = c != '"';
715 int saw_usage;
717 putc (037, outfile);
718 putc (defvarflag ? 'V' : 'F', outfile);
719 fprintf (outfile, "%s\n", buf);
721 if (comment)
722 getc (infile); /* Skip past `*' */
723 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
725 /* If this is a defun, find the arguments and print them. If
726 this function takes MANY or UNEVALLED args, then the C source
727 won't give the names of the arguments, so we shouldn't bother
728 trying to find them.
730 Various doc-string styles:
731 0: DEFUN (..., "DOC") (args) [!comment]
732 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
733 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
735 if (defunflag && maxargs != -1 && !saw_usage)
737 char argbuf[1024], *p = argbuf;
739 if (!comment || doc_keyword)
740 while (c != ')')
742 if (c < 0)
743 goto eof;
744 c = getc (infile);
747 /* Skip into arguments. */
748 while (c != '(')
750 if (c < 0)
751 goto eof;
752 c = getc (infile);
754 /* Copy arguments into ARGBUF. */
755 *p++ = c;
757 *p++ = c = getc (infile);
758 while (c != ')');
759 *p = '\0';
760 /* Output them. */
761 fprintf (outfile, "\n\n");
762 write_c_args (outfile, buf, argbuf, minargs, maxargs);
764 else if (defunflag && maxargs == -1 && !saw_usage)
765 /* The DOC should provide the usage form. */
766 fprintf (stderr, "Missing `usage' for function `%s'.\n", buf);
769 eof:
770 fclose (infile);
771 return 0;
774 /* Read a file of Lisp code, compiled or interpreted.
775 Looks for
776 (defun NAME ARGS DOCSTRING ...)
777 (defmacro NAME ARGS DOCSTRING ...)
778 (defsubst NAME ARGS DOCSTRING ...)
779 (autoload (quote NAME) FILE DOCSTRING ...)
780 (defvar NAME VALUE DOCSTRING)
781 (defconst NAME VALUE DOCSTRING)
782 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
783 (fset (quote NAME) #[... DOCSTRING ...])
784 (defalias (quote NAME) #[... DOCSTRING ...])
785 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
786 starting in column zero.
787 (quote NAME) may appear as 'NAME as well.
789 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
790 When we find that, we save it for the following defining-form,
791 and we use that instead of reading a doc string within that defining-form.
793 For defvar, defconst, and fset we skip to the docstring with a kludgy
794 formatting convention: all docstrings must appear on the same line as the
795 initial open-paren (the one in column zero) and must contain a backslash
796 and a newline immediately after the initial double-quote. No newlines
797 must appear between the beginning of the form and the first double-quote.
798 For defun, defmacro, and autoload, we know how to skip over the
799 arglist, but the doc string must still have a backslash and newline
800 immediately after the double quote.
801 The only source files that must follow this convention are preloaded
802 uncompiled ones like loaddefs.el and bindings.el; aside
803 from that, it is always the .elc file that we look at, and they are no
804 problem because byte-compiler output follows this convention.
805 The NAME and DOCSTRING are output.
806 NAME is preceded by `F' for a function or `V' for a variable.
807 An entry is output only if DOCSTRING has \ newline just after the opening "
810 void
811 skip_white (infile)
812 FILE *infile;
814 char c = ' ';
815 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
816 c = getc (infile);
817 ungetc (c, infile);
820 void
821 read_lisp_symbol (infile, buffer)
822 FILE *infile;
823 char *buffer;
825 char c;
826 char *fillp = buffer;
828 skip_white (infile);
829 while (1)
831 c = getc (infile);
832 if (c == '\\')
833 *(++fillp) = getc (infile);
834 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
836 ungetc (c, infile);
837 *fillp = 0;
838 break;
840 else
841 *fillp++ = c;
844 if (! buffer[0])
845 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
847 skip_white (infile);
851 scan_lisp_file (filename, mode)
852 char *filename, *mode;
854 FILE *infile;
855 register int c;
856 char *saved_string = 0;
858 infile = fopen (filename, mode);
859 if (infile == NULL)
861 perror (filename);
862 return 0; /* No error */
865 c = '\n';
866 while (!feof (infile))
868 char buffer[BUFSIZ];
869 char type;
871 /* If not at end of line, skip till we get to one. */
872 if (c != '\n' && c != '\r')
874 c = getc (infile);
875 continue;
877 /* Skip the line break. */
878 while (c == '\n' || c == '\r')
879 c = getc (infile);
880 /* Detect a dynamic doc string and save it for the next expression. */
881 if (c == '#')
883 c = getc (infile);
884 if (c == '@')
886 int length = 0;
887 int i;
889 /* Read the length. */
890 while ((c = getc (infile),
891 c >= '0' && c <= '9'))
893 length *= 10;
894 length += c - '0';
897 /* The next character is a space that is counted in the length
898 but not part of the doc string.
899 We already read it, so just ignore it. */
900 length--;
902 /* Read in the contents. */
903 if (saved_string != 0)
904 free (saved_string);
905 saved_string = (char *) malloc (length);
906 for (i = 0; i < length; i++)
907 saved_string[i] = getc (infile);
908 /* The last character is a ^_.
909 That is needed in the .elc file
910 but it is redundant in DOC. So get rid of it here. */
911 saved_string[length - 1] = 0;
912 /* Skip the line break. */
913 while (c == '\n' && c == '\r')
914 c = getc (infile);
915 /* Skip the following line. */
916 while (c != '\n' && c != '\r')
917 c = getc (infile);
919 continue;
922 if (c != '(')
923 continue;
925 read_lisp_symbol (infile, buffer);
927 if (! strcmp (buffer, "defun")
928 || ! strcmp (buffer, "defmacro")
929 || ! strcmp (buffer, "defsubst"))
931 type = 'F';
932 read_lisp_symbol (infile, buffer);
934 /* Skip the arguments: either "nil" or a list in parens */
936 c = getc (infile);
937 if (c == 'n') /* nil */
939 if ((c = getc (infile)) != 'i'
940 || (c = getc (infile)) != 'l')
942 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
943 buffer, filename);
944 continue;
947 else if (c != '(')
949 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
950 buffer, filename);
951 continue;
953 else
954 while (c != ')')
955 c = getc (infile);
956 skip_white (infile);
958 /* If the next three characters aren't `dquote bslash newline'
959 then we're not reading a docstring.
961 if ((c = getc (infile)) != '"'
962 || (c = getc (infile)) != '\\'
963 || ((c = getc (infile)) != '\n' && c != '\r'))
965 #ifdef DEBUG
966 fprintf (stderr, "## non-docstring in %s (%s)\n",
967 buffer, filename);
968 #endif
969 continue;
973 else if (! strcmp (buffer, "defvar")
974 || ! strcmp (buffer, "defconst"))
976 char c1 = 0, c2 = 0;
977 type = 'V';
978 read_lisp_symbol (infile, buffer);
980 if (saved_string == 0)
983 /* Skip until the end of line; remember two previous chars. */
984 while (c != '\n' && c != '\r' && c >= 0)
986 c2 = c1;
987 c1 = c;
988 c = getc (infile);
991 /* If two previous characters were " and \,
992 this is a doc string. Otherwise, there is none. */
993 if (c2 != '"' || c1 != '\\')
995 #ifdef DEBUG
996 fprintf (stderr, "## non-docstring in %s (%s)\n",
997 buffer, filename);
998 #endif
999 continue;
1004 else if (! strcmp (buffer, "custom-declare-variable"))
1006 char c1 = 0, c2 = 0;
1007 type = 'V';
1009 c = getc (infile);
1010 if (c == '\'')
1011 read_lisp_symbol (infile, buffer);
1012 else
1014 if (c != '(')
1016 fprintf (stderr,
1017 "## unparsable name in custom-declare-variable in %s\n",
1018 filename);
1019 continue;
1021 read_lisp_symbol (infile, buffer);
1022 if (strcmp (buffer, "quote"))
1024 fprintf (stderr,
1025 "## unparsable name in custom-declare-variable in %s\n",
1026 filename);
1027 continue;
1029 read_lisp_symbol (infile, buffer);
1030 c = getc (infile);
1031 if (c != ')')
1033 fprintf (stderr,
1034 "## unparsable quoted name in custom-declare-variable in %s\n",
1035 filename);
1036 continue;
1040 if (saved_string == 0)
1042 /* Skip to end of line; remember the two previous chars. */
1043 while (c != '\n' && c != '\r' && c >= 0)
1045 c2 = c1;
1046 c1 = c;
1047 c = getc (infile);
1050 /* If two previous characters were " and \,
1051 this is a doc string. Otherwise, there is none. */
1052 if (c2 != '"' || c1 != '\\')
1054 #ifdef DEBUG
1055 fprintf (stderr, "## non-docstring in %s (%s)\n",
1056 buffer, filename);
1057 #endif
1058 continue;
1063 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1065 char c1 = 0, c2 = 0;
1066 type = 'F';
1068 c = getc (infile);
1069 if (c == '\'')
1070 read_lisp_symbol (infile, buffer);
1071 else
1073 if (c != '(')
1075 fprintf (stderr, "## unparsable name in fset in %s\n",
1076 filename);
1077 continue;
1079 read_lisp_symbol (infile, buffer);
1080 if (strcmp (buffer, "quote"))
1082 fprintf (stderr, "## unparsable name in fset in %s\n",
1083 filename);
1084 continue;
1086 read_lisp_symbol (infile, buffer);
1087 c = getc (infile);
1088 if (c != ')')
1090 fprintf (stderr,
1091 "## unparsable quoted name in fset in %s\n",
1092 filename);
1093 continue;
1097 if (saved_string == 0)
1099 /* Skip to end of line; remember the two previous chars. */
1100 while (c != '\n' && c != '\r' && c >= 0)
1102 c2 = c1;
1103 c1 = c;
1104 c = getc (infile);
1107 /* If two previous characters were " and \,
1108 this is a doc string. Otherwise, there is none. */
1109 if (c2 != '"' || c1 != '\\')
1111 #ifdef DEBUG
1112 fprintf (stderr, "## non-docstring in %s (%s)\n",
1113 buffer, filename);
1114 #endif
1115 continue;
1120 else if (! strcmp (buffer, "autoload"))
1122 type = 'F';
1123 c = getc (infile);
1124 if (c == '\'')
1125 read_lisp_symbol (infile, buffer);
1126 else
1128 if (c != '(')
1130 fprintf (stderr, "## unparsable name in autoload in %s\n",
1131 filename);
1132 continue;
1134 read_lisp_symbol (infile, buffer);
1135 if (strcmp (buffer, "quote"))
1137 fprintf (stderr, "## unparsable name in autoload in %s\n",
1138 filename);
1139 continue;
1141 read_lisp_symbol (infile, buffer);
1142 c = getc (infile);
1143 if (c != ')')
1145 fprintf (stderr,
1146 "## unparsable quoted name in autoload in %s\n",
1147 filename);
1148 continue;
1151 skip_white (infile);
1152 if ((c = getc (infile)) != '\"')
1154 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1155 buffer, filename);
1156 continue;
1158 read_c_string_or_comment (infile, 0, 0, 0);
1159 skip_white (infile);
1161 if (saved_string == 0)
1163 /* If the next three characters aren't `dquote bslash newline'
1164 then we're not reading a docstring. */
1165 if ((c = getc (infile)) != '"'
1166 || (c = getc (infile)) != '\\'
1167 || ((c = getc (infile)) != '\n' && c != '\r'))
1169 #ifdef DEBUG
1170 fprintf (stderr, "## non-docstring in %s (%s)\n",
1171 buffer, filename);
1172 #endif
1173 continue;
1178 #ifdef DEBUG
1179 else if (! strcmp (buffer, "if")
1180 || ! strcmp (buffer, "byte-code"))
1182 #endif
1184 else
1186 #ifdef DEBUG
1187 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
1188 buffer, filename);
1189 #endif
1190 continue;
1193 /* At this point, we should either use the previous
1194 dynamic doc string in saved_string
1195 or gobble a doc string from the input file.
1197 In the latter case, the opening quote (and leading
1198 backslash-newline) have already been read. */
1200 putc (037, outfile);
1201 putc (type, outfile);
1202 fprintf (outfile, "%s\n", buffer);
1203 if (saved_string)
1205 fputs (saved_string, outfile);
1206 /* Don't use one dynamic doc string twice. */
1207 free (saved_string);
1208 saved_string = 0;
1210 else
1211 read_c_string_or_comment (infile, 1, 0, 0);
1213 fclose (infile);
1214 return 0;
1217 /* arch-tag: f7203aaf-991a-4238-acb5-601db56f2894
1218 (do not change this comment) */
1220 /* make-docfile.c ends here */