Include <unistd.h> unilaterally.
[emacs.git] / lib-src / make-docfile.c
blob43648c8abc711719ea388115f793b3f932f5061b
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 (const char *filename, const char *mode);
72 int scan_c_file (char *filename, const char *mode);
73 void fatal (const char *s1, const char *s2) NO_RETURN;
75 #ifdef MSDOS
76 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
77 file where that function is defined. */
78 #undef chdir
79 #endif
81 #include <unistd.h>
83 /* Stdio stream for output to the DOC file. */
84 FILE *outfile;
86 /* Name this program was invoked with. */
87 char *progname;
89 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
91 /* VARARGS1 */
92 void
93 error (const char *s1, const char *s2)
95 fprintf (stderr, "%s: ", progname);
96 fprintf (stderr, s1, s2);
97 fprintf (stderr, "\n");
100 /* Print error message and exit. */
102 /* VARARGS1 */
103 void
104 fatal (const char *s1, const char *s2)
106 error (s1, s2);
107 exit (EXIT_FAILURE);
110 /* Like malloc but get fatal error if memory is exhausted. */
112 void *
113 xmalloc (unsigned int size)
115 void *result = (void *) malloc (size);
116 if (result == NULL)
117 fatal ("virtual memory exhausted", 0);
118 return result;
122 main (int argc, char **argv)
124 int i;
125 int err_count = 0;
126 int first_infile;
128 progname = argv[0];
130 outfile = stdout;
132 /* Don't put CRs in the DOC file. */
133 #ifdef MSDOS
134 _fmode = O_BINARY;
135 #if 0 /* Suspicion is that this causes hanging.
136 So instead we require people to use -o on MSDOS. */
137 (stdout)->_flag &= ~_IOTEXT;
138 _setmode (fileno (stdout), O_BINARY);
139 #endif
140 outfile = 0;
141 #endif /* MSDOS */
142 #ifdef WINDOWSNT
143 _fmode = O_BINARY;
144 _setmode (fileno (stdout), O_BINARY);
145 #endif /* WINDOWSNT */
147 /* If first two args are -o FILE, output to FILE. */
148 i = 1;
149 if (argc > i + 1 && !strcmp (argv[i], "-o"))
151 outfile = fopen (argv[i + 1], "w");
152 i += 2;
154 if (argc > i + 1 && !strcmp (argv[i], "-a"))
156 outfile = fopen (argv[i + 1], "a");
157 i += 2;
159 if (argc > i + 1 && !strcmp (argv[i], "-d"))
161 chdir (argv[i + 1]);
162 i += 2;
165 if (outfile == 0)
166 fatal ("No output file specified", "");
168 first_infile = i;
169 for (; i < argc; i++)
171 int j;
172 /* Don't process one file twice. */
173 for (j = first_infile; j < i; j++)
174 if (! strcmp (argv[i], argv[j]))
175 break;
176 if (j == i)
177 err_count += scan_file (argv[i]);
179 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
182 /* Add a source file name boundary marker in the output file. */
183 void
184 put_filename (char *filename)
186 char *tmp;
188 for (tmp = filename; *tmp; tmp++)
190 if (IS_DIRECTORY_SEP(*tmp))
191 filename = tmp + 1;
194 putc (037, outfile);
195 putc ('S', outfile);
196 fprintf (outfile, "%s\n", filename);
199 /* Read file FILENAME and output its doc strings to outfile. */
200 /* Return 1 if file is not found, 0 if it is found. */
203 scan_file (char *filename)
206 size_t 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 const char *keyword;
236 /* The current point we've reached in an occurrence of KEYWORD in
237 the input stream. */
238 const 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 const 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 size_t ident_length = 0;
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 (ident_length == 0)
480 error ("empty arg list for `%s' should be (void), not ()", func);
481 continue;
484 if (strncmp (ident_start, "void", ident_length) == 0)
485 continue;
487 putc (' ', out);
489 if (minargs == 0 && maxargs > 0)
490 fprintf (out, "&optional ");
492 minargs--;
493 maxargs--;
495 /* In C code, `default' is a reserved word, so we spell it
496 `defalt'; unmangle that here. */
497 if (ident_length == 6 && strncmp (ident_start, "defalt", 6) == 0)
498 fprintf (out, "DEFAULT");
499 else
500 while (ident_length-- > 0)
502 c = *ident_start++;
503 if (c >= 'a' && c <= 'z')
504 /* Upcase the letter. */
505 c += 'A' - 'a';
506 else if (c == '_')
507 /* Print underscore as hyphen. */
508 c = '-';
509 putc (c, out);
514 putc (')', out);
517 /* Read through a c file. If a .o file is named,
518 the corresponding .c or .m file is read instead.
519 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
520 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
523 scan_c_file (char *filename, const char *mode)
525 FILE *infile;
526 register int c;
527 register int commas;
528 register int defunflag;
529 register int defvarperbufferflag;
530 register int defvarflag;
531 int minargs, maxargs;
532 int extension = filename[strlen (filename) - 1];
534 if (extension == 'o')
535 filename[strlen (filename) - 1] = 'c';
537 infile = fopen (filename, mode);
539 if (infile == NULL && extension == 'o')
541 /* try .m */
542 filename[strlen (filename) - 1] = 'm';
543 infile = fopen (filename, mode);
544 if (infile == NULL)
545 filename[strlen (filename) - 1] = 'c'; /* don't confuse people */
548 /* No error if non-ex input file */
549 if (infile == NULL)
551 perror (filename);
552 return 0;
555 /* Reset extension to be able to detect duplicate files. */
556 filename[strlen (filename) - 1] = extension;
558 c = '\n';
559 while (!feof (infile))
561 int doc_keyword = 0;
563 if (c != '\n' && c != '\r')
565 c = getc (infile);
566 continue;
568 c = getc (infile);
569 if (c == ' ')
571 while (c == ' ')
572 c = getc (infile);
573 if (c != 'D')
574 continue;
575 c = getc (infile);
576 if (c != 'E')
577 continue;
578 c = getc (infile);
579 if (c != 'F')
580 continue;
581 c = getc (infile);
582 if (c != 'V')
583 continue;
584 c = getc (infile);
585 if (c != 'A')
586 continue;
587 c = getc (infile);
588 if (c != 'R')
589 continue;
590 c = getc (infile);
591 if (c != '_')
592 continue;
594 defvarflag = 1;
595 defunflag = 0;
597 c = getc (infile);
598 defvarperbufferflag = (c == 'P');
600 c = getc (infile);
602 else if (c == 'D')
604 c = getc (infile);
605 if (c != 'E')
606 continue;
607 c = getc (infile);
608 if (c != 'F')
609 continue;
610 c = getc (infile);
611 defunflag = c == 'U';
612 defvarflag = 0;
613 defvarperbufferflag = 0;
615 else continue;
617 while (c != '(')
619 if (c < 0)
620 goto eof;
621 c = getc (infile);
624 /* Lisp variable or function name. */
625 c = getc (infile);
626 if (c != '"')
627 continue;
628 c = read_c_string_or_comment (infile, -1, 0, 0);
630 /* DEFVAR_LISP ("name", addr, "doc")
631 DEFVAR_LISP ("name", addr /\* doc *\/)
632 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
634 if (defunflag)
635 commas = 5;
636 else if (defvarperbufferflag)
637 commas = 2;
638 else if (defvarflag)
639 commas = 1;
640 else /* For DEFSIMPLE and DEFPRED */
641 commas = 2;
643 while (commas)
645 if (c == ',')
647 commas--;
649 if (defunflag && (commas == 1 || commas == 2))
652 c = getc (infile);
653 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
654 if (c < 0)
655 goto eof;
656 ungetc (c, infile);
657 if (commas == 2) /* pick up minargs */
658 fscanf (infile, "%d", &minargs);
659 else /* pick up maxargs */
660 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
661 maxargs = -1;
662 else
663 fscanf (infile, "%d", &maxargs);
667 if (c == EOF)
668 goto eof;
669 c = getc (infile);
672 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
673 c = getc (infile);
675 if (c == '"')
676 c = read_c_string_or_comment (infile, 0, 0, 0);
678 while (c != EOF && c != ',' && c != '/')
679 c = getc (infile);
680 if (c == ',')
682 c = getc (infile);
683 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
684 c = getc (infile);
685 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
686 c = getc (infile);
687 if (c == ':')
689 doc_keyword = 1;
690 c = getc (infile);
691 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
692 c = getc (infile);
696 if (c == '"'
697 || (c == '/'
698 && (c = getc (infile),
699 ungetc (c, infile),
700 c == '*')))
702 int comment = c != '"';
703 int saw_usage;
705 putc (037, outfile);
706 putc (defvarflag ? 'V' : 'F', outfile);
707 fprintf (outfile, "%s\n", buf);
709 if (comment)
710 getc (infile); /* Skip past `*' */
711 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
713 /* If this is a defun, find the arguments and print them. If
714 this function takes MANY or UNEVALLED args, then the C source
715 won't give the names of the arguments, so we shouldn't bother
716 trying to find them.
718 Various doc-string styles:
719 0: DEFUN (..., "DOC") (args) [!comment]
720 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
721 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
723 if (defunflag && maxargs != -1 && !saw_usage)
725 char argbuf[1024], *p = argbuf;
727 if (!comment || doc_keyword)
728 while (c != ')')
730 if (c < 0)
731 goto eof;
732 c = getc (infile);
735 /* Skip into arguments. */
736 while (c != '(')
738 if (c < 0)
739 goto eof;
740 c = getc (infile);
742 /* Copy arguments into ARGBUF. */
743 *p++ = c;
745 *p++ = c = getc (infile);
746 while (c != ')');
747 *p = '\0';
748 /* Output them. */
749 fprintf (outfile, "\n\n");
750 write_c_args (outfile, buf, argbuf, minargs, maxargs);
752 else if (defunflag && maxargs == -1 && !saw_usage)
753 /* The DOC should provide the usage form. */
754 fprintf (stderr, "Missing `usage' for function `%s'.\n", buf);
757 eof:
758 fclose (infile);
759 return 0;
762 /* Read a file of Lisp code, compiled or interpreted.
763 Looks for
764 (defun NAME ARGS DOCSTRING ...)
765 (defmacro NAME ARGS DOCSTRING ...)
766 (defsubst NAME ARGS DOCSTRING ...)
767 (autoload (quote NAME) FILE DOCSTRING ...)
768 (defvar NAME VALUE DOCSTRING)
769 (defconst NAME VALUE DOCSTRING)
770 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
771 (fset (quote NAME) #[... DOCSTRING ...])
772 (defalias (quote NAME) #[... DOCSTRING ...])
773 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
774 starting in column zero.
775 (quote NAME) may appear as 'NAME as well.
777 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
778 When we find that, we save it for the following defining-form,
779 and we use that instead of reading a doc string within that defining-form.
781 For defvar, defconst, and fset we skip to the docstring with a kludgy
782 formatting convention: all docstrings must appear on the same line as the
783 initial open-paren (the one in column zero) and must contain a backslash
784 and a newline immediately after the initial double-quote. No newlines
785 must appear between the beginning of the form and the first double-quote.
786 For defun, defmacro, and autoload, we know how to skip over the
787 arglist, but the doc string must still have a backslash and newline
788 immediately after the double quote.
789 The only source files that must follow this convention are preloaded
790 uncompiled ones like loaddefs.el and bindings.el; aside
791 from that, it is always the .elc file that we look at, and they are no
792 problem because byte-compiler output follows this convention.
793 The NAME and DOCSTRING are output.
794 NAME is preceded by `F' for a function or `V' for a variable.
795 An entry is output only if DOCSTRING has \ newline just after the opening "
798 void
799 skip_white (FILE *infile)
801 char c = ' ';
802 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
803 c = getc (infile);
804 ungetc (c, infile);
807 void
808 read_lisp_symbol (FILE *infile, char *buffer)
810 char c;
811 char *fillp = buffer;
813 skip_white (infile);
814 while (1)
816 c = getc (infile);
817 if (c == '\\')
818 *(++fillp) = getc (infile);
819 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
821 ungetc (c, infile);
822 *fillp = 0;
823 break;
825 else
826 *fillp++ = c;
829 if (! buffer[0])
830 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
832 skip_white (infile);
836 scan_lisp_file (const char *filename, const char *mode)
838 FILE *infile;
839 register int c;
840 char *saved_string = 0;
842 infile = fopen (filename, mode);
843 if (infile == NULL)
845 perror (filename);
846 return 0; /* No error */
849 c = '\n';
850 while (!feof (infile))
852 char buffer[BUFSIZ];
853 char type;
855 /* If not at end of line, skip till we get to one. */
856 if (c != '\n' && c != '\r')
858 c = getc (infile);
859 continue;
861 /* Skip the line break. */
862 while (c == '\n' || c == '\r')
863 c = getc (infile);
864 /* Detect a dynamic doc string and save it for the next expression. */
865 if (c == '#')
867 c = getc (infile);
868 if (c == '@')
870 int length = 0;
871 int i;
873 /* Read the length. */
874 while ((c = getc (infile),
875 c >= '0' && c <= '9'))
877 length *= 10;
878 length += c - '0';
881 /* The next character is a space that is counted in the length
882 but not part of the doc string.
883 We already read it, so just ignore it. */
884 length--;
886 /* Read in the contents. */
887 free (saved_string);
888 saved_string = (char *) xmalloc (length);
889 for (i = 0; i < length; i++)
890 saved_string[i] = getc (infile);
891 /* The last character is a ^_.
892 That is needed in the .elc file
893 but it is redundant in DOC. So get rid of it here. */
894 saved_string[length - 1] = 0;
895 /* Skip the line break. */
896 while (c == '\n' && c == '\r')
897 c = getc (infile);
898 /* Skip the following line. */
899 while (c != '\n' && c != '\r')
900 c = getc (infile);
902 continue;
905 if (c != '(')
906 continue;
908 read_lisp_symbol (infile, buffer);
910 if (! strcmp (buffer, "defun")
911 || ! strcmp (buffer, "defmacro")
912 || ! strcmp (buffer, "defsubst"))
914 type = 'F';
915 read_lisp_symbol (infile, buffer);
917 /* Skip the arguments: either "nil" or a list in parens */
919 c = getc (infile);
920 if (c == 'n') /* nil */
922 if ((c = getc (infile)) != 'i'
923 || (c = getc (infile)) != 'l')
925 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
926 buffer, filename);
927 continue;
930 else if (c != '(')
932 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
933 buffer, filename);
934 continue;
936 else
937 while (c != ')')
938 c = getc (infile);
939 skip_white (infile);
941 /* If the next three characters aren't `dquote bslash newline'
942 then we're not reading a docstring.
944 if ((c = getc (infile)) != '"'
945 || (c = getc (infile)) != '\\'
946 || ((c = getc (infile)) != '\n' && c != '\r'))
948 #ifdef DEBUG
949 fprintf (stderr, "## non-docstring in %s (%s)\n",
950 buffer, filename);
951 #endif
952 continue;
956 else if (! strcmp (buffer, "defvar")
957 || ! strcmp (buffer, "defconst"))
959 char c1 = 0, c2 = 0;
960 type = 'V';
961 read_lisp_symbol (infile, buffer);
963 if (saved_string == 0)
966 /* Skip until the end of line; remember two previous chars. */
967 while (c != '\n' && c != '\r' && c >= 0)
969 c2 = c1;
970 c1 = c;
971 c = getc (infile);
974 /* If two previous characters were " and \,
975 this is a doc string. Otherwise, there is none. */
976 if (c2 != '"' || c1 != '\\')
978 #ifdef DEBUG
979 fprintf (stderr, "## non-docstring in %s (%s)\n",
980 buffer, filename);
981 #endif
982 continue;
987 else if (! strcmp (buffer, "custom-declare-variable")
988 || ! strcmp (buffer, "defvaralias")
991 char c1 = 0, c2 = 0;
992 type = 'V';
994 c = getc (infile);
995 if (c == '\'')
996 read_lisp_symbol (infile, buffer);
997 else
999 if (c != '(')
1001 fprintf (stderr,
1002 "## unparsable name in custom-declare-variable in %s\n",
1003 filename);
1004 continue;
1006 read_lisp_symbol (infile, buffer);
1007 if (strcmp (buffer, "quote"))
1009 fprintf (stderr,
1010 "## unparsable name in custom-declare-variable in %s\n",
1011 filename);
1012 continue;
1014 read_lisp_symbol (infile, buffer);
1015 c = getc (infile);
1016 if (c != ')')
1018 fprintf (stderr,
1019 "## unparsable quoted name in custom-declare-variable in %s\n",
1020 filename);
1021 continue;
1025 if (saved_string == 0)
1027 /* Skip to end of line; remember the two previous chars. */
1028 while (c != '\n' && c != '\r' && c >= 0)
1030 c2 = c1;
1031 c1 = c;
1032 c = getc (infile);
1035 /* If two previous characters were " and \,
1036 this is a doc string. Otherwise, there is none. */
1037 if (c2 != '"' || c1 != '\\')
1039 #ifdef DEBUG
1040 fprintf (stderr, "## non-docstring in %s (%s)\n",
1041 buffer, filename);
1042 #endif
1043 continue;
1048 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1050 char c1 = 0, c2 = 0;
1051 type = 'F';
1053 c = getc (infile);
1054 if (c == '\'')
1055 read_lisp_symbol (infile, buffer);
1056 else
1058 if (c != '(')
1060 fprintf (stderr, "## unparsable name in fset in %s\n",
1061 filename);
1062 continue;
1064 read_lisp_symbol (infile, buffer);
1065 if (strcmp (buffer, "quote"))
1067 fprintf (stderr, "## unparsable name in fset in %s\n",
1068 filename);
1069 continue;
1071 read_lisp_symbol (infile, buffer);
1072 c = getc (infile);
1073 if (c != ')')
1075 fprintf (stderr,
1076 "## unparsable quoted name in fset in %s\n",
1077 filename);
1078 continue;
1082 if (saved_string == 0)
1084 /* Skip to end of line; remember the two previous chars. */
1085 while (c != '\n' && c != '\r' && c >= 0)
1087 c2 = c1;
1088 c1 = c;
1089 c = getc (infile);
1092 /* If two previous characters were " and \,
1093 this is a doc string. Otherwise, there is none. */
1094 if (c2 != '"' || c1 != '\\')
1096 #ifdef DEBUG
1097 fprintf (stderr, "## non-docstring in %s (%s)\n",
1098 buffer, filename);
1099 #endif
1100 continue;
1105 else if (! strcmp (buffer, "autoload"))
1107 type = 'F';
1108 c = getc (infile);
1109 if (c == '\'')
1110 read_lisp_symbol (infile, buffer);
1111 else
1113 if (c != '(')
1115 fprintf (stderr, "## unparsable name in autoload in %s\n",
1116 filename);
1117 continue;
1119 read_lisp_symbol (infile, buffer);
1120 if (strcmp (buffer, "quote"))
1122 fprintf (stderr, "## unparsable name in autoload in %s\n",
1123 filename);
1124 continue;
1126 read_lisp_symbol (infile, buffer);
1127 c = getc (infile);
1128 if (c != ')')
1130 fprintf (stderr,
1131 "## unparsable quoted name in autoload in %s\n",
1132 filename);
1133 continue;
1136 skip_white (infile);
1137 if ((c = getc (infile)) != '\"')
1139 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1140 buffer, filename);
1141 continue;
1143 read_c_string_or_comment (infile, 0, 0, 0);
1144 skip_white (infile);
1146 if (saved_string == 0)
1148 /* If the next three characters aren't `dquote bslash newline'
1149 then we're not reading a docstring. */
1150 if ((c = getc (infile)) != '"'
1151 || (c = getc (infile)) != '\\'
1152 || ((c = getc (infile)) != '\n' && c != '\r'))
1154 #ifdef DEBUG
1155 fprintf (stderr, "## non-docstring in %s (%s)\n",
1156 buffer, filename);
1157 #endif
1158 continue;
1163 #ifdef DEBUG
1164 else if (! strcmp (buffer, "if")
1165 || ! strcmp (buffer, "byte-code"))
1167 #endif
1169 else
1171 #ifdef DEBUG
1172 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1173 buffer, filename);
1174 #endif
1175 continue;
1178 /* At this point, we should either use the previous
1179 dynamic doc string in saved_string
1180 or gobble a doc string from the input file.
1182 In the latter case, the opening quote (and leading
1183 backslash-newline) have already been read. */
1185 putc (037, outfile);
1186 putc (type, outfile);
1187 fprintf (outfile, "%s\n", buffer);
1188 if (saved_string)
1190 fputs (saved_string, outfile);
1191 /* Don't use one dynamic doc string twice. */
1192 free (saved_string);
1193 saved_string = 0;
1195 else
1196 read_c_string_or_comment (infile, 1, 0, 0);
1198 fclose (infile);
1199 return 0;
1202 /* arch-tag: f7203aaf-991a-4238-acb5-601db56f2894
1203 (do not change this comment) */
1205 /* make-docfile.c ends here */