Allow use of vc-root-* commands in *vc-log* buffers.
[emacs.git] / lib-src / make-docfile.c
blobbd87b5b6524b70a5f8de43cb894984a44e142b5b
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2012
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 3 of the License, or
10 (at your option) 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. If not, see <http://www.gnu.org/licenses/>. */
21 /* The arguments given to this program are all the C and Lisp source files
22 of GNU Emacs. .elc and .el and .c files are allowed.
23 A .o file can also be specified; the .c file it was made from is used.
24 This helps the makefile pass the correct list of files.
25 Option -d DIR means change to DIR before looking for files.
27 The results, which go to standard output or to a file
28 specified with -a or -o (-a to append, -o to start from nothing),
29 are entries containing function or variable names and their documentation.
30 Each entry starts with a ^_ character.
31 Then comes F for a function or V for a variable.
32 Then comes the function or variable name, terminated with a newline.
33 Then comes the documentation for that function or variable.
36 #include <config.h>
38 /* Defined to be emacs_main, sys_fopen, etc. in config.h. */
39 #undef main
40 #undef fopen
41 #undef chdir
43 #include <stdio.h>
44 #include <stdlib.h>
45 #ifdef MSDOS
46 #include <fcntl.h>
47 #endif /* MSDOS */
48 #ifdef WINDOWSNT
49 #include <fcntl.h>
50 #include <direct.h>
51 #endif /* WINDOWSNT */
53 #ifdef DOS_NT
54 #define READ_TEXT "rt"
55 #define READ_BINARY "rb"
56 #else /* not DOS_NT */
57 #define READ_TEXT "r"
58 #define READ_BINARY "r"
59 #endif /* not DOS_NT */
61 #ifndef DIRECTORY_SEP
62 #define DIRECTORY_SEP '/'
63 #endif
65 #ifndef IS_DIRECTORY_SEP
66 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
67 #endif
69 /* Use this to suppress gcc's `...may be used before initialized' warnings. */
70 #ifdef lint
71 # define IF_LINT(Code) Code
72 #else
73 # define IF_LINT(Code) /* empty */
74 #endif
76 static int scan_file (char *filename);
77 static int scan_lisp_file (const char *filename, const char *mode);
78 static int scan_c_file (char *filename, const char *mode);
79 static void start_globals (void);
80 static void write_globals (void);
82 #ifdef MSDOS
83 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
84 file where that function is defined. */
85 #undef chdir
86 #endif
88 #include <unistd.h>
90 /* Stdio stream for output to the DOC file. */
91 FILE *outfile;
93 /* Name this program was invoked with. */
94 char *progname;
96 /* Nonzero if this invocation is generating globals.h. */
97 int generate_globals;
99 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
101 /* VARARGS1 */
102 static void
103 error (const char *s1, const char *s2)
105 fprintf (stderr, "%s: ", progname);
106 fprintf (stderr, s1, s2);
107 fprintf (stderr, "\n");
110 /* Print error message and exit. */
112 /* VARARGS1 */
113 static _Noreturn void
114 fatal (const char *s1, const char *s2)
116 error (s1, s2);
117 exit (EXIT_FAILURE);
120 /* Like malloc but get fatal error if memory is exhausted. */
122 static void *
123 xmalloc (unsigned int size)
125 void *result = (void *) malloc (size);
126 if (result == NULL)
127 fatal ("virtual memory exhausted", 0);
128 return result;
131 /* Like realloc but get fatal error if memory is exhausted. */
133 static void *
134 xrealloc (void *arg, unsigned int size)
136 void *result = (void *) realloc (arg, size);
137 if (result == NULL)
138 fatal ("virtual memory exhausted", 0);
139 return result;
144 main (int argc, char **argv)
146 int i;
147 int err_count = 0;
148 int first_infile;
150 progname = argv[0];
152 outfile = stdout;
154 /* Don't put CRs in the DOC file. */
155 #ifdef MSDOS
156 _fmode = O_BINARY;
157 #if 0 /* Suspicion is that this causes hanging.
158 So instead we require people to use -o on MSDOS. */
159 (stdout)->_flag &= ~_IOTEXT;
160 _setmode (fileno (stdout), O_BINARY);
161 #endif
162 outfile = 0;
163 #endif /* MSDOS */
164 #ifdef WINDOWSNT
165 _fmode = O_BINARY;
166 _setmode (fileno (stdout), O_BINARY);
167 #endif /* WINDOWSNT */
169 /* If first two args are -o FILE, output to FILE. */
170 i = 1;
171 if (argc > i + 1 && !strcmp (argv[i], "-o"))
173 outfile = fopen (argv[i + 1], "w");
174 i += 2;
176 if (argc > i + 1 && !strcmp (argv[i], "-a"))
178 outfile = fopen (argv[i + 1], "a");
179 i += 2;
181 if (argc > i + 1 && !strcmp (argv[i], "-d"))
183 if (chdir (argv[i + 1]) != 0)
185 perror (argv[i + 1]);
186 return EXIT_FAILURE;
188 i += 2;
190 if (argc > i && !strcmp (argv[i], "-g"))
192 generate_globals = 1;
193 ++i;
196 if (outfile == 0)
197 fatal ("No output file specified", "");
199 if (generate_globals)
200 start_globals ();
202 first_infile = i;
203 for (; i < argc; i++)
205 int j;
206 /* Don't process one file twice. */
207 for (j = first_infile; j < i; j++)
208 if (! strcmp (argv[i], argv[j]))
209 break;
210 if (j == i)
211 err_count += scan_file (argv[i]);
214 if (err_count == 0 && generate_globals)
215 write_globals ();
217 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
220 /* Add a source file name boundary marker in the output file. */
221 static void
222 put_filename (char *filename)
224 char *tmp;
226 for (tmp = filename; *tmp; tmp++)
228 if (IS_DIRECTORY_SEP (*tmp))
229 filename = tmp + 1;
232 putc (037, outfile);
233 putc ('S', outfile);
234 fprintf (outfile, "%s\n", filename);
237 /* Read file FILENAME and output its doc strings to outfile. */
238 /* Return 1 if file is not found, 0 if it is found. */
240 static int
241 scan_file (char *filename)
244 size_t len = strlen (filename);
246 if (!generate_globals)
247 put_filename (filename);
248 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
249 return scan_lisp_file (filename, READ_BINARY);
250 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
251 return scan_lisp_file (filename, READ_TEXT);
252 else
253 return scan_c_file (filename, READ_TEXT);
256 static void
257 start_globals (void)
259 fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n");
260 fprintf (outfile, "/* DO NOT EDIT. */\n");
261 fprintf (outfile, "struct emacs_globals {\n");
264 static char input_buffer[128];
266 /* Some state during the execution of `read_c_string_or_comment'. */
267 struct rcsoc_state
269 /* A count of spaces and newlines that have been read, but not output. */
270 unsigned pending_spaces, pending_newlines;
272 /* Where we're reading from. */
273 FILE *in_file;
275 /* If non-zero, a buffer into which to copy characters. */
276 char *buf_ptr;
277 /* If non-zero, a file into which to copy characters. */
278 FILE *out_file;
280 /* A keyword we look for at the beginning of lines. If found, it is
281 not copied, and SAW_KEYWORD is set to true. */
282 const char *keyword;
283 /* The current point we've reached in an occurrence of KEYWORD in
284 the input stream. */
285 const char *cur_keyword_ptr;
286 /* Set to true if we saw an occurrence of KEYWORD. */
287 int saw_keyword;
290 /* Output CH to the file or buffer in STATE. Any pending newlines or
291 spaces are output first. */
293 static inline void
294 put_char (int ch, struct rcsoc_state *state)
296 int out_ch;
299 if (state->pending_newlines > 0)
301 state->pending_newlines--;
302 out_ch = '\n';
304 else if (state->pending_spaces > 0)
306 state->pending_spaces--;
307 out_ch = ' ';
309 else
310 out_ch = ch;
312 if (state->out_file)
313 putc (out_ch, state->out_file);
314 if (state->buf_ptr)
315 *state->buf_ptr++ = out_ch;
317 while (out_ch != ch);
320 /* If in the middle of scanning a keyword, continue scanning with
321 character CH, otherwise output CH to the file or buffer in STATE.
322 Any pending newlines or spaces are output first, as well as any
323 previously scanned characters that were thought to be part of a
324 keyword, but were in fact not. */
326 static void
327 scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
329 if (state->keyword
330 && *state->cur_keyword_ptr == ch
331 && (state->cur_keyword_ptr > state->keyword
332 || state->pending_newlines > 0))
333 /* We might be looking at STATE->keyword at some point.
334 Keep looking until we know for sure. */
336 if (*++state->cur_keyword_ptr == '\0')
337 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
339 state->saw_keyword = 1;
341 /* Reset the scanning pointer. */
342 state->cur_keyword_ptr = state->keyword;
344 /* Canonicalize whitespace preceding a usage string. */
345 state->pending_newlines = 2;
346 state->pending_spaces = 0;
348 /* Skip any whitespace between the keyword and the
349 usage string. */
351 ch = getc (state->in_file);
352 while (ch == ' ' || ch == '\n');
354 /* Output the open-paren we just read. */
355 put_char (ch, state);
357 /* Skip the function name and replace it with `fn'. */
359 ch = getc (state->in_file);
360 while (ch != ' ' && ch != ')');
361 put_char ('f', state);
362 put_char ('n', state);
364 /* Put back the last character. */
365 ungetc (ch, state->in_file);
368 else
370 if (state->keyword && state->cur_keyword_ptr > state->keyword)
371 /* We scanned the beginning of a potential usage
372 keyword, but it was a false alarm. Output the
373 part we scanned. */
375 const char *p;
377 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
378 put_char (*p, state);
380 state->cur_keyword_ptr = state->keyword;
383 put_char (ch, state);
388 /* Skip a C string or C-style comment from INFILE, and return the
389 character that follows. COMMENT non-zero means skip a comment. If
390 PRINTFLAG is positive, output string contents to outfile. If it is
391 negative, store contents in buf. Convert escape sequences \n and
392 \t to newline and tab; discard \ followed by newline.
393 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
394 at the beginning of a line will be removed, and *SAW_USAGE set to
395 true if any were encountered. */
397 static int
398 read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
400 register int c;
401 struct rcsoc_state state;
403 state.in_file = infile;
404 state.buf_ptr = (printflag < 0 ? input_buffer : 0);
405 state.out_file = (printflag > 0 ? outfile : 0);
406 state.pending_spaces = 0;
407 state.pending_newlines = 0;
408 state.keyword = (saw_usage ? "usage:" : 0);
409 state.cur_keyword_ptr = state.keyword;
410 state.saw_keyword = 0;
412 c = getc (infile);
413 if (comment)
414 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
415 c = getc (infile);
417 while (c != EOF)
419 while (c != EOF && (comment ? c != '*' : c != '"'))
421 if (c == '\\')
423 c = getc (infile);
424 if (c == '\n' || c == '\r')
426 c = getc (infile);
427 continue;
429 if (c == 'n')
430 c = '\n';
431 if (c == 't')
432 c = '\t';
435 if (c == ' ')
436 state.pending_spaces++;
437 else if (c == '\n')
439 state.pending_newlines++;
440 state.pending_spaces = 0;
442 else
443 scan_keyword_or_put_char (c, &state);
445 c = getc (infile);
448 if (c != EOF)
449 c = getc (infile);
451 if (comment)
453 if (c == '/')
455 c = getc (infile);
456 break;
459 scan_keyword_or_put_char ('*', &state);
461 else
463 if (c != '"')
464 break;
466 /* If we had a "", concatenate the two strings. */
467 c = getc (infile);
471 if (printflag < 0)
472 *state.buf_ptr = 0;
474 if (saw_usage)
475 *saw_usage = state.saw_keyword;
477 return c;
482 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
483 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
485 static void
486 write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
488 register char *p;
489 int in_ident = 0;
490 char *ident_start IF_LINT (= NULL);
491 size_t ident_length = 0;
493 fprintf (out, "(fn");
495 if (*buf == '(')
496 ++buf;
498 for (p = buf; *p; p++)
500 char c = *p;
502 /* Notice when a new identifier starts. */
503 if ((('A' <= c && c <= 'Z')
504 || ('a' <= c && c <= 'z')
505 || ('0' <= c && c <= '9')
506 || c == '_')
507 != in_ident)
509 if (!in_ident)
511 in_ident = 1;
512 ident_start = p;
514 else
516 in_ident = 0;
517 ident_length = p - ident_start;
521 /* Found the end of an argument, write out the last seen
522 identifier. */
523 if (c == ',' || c == ')')
525 if (ident_length == 0)
527 error ("empty arg list for `%s' should be (void), not ()", func);
528 continue;
531 if (strncmp (ident_start, "void", ident_length) == 0)
532 continue;
534 putc (' ', out);
536 if (minargs == 0 && maxargs > 0)
537 fprintf (out, "&optional ");
539 minargs--;
540 maxargs--;
542 /* In C code, `default' is a reserved word, so we spell it
543 `defalt'; demangle that here. */
544 if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0)
545 fprintf (out, "DEFAULT");
546 else
547 while (ident_length-- > 0)
549 c = *ident_start++;
550 if (c >= 'a' && c <= 'z')
551 /* Upcase the letter. */
552 c += 'A' - 'a';
553 else if (c == '_')
554 /* Print underscore as hyphen. */
555 c = '-';
556 putc (c, out);
561 putc (')', out);
564 /* The types of globals. */
565 enum global_type
567 FUNCTION,
568 EMACS_INTEGER,
569 BOOLEAN,
570 LISP_OBJECT,
571 INVALID
574 /* A single global. */
575 struct global
577 enum global_type type;
578 char *name;
579 int value;
582 /* All the variable names we saw while scanning C sources in `-g'
583 mode. */
584 int num_globals;
585 int num_globals_allocated;
586 struct global *globals;
588 static void
589 add_global (enum global_type type, char *name, int value)
591 /* Ignore the one non-symbol that can occur. */
592 if (strcmp (name, "..."))
594 ++num_globals;
596 if (num_globals_allocated == 0)
598 num_globals_allocated = 100;
599 globals = xmalloc (num_globals_allocated * sizeof (struct global));
601 else if (num_globals == num_globals_allocated)
603 num_globals_allocated *= 2;
604 globals = xrealloc (globals,
605 num_globals_allocated * sizeof (struct global));
608 globals[num_globals - 1].type = type;
609 globals[num_globals - 1].name = name;
610 globals[num_globals - 1].value = value;
614 static int
615 compare_globals (const void *a, const void *b)
617 const struct global *ga = a;
618 const struct global *gb = b;
620 if (ga->type == FUNCTION)
622 if (gb->type != FUNCTION)
623 return 1;
625 else if (gb->type == FUNCTION)
626 return -1;
628 return strcmp (ga->name, gb->name);
631 static void
632 close_emacs_globals (void)
634 fprintf (outfile, "};\n");
635 fprintf (outfile, "extern struct emacs_globals globals;\n");
638 static void
639 write_globals (void)
641 int i, seen_defun = 0;
642 qsort (globals, num_globals, sizeof (struct global), compare_globals);
643 for (i = 0; i < num_globals; ++i)
645 char const *type;
647 switch (globals[i].type)
649 case EMACS_INTEGER:
650 type = "EMACS_INT";
651 break;
652 case BOOLEAN:
653 type = "int";
654 break;
655 case LISP_OBJECT:
656 type = "Lisp_Object";
657 break;
658 case FUNCTION:
659 if (!seen_defun)
661 close_emacs_globals ();
662 fprintf (outfile, "\n");
663 seen_defun = 1;
665 break;
666 default:
667 fatal ("not a recognized DEFVAR_", 0);
670 if (globals[i].type != FUNCTION)
672 fprintf (outfile, " %s f_%s;\n", type, globals[i].name);
673 fprintf (outfile, "#define %s globals.f_%s\n",
674 globals[i].name, globals[i].name);
676 else
678 /* It would be nice to have a cleaner way to deal with these
679 special hacks. */
680 if (strcmp (globals[i].name, "Fthrow") == 0
681 || strcmp (globals[i].name, "Ftop_level") == 0
682 || strcmp (globals[i].name, "Fkill_emacs") == 0)
683 fprintf (outfile, "_Noreturn ");
684 fprintf (outfile, "EXFUN (%s, ", globals[i].name);
685 if (globals[i].value == -1)
686 fprintf (outfile, "MANY");
687 else if (globals[i].value == -2)
688 fprintf (outfile, "UNEVALLED");
689 else
690 fprintf (outfile, "%d", globals[i].value);
691 fprintf (outfile, ");\n");
694 while (i + 1 < num_globals
695 && !strcmp (globals[i].name, globals[i + 1].name))
697 if (globals[i].type == FUNCTION
698 && globals[i].value != globals[i + 1].value)
699 error ("function '%s' defined twice with differing signatures",
700 globals[i].name);
701 ++i;
705 if (!seen_defun)
706 close_emacs_globals ();
710 /* Read through a c file. If a .o file is named,
711 the corresponding .c or .m file is read instead.
712 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
713 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
715 static int
716 scan_c_file (char *filename, const char *mode)
718 FILE *infile;
719 register int c;
720 register int commas;
721 int minargs, maxargs;
722 int extension = filename[strlen (filename) - 1];
724 if (extension == 'o')
725 filename[strlen (filename) - 1] = 'c';
727 infile = fopen (filename, mode);
729 if (infile == NULL && extension == 'o')
731 /* Try .m. */
732 filename[strlen (filename) - 1] = 'm';
733 infile = fopen (filename, mode);
734 if (infile == NULL)
735 filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */
738 /* No error if non-ex input file. */
739 if (infile == NULL)
741 perror (filename);
742 return 0;
745 /* Reset extension to be able to detect duplicate files. */
746 filename[strlen (filename) - 1] = extension;
748 c = '\n';
749 while (!feof (infile))
751 int doc_keyword = 0;
752 int defunflag = 0;
753 int defvarperbufferflag = 0;
754 int defvarflag = 0;
755 enum global_type type = INVALID;
756 char *name IF_LINT (= 0);
758 if (c != '\n' && c != '\r')
760 c = getc (infile);
761 continue;
763 c = getc (infile);
764 if (c == ' ')
766 while (c == ' ')
767 c = getc (infile);
768 if (c != 'D')
769 continue;
770 c = getc (infile);
771 if (c != 'E')
772 continue;
773 c = getc (infile);
774 if (c != 'F')
775 continue;
776 c = getc (infile);
777 if (c != 'V')
778 continue;
779 c = getc (infile);
780 if (c != 'A')
781 continue;
782 c = getc (infile);
783 if (c != 'R')
784 continue;
785 c = getc (infile);
786 if (c != '_')
787 continue;
789 defvarflag = 1;
791 c = getc (infile);
792 defvarperbufferflag = (c == 'P');
793 if (generate_globals)
795 if (c == 'I')
796 type = EMACS_INTEGER;
797 else if (c == 'L')
798 type = LISP_OBJECT;
799 else if (c == 'B')
800 type = BOOLEAN;
803 c = getc (infile);
804 /* We need to distinguish between DEFVAR_BOOL and
805 DEFVAR_BUFFER_DEFAULTS. */
806 if (generate_globals && type == BOOLEAN && c != 'O')
807 type = INVALID;
809 else if (c == 'D')
811 c = getc (infile);
812 if (c != 'E')
813 continue;
814 c = getc (infile);
815 if (c != 'F')
816 continue;
817 c = getc (infile);
818 defunflag = c == 'U';
820 else continue;
822 if (generate_globals
823 && (!defvarflag || defvarperbufferflag || type == INVALID)
824 && !defunflag)
825 continue;
827 while (c != '(')
829 if (c < 0)
830 goto eof;
831 c = getc (infile);
834 /* Lisp variable or function name. */
835 c = getc (infile);
836 if (c != '"')
837 continue;
838 c = read_c_string_or_comment (infile, -1, 0, 0);
840 if (generate_globals)
842 int i = 0;
844 /* Skip "," and whitespace. */
847 c = getc (infile);
849 while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
851 /* Read in the identifier. */
854 input_buffer[i++] = c;
855 c = getc (infile);
857 while (! (c == ',' || c == ' ' || c == '\t'
858 || c == '\n' || c == '\r'));
859 input_buffer[i] = '\0';
861 name = xmalloc (i + 1);
862 memcpy (name, input_buffer, i + 1);
864 if (!defunflag)
866 add_global (type, name, 0);
867 continue;
871 /* DEFVAR_LISP ("name", addr, "doc")
872 DEFVAR_LISP ("name", addr /\* doc *\/)
873 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
875 if (defunflag)
876 commas = generate_globals ? 4 : 5;
877 else if (defvarperbufferflag)
878 commas = 3;
879 else if (defvarflag)
880 commas = 1;
881 else /* For DEFSIMPLE and DEFPRED. */
882 commas = 2;
884 while (commas)
886 if (c == ',')
888 commas--;
890 if (defunflag && (commas == 1 || commas == 2))
892 int scanned = 0;
894 c = getc (infile);
895 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
896 if (c < 0)
897 goto eof;
898 ungetc (c, infile);
899 if (commas == 2) /* Pick up minargs. */
900 scanned = fscanf (infile, "%d", &minargs);
901 else /* Pick up maxargs. */
902 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
904 if (generate_globals)
905 maxargs = (c == 'M') ? -1 : -2;
906 else
907 maxargs = -1;
909 else
910 scanned = fscanf (infile, "%d", &maxargs);
911 if (scanned < 0)
912 goto eof;
916 if (c == EOF)
917 goto eof;
918 c = getc (infile);
921 if (generate_globals)
923 add_global (FUNCTION, name, maxargs);
924 continue;
927 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
928 c = getc (infile);
930 if (c == '"')
931 c = read_c_string_or_comment (infile, 0, 0, 0);
933 while (c != EOF && c != ',' && c != '/')
934 c = getc (infile);
935 if (c == ',')
937 c = getc (infile);
938 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
939 c = getc (infile);
940 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
941 c = getc (infile);
942 if (c == ':')
944 doc_keyword = 1;
945 c = getc (infile);
946 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
947 c = getc (infile);
951 if (c == '"'
952 || (c == '/'
953 && (c = getc (infile),
954 ungetc (c, infile),
955 c == '*')))
957 int comment = c != '"';
958 int saw_usage;
960 putc (037, outfile);
961 putc (defvarflag ? 'V' : 'F', outfile);
962 fprintf (outfile, "%s\n", input_buffer);
964 if (comment)
965 getc (infile); /* Skip past `*'. */
966 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
968 /* If this is a defun, find the arguments and print them. If
969 this function takes MANY or UNEVALLED args, then the C source
970 won't give the names of the arguments, so we shouldn't bother
971 trying to find them.
973 Various doc-string styles:
974 0: DEFUN (..., "DOC") (args) [!comment]
975 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
976 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
978 if (defunflag && maxargs != -1 && !saw_usage)
980 char argbuf[1024], *p = argbuf;
982 if (!comment || doc_keyword)
983 while (c != ')')
985 if (c < 0)
986 goto eof;
987 c = getc (infile);
990 /* Skip into arguments. */
991 while (c != '(')
993 if (c < 0)
994 goto eof;
995 c = getc (infile);
997 /* Copy arguments into ARGBUF. */
998 *p++ = c;
1000 *p++ = c = getc (infile);
1001 while (c != ')');
1002 *p = '\0';
1003 /* Output them. */
1004 fprintf (outfile, "\n\n");
1005 write_c_args (outfile, input_buffer, argbuf, minargs, maxargs);
1007 else if (defunflag && maxargs == -1 && !saw_usage)
1008 /* The DOC should provide the usage form. */
1009 fprintf (stderr, "Missing `usage' for function `%s'.\n",
1010 input_buffer);
1013 eof:
1014 fclose (infile);
1015 return 0;
1018 /* Read a file of Lisp code, compiled or interpreted.
1019 Looks for
1020 (defun NAME ARGS DOCSTRING ...)
1021 (defmacro NAME ARGS DOCSTRING ...)
1022 (defsubst NAME ARGS DOCSTRING ...)
1023 (autoload (quote NAME) FILE DOCSTRING ...)
1024 (defvar NAME VALUE DOCSTRING)
1025 (defconst NAME VALUE DOCSTRING)
1026 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
1027 (fset (quote NAME) #[... DOCSTRING ...])
1028 (defalias (quote NAME) #[... DOCSTRING ...])
1029 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
1030 starting in column zero.
1031 (quote NAME) may appear as 'NAME as well.
1033 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
1034 When we find that, we save it for the following defining-form,
1035 and we use that instead of reading a doc string within that defining-form.
1037 For defvar, defconst, and fset we skip to the docstring with a kludgy
1038 formatting convention: all docstrings must appear on the same line as the
1039 initial open-paren (the one in column zero) and must contain a backslash
1040 and a newline immediately after the initial double-quote. No newlines
1041 must appear between the beginning of the form and the first double-quote.
1042 For defun, defmacro, and autoload, we know how to skip over the
1043 arglist, but the doc string must still have a backslash and newline
1044 immediately after the double quote.
1045 The only source files that must follow this convention are preloaded
1046 uncompiled ones like loaddefs.el and bindings.el; aside
1047 from that, it is always the .elc file that we look at, and they are no
1048 problem because byte-compiler output follows this convention.
1049 The NAME and DOCSTRING are output.
1050 NAME is preceded by `F' for a function or `V' for a variable.
1051 An entry is output only if DOCSTRING has \ newline just after the opening ".
1054 static void
1055 skip_white (FILE *infile)
1057 char c = ' ';
1058 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
1059 c = getc (infile);
1060 ungetc (c, infile);
1063 static void
1064 read_lisp_symbol (FILE *infile, char *buffer)
1066 char c;
1067 char *fillp = buffer;
1069 skip_white (infile);
1070 while (1)
1072 c = getc (infile);
1073 if (c == '\\')
1074 *(++fillp) = getc (infile);
1075 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
1077 ungetc (c, infile);
1078 *fillp = 0;
1079 break;
1081 else
1082 *fillp++ = c;
1085 if (! buffer[0])
1086 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
1088 skip_white (infile);
1091 static int
1092 search_lisp_doc_at_eol (FILE *infile)
1094 char c = 0, c1 = 0, c2 = 0;
1096 /* Skip until the end of line; remember two previous chars. */
1097 while (c != '\n' && c != '\r' && c != EOF)
1099 c2 = c1;
1100 c1 = c;
1101 c = getc (infile);
1104 /* If two previous characters were " and \,
1105 this is a doc string. Otherwise, there is none. */
1106 if (c2 != '"' || c1 != '\\')
1108 #ifdef DEBUG
1109 fprintf (stderr, "## non-docstring in %s (%s)\n",
1110 buffer, filename);
1111 #endif
1112 if (c != EOF)
1113 ungetc (c, infile);
1114 return 0;
1116 return 1;
1119 static int
1120 scan_lisp_file (const char *filename, const char *mode)
1122 FILE *infile;
1123 register int c;
1124 char *saved_string = 0;
1126 if (generate_globals)
1127 fatal ("scanning lisp file when -g specified", 0);
1129 infile = fopen (filename, mode);
1130 if (infile == NULL)
1132 perror (filename);
1133 return 0; /* No error. */
1136 c = '\n';
1137 while (!feof (infile))
1139 char buffer[BUFSIZ];
1140 char type;
1142 /* If not at end of line, skip till we get to one. */
1143 if (c != '\n' && c != '\r')
1145 c = getc (infile);
1146 continue;
1148 /* Skip the line break. */
1149 while (c == '\n' || c == '\r')
1150 c = getc (infile);
1151 /* Detect a dynamic doc string and save it for the next expression. */
1152 if (c == '#')
1154 c = getc (infile);
1155 if (c == '@')
1157 size_t length = 0;
1158 size_t i;
1160 /* Read the length. */
1161 while ((c = getc (infile),
1162 c >= '0' && c <= '9'))
1164 length *= 10;
1165 length += c - '0';
1168 if (length <= 1)
1169 fatal ("invalid dynamic doc string length", "");
1171 if (c != ' ')
1172 fatal ("space not found after dynamic doc string length", "");
1174 /* The next character is a space that is counted in the length
1175 but not part of the doc string.
1176 We already read it, so just ignore it. */
1177 length--;
1179 /* Read in the contents. */
1180 free (saved_string);
1181 saved_string = (char *) xmalloc (length);
1182 for (i = 0; i < length; i++)
1183 saved_string[i] = getc (infile);
1184 /* The last character is a ^_.
1185 That is needed in the .elc file
1186 but it is redundant in DOC. So get rid of it here. */
1187 saved_string[length - 1] = 0;
1188 /* Skip the line break. */
1189 while (c == '\n' || c == '\r')
1190 c = getc (infile);
1191 /* Skip the following line. */
1192 while (c != '\n' && c != '\r')
1193 c = getc (infile);
1195 continue;
1198 if (c != '(')
1199 continue;
1201 read_lisp_symbol (infile, buffer);
1203 if (! strcmp (buffer, "defun")
1204 || ! strcmp (buffer, "defmacro")
1205 || ! strcmp (buffer, "defsubst"))
1207 type = 'F';
1208 read_lisp_symbol (infile, buffer);
1210 /* Skip the arguments: either "nil" or a list in parens. */
1212 c = getc (infile);
1213 if (c == 'n') /* nil */
1215 if ((c = getc (infile)) != 'i'
1216 || (c = getc (infile)) != 'l')
1218 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1219 buffer, filename);
1220 continue;
1223 else if (c != '(')
1225 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1226 buffer, filename);
1227 continue;
1229 else
1230 while (c != ')')
1231 c = getc (infile);
1232 skip_white (infile);
1234 /* If the next three characters aren't `dquote bslash newline'
1235 then we're not reading a docstring.
1237 if ((c = getc (infile)) != '"'
1238 || (c = getc (infile)) != '\\'
1239 || ((c = getc (infile)) != '\n' && c != '\r'))
1241 #ifdef DEBUG
1242 fprintf (stderr, "## non-docstring in %s (%s)\n",
1243 buffer, filename);
1244 #endif
1245 continue;
1249 /* defcustom can only occur in uncompiled Lisp files. */
1250 else if (! strcmp (buffer, "defvar")
1251 || ! strcmp (buffer, "defconst")
1252 || ! strcmp (buffer, "defcustom"))
1254 type = 'V';
1255 read_lisp_symbol (infile, buffer);
1257 if (saved_string == 0)
1258 if (!search_lisp_doc_at_eol (infile))
1259 continue;
1262 else if (! strcmp (buffer, "custom-declare-variable")
1263 || ! strcmp (buffer, "defvaralias")
1266 type = 'V';
1268 c = getc (infile);
1269 if (c == '\'')
1270 read_lisp_symbol (infile, buffer);
1271 else
1273 if (c != '(')
1275 fprintf (stderr,
1276 "## unparsable name in custom-declare-variable in %s\n",
1277 filename);
1278 continue;
1280 read_lisp_symbol (infile, buffer);
1281 if (strcmp (buffer, "quote"))
1283 fprintf (stderr,
1284 "## unparsable name in custom-declare-variable in %s\n",
1285 filename);
1286 continue;
1288 read_lisp_symbol (infile, buffer);
1289 c = getc (infile);
1290 if (c != ')')
1292 fprintf (stderr,
1293 "## unparsable quoted name in custom-declare-variable in %s\n",
1294 filename);
1295 continue;
1299 if (saved_string == 0)
1300 if (!search_lisp_doc_at_eol (infile))
1301 continue;
1304 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1306 type = 'F';
1308 c = getc (infile);
1309 if (c == '\'')
1310 read_lisp_symbol (infile, buffer);
1311 else
1313 if (c != '(')
1315 fprintf (stderr, "## unparsable name in fset in %s\n",
1316 filename);
1317 continue;
1319 read_lisp_symbol (infile, buffer);
1320 if (strcmp (buffer, "quote"))
1322 fprintf (stderr, "## unparsable name in fset in %s\n",
1323 filename);
1324 continue;
1326 read_lisp_symbol (infile, buffer);
1327 c = getc (infile);
1328 if (c != ')')
1330 fprintf (stderr,
1331 "## unparsable quoted name in fset in %s\n",
1332 filename);
1333 continue;
1337 if (saved_string == 0)
1338 if (!search_lisp_doc_at_eol (infile))
1339 continue;
1342 else if (! strcmp (buffer, "autoload"))
1344 type = 'F';
1345 c = getc (infile);
1346 if (c == '\'')
1347 read_lisp_symbol (infile, buffer);
1348 else
1350 if (c != '(')
1352 fprintf (stderr, "## unparsable name in autoload in %s\n",
1353 filename);
1354 continue;
1356 read_lisp_symbol (infile, buffer);
1357 if (strcmp (buffer, "quote"))
1359 fprintf (stderr, "## unparsable name in autoload in %s\n",
1360 filename);
1361 continue;
1363 read_lisp_symbol (infile, buffer);
1364 c = getc (infile);
1365 if (c != ')')
1367 fprintf (stderr,
1368 "## unparsable quoted name in autoload in %s\n",
1369 filename);
1370 continue;
1373 skip_white (infile);
1374 if ((c = getc (infile)) != '\"')
1376 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1377 buffer, filename);
1378 continue;
1380 read_c_string_or_comment (infile, 0, 0, 0);
1382 if (saved_string == 0)
1383 if (!search_lisp_doc_at_eol (infile))
1384 continue;
1387 #ifdef DEBUG
1388 else if (! strcmp (buffer, "if")
1389 || ! strcmp (buffer, "byte-code"))
1390 continue;
1391 #endif
1393 else
1395 #ifdef DEBUG
1396 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1397 buffer, filename);
1398 #endif
1399 continue;
1402 /* At this point, we should either use the previous dynamic doc string in
1403 saved_string or gobble a doc string from the input file.
1404 In the latter case, the opening quote (and leading backslash-newline)
1405 have already been read. */
1407 putc (037, outfile);
1408 putc (type, outfile);
1409 fprintf (outfile, "%s\n", buffer);
1410 if (saved_string)
1412 fputs (saved_string, outfile);
1413 /* Don't use one dynamic doc string twice. */
1414 free (saved_string);
1415 saved_string = 0;
1417 else
1418 read_c_string_or_comment (infile, 1, 0, 0);
1420 fclose (infile);
1421 return 0;
1425 /* make-docfile.c ends here */