A few more naming-convention fixes for getters and setters.
[emacs.git] / lib-src / make-docfile.c
blob2654387fb37b18a9318d07d443ff0b86fc00818e
1 /* Generate doc-string file for GNU Emacs from source files.
3 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2012
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 #include <stdio.h>
40 #include <stdlib.h> /* config.h unconditionally includes this anyway */
41 #ifdef MSDOS
42 #include <fcntl.h>
43 #endif /* MSDOS */
44 #ifdef WINDOWSNT
45 /* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
46 is really just insurance. */
47 #undef fopen
48 #include <fcntl.h>
49 #include <direct.h>
50 #endif /* WINDOWSNT */
52 #ifdef DOS_NT
53 /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
54 is really just insurance.
56 Similarly, msdos defines this as sys_chdir, but we're not linking with the
57 file where that function is defined. */
58 #undef chdir
59 #define READ_TEXT "rt"
60 #define READ_BINARY "rb"
61 #else /* not DOS_NT */
62 #define READ_TEXT "r"
63 #define READ_BINARY "r"
64 #endif /* not DOS_NT */
66 static int scan_file (char *filename);
67 static int scan_lisp_file (const char *filename, const char *mode);
68 static int scan_c_file (char *filename, const char *mode);
69 static void start_globals (void);
70 static void write_globals (void);
72 #include <unistd.h>
74 /* Stdio stream for output to the DOC file. */
75 FILE *outfile;
77 /* Name this program was invoked with. */
78 char *progname;
80 /* Nonzero if this invocation is generating globals.h. */
81 int generate_globals;
83 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
85 /* VARARGS1 */
86 static void
87 error (const char *s1, const char *s2)
89 fprintf (stderr, "%s: ", progname);
90 fprintf (stderr, s1, s2);
91 fprintf (stderr, "\n");
94 /* Print error message and exit. */
96 /* VARARGS1 */
97 static _Noreturn void
98 fatal (const char *s1, const char *s2)
100 error (s1, s2);
101 exit (EXIT_FAILURE);
104 /* Like malloc but get fatal error if memory is exhausted. */
106 static void *
107 xmalloc (unsigned int size)
109 void *result = (void *) malloc (size);
110 if (result == NULL)
111 fatal ("virtual memory exhausted", 0);
112 return result;
115 /* Like realloc but get fatal error if memory is exhausted. */
117 static void *
118 xrealloc (void *arg, unsigned int size)
120 void *result = (void *) realloc (arg, size);
121 if (result == NULL)
122 fatal ("virtual memory exhausted", 0);
123 return result;
128 main (int argc, char **argv)
130 int i;
131 int err_count = 0;
132 int first_infile;
134 progname = argv[0];
136 outfile = stdout;
138 /* Don't put CRs in the DOC file. */
139 #ifdef MSDOS
140 _fmode = O_BINARY;
141 #if 0 /* Suspicion is that this causes hanging.
142 So instead we require people to use -o on MSDOS. */
143 (stdout)->_flag &= ~_IOTEXT;
144 _setmode (fileno (stdout), O_BINARY);
145 #endif
146 outfile = 0;
147 #endif /* MSDOS */
148 #ifdef WINDOWSNT
149 _fmode = O_BINARY;
150 _setmode (fileno (stdout), O_BINARY);
151 #endif /* WINDOWSNT */
153 /* If first two args are -o FILE, output to FILE. */
154 i = 1;
155 if (argc > i + 1 && !strcmp (argv[i], "-o"))
157 outfile = fopen (argv[i + 1], "w");
158 i += 2;
160 if (argc > i + 1 && !strcmp (argv[i], "-a"))
162 outfile = fopen (argv[i + 1], "a");
163 i += 2;
165 if (argc > i + 1 && !strcmp (argv[i], "-d"))
167 if (chdir (argv[i + 1]) != 0)
169 perror (argv[i + 1]);
170 return EXIT_FAILURE;
172 i += 2;
174 if (argc > i && !strcmp (argv[i], "-g"))
176 generate_globals = 1;
177 ++i;
180 if (outfile == 0)
181 fatal ("No output file specified", "");
183 if (generate_globals)
184 start_globals ();
186 first_infile = i;
187 for (; i < argc; i++)
189 int j;
190 /* Don't process one file twice. */
191 for (j = first_infile; j < i; j++)
192 if (! strcmp (argv[i], argv[j]))
193 break;
194 if (j == i)
195 err_count += scan_file (argv[i]);
198 if (err_count == 0 && generate_globals)
199 write_globals ();
201 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
204 /* Add a source file name boundary marker in the output file. */
205 static void
206 put_filename (char *filename)
208 char *tmp;
210 for (tmp = filename; *tmp; tmp++)
212 if (IS_DIRECTORY_SEP (*tmp))
213 filename = tmp + 1;
216 putc (037, outfile);
217 putc ('S', outfile);
218 fprintf (outfile, "%s\n", filename);
221 /* Read file FILENAME and output its doc strings to outfile. */
222 /* Return 1 if file is not found, 0 if it is found. */
224 static int
225 scan_file (char *filename)
228 size_t len = strlen (filename);
230 if (!generate_globals)
231 put_filename (filename);
232 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
233 return scan_lisp_file (filename, READ_BINARY);
234 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
235 return scan_lisp_file (filename, READ_TEXT);
236 else
237 return scan_c_file (filename, READ_TEXT);
240 static void
241 start_globals (void)
243 fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n");
244 fprintf (outfile, "/* DO NOT EDIT. */\n");
245 fprintf (outfile, "struct emacs_globals {\n");
248 static char input_buffer[128];
250 /* Some state during the execution of `read_c_string_or_comment'. */
251 struct rcsoc_state
253 /* A count of spaces and newlines that have been read, but not output. */
254 unsigned pending_spaces, pending_newlines;
256 /* Where we're reading from. */
257 FILE *in_file;
259 /* If non-zero, a buffer into which to copy characters. */
260 char *buf_ptr;
261 /* If non-zero, a file into which to copy characters. */
262 FILE *out_file;
264 /* A keyword we look for at the beginning of lines. If found, it is
265 not copied, and SAW_KEYWORD is set to true. */
266 const char *keyword;
267 /* The current point we've reached in an occurrence of KEYWORD in
268 the input stream. */
269 const char *cur_keyword_ptr;
270 /* Set to true if we saw an occurrence of KEYWORD. */
271 int saw_keyword;
274 /* Output CH to the file or buffer in STATE. Any pending newlines or
275 spaces are output first. */
277 static inline void
278 put_char (int ch, struct rcsoc_state *state)
280 int out_ch;
283 if (state->pending_newlines > 0)
285 state->pending_newlines--;
286 out_ch = '\n';
288 else if (state->pending_spaces > 0)
290 state->pending_spaces--;
291 out_ch = ' ';
293 else
294 out_ch = ch;
296 if (state->out_file)
297 putc (out_ch, state->out_file);
298 if (state->buf_ptr)
299 *state->buf_ptr++ = out_ch;
301 while (out_ch != ch);
304 /* If in the middle of scanning a keyword, continue scanning with
305 character CH, otherwise output CH to the file or buffer in STATE.
306 Any pending newlines or spaces are output first, as well as any
307 previously scanned characters that were thought to be part of a
308 keyword, but were in fact not. */
310 static void
311 scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
313 if (state->keyword
314 && *state->cur_keyword_ptr == ch
315 && (state->cur_keyword_ptr > state->keyword
316 || state->pending_newlines > 0))
317 /* We might be looking at STATE->keyword at some point.
318 Keep looking until we know for sure. */
320 if (*++state->cur_keyword_ptr == '\0')
321 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
323 state->saw_keyword = 1;
325 /* Reset the scanning pointer. */
326 state->cur_keyword_ptr = state->keyword;
328 /* Canonicalize whitespace preceding a usage string. */
329 state->pending_newlines = 2;
330 state->pending_spaces = 0;
332 /* Skip any whitespace between the keyword and the
333 usage string. */
335 ch = getc (state->in_file);
336 while (ch == ' ' || ch == '\n');
338 /* Output the open-paren we just read. */
339 put_char (ch, state);
341 /* Skip the function name and replace it with `fn'. */
343 ch = getc (state->in_file);
344 while (ch != ' ' && ch != ')');
345 put_char ('f', state);
346 put_char ('n', state);
348 /* Put back the last character. */
349 ungetc (ch, state->in_file);
352 else
354 if (state->keyword && state->cur_keyword_ptr > state->keyword)
355 /* We scanned the beginning of a potential usage
356 keyword, but it was a false alarm. Output the
357 part we scanned. */
359 const char *p;
361 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
362 put_char (*p, state);
364 state->cur_keyword_ptr = state->keyword;
367 put_char (ch, state);
372 /* Skip a C string or C-style comment from INFILE, and return the
373 character that follows. COMMENT non-zero means skip a comment. If
374 PRINTFLAG is positive, output string contents to outfile. If it is
375 negative, store contents in buf. Convert escape sequences \n and
376 \t to newline and tab; discard \ followed by newline.
377 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
378 at the beginning of a line will be removed, and *SAW_USAGE set to
379 true if any were encountered. */
381 static int
382 read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
384 register int c;
385 struct rcsoc_state state;
387 state.in_file = infile;
388 state.buf_ptr = (printflag < 0 ? input_buffer : 0);
389 state.out_file = (printflag > 0 ? outfile : 0);
390 state.pending_spaces = 0;
391 state.pending_newlines = 0;
392 state.keyword = (saw_usage ? "usage:" : 0);
393 state.cur_keyword_ptr = state.keyword;
394 state.saw_keyword = 0;
396 c = getc (infile);
397 if (comment)
398 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
399 c = getc (infile);
401 while (c != EOF)
403 while (c != EOF && (comment ? c != '*' : c != '"'))
405 if (c == '\\')
407 c = getc (infile);
408 if (c == '\n' || c == '\r')
410 c = getc (infile);
411 continue;
413 if (c == 'n')
414 c = '\n';
415 if (c == 't')
416 c = '\t';
419 if (c == ' ')
420 state.pending_spaces++;
421 else if (c == '\n')
423 state.pending_newlines++;
424 state.pending_spaces = 0;
426 else
427 scan_keyword_or_put_char (c, &state);
429 c = getc (infile);
432 if (c != EOF)
433 c = getc (infile);
435 if (comment)
437 if (c == '/')
439 c = getc (infile);
440 break;
443 scan_keyword_or_put_char ('*', &state);
445 else
447 if (c != '"')
448 break;
450 /* If we had a "", concatenate the two strings. */
451 c = getc (infile);
455 if (printflag < 0)
456 *state.buf_ptr = 0;
458 if (saw_usage)
459 *saw_usage = state.saw_keyword;
461 return c;
466 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
467 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
469 static void
470 write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
472 register char *p;
473 int in_ident = 0;
474 char *ident_start IF_LINT (= NULL);
475 size_t ident_length = 0;
477 fprintf (out, "(fn");
479 if (*buf == '(')
480 ++buf;
482 for (p = buf; *p; p++)
484 char c = *p;
486 /* Notice when a new identifier starts. */
487 if ((('A' <= c && c <= 'Z')
488 || ('a' <= c && c <= 'z')
489 || ('0' <= c && c <= '9')
490 || c == '_')
491 != in_ident)
493 if (!in_ident)
495 in_ident = 1;
496 ident_start = p;
498 else
500 in_ident = 0;
501 ident_length = p - ident_start;
505 /* Found the end of an argument, write out the last seen
506 identifier. */
507 if (c == ',' || c == ')')
509 if (ident_length == 0)
511 error ("empty arg list for `%s' should be (void), not ()", func);
512 continue;
515 if (strncmp (ident_start, "void", ident_length) == 0)
516 continue;
518 putc (' ', out);
520 if (minargs == 0 && maxargs > 0)
521 fprintf (out, "&optional ");
523 minargs--;
524 maxargs--;
526 /* In C code, `default' is a reserved word, so we spell it
527 `defalt'; demangle that here. */
528 if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0)
529 fprintf (out, "DEFAULT");
530 else
531 while (ident_length-- > 0)
533 c = *ident_start++;
534 if (c >= 'a' && c <= 'z')
535 /* Upcase the letter. */
536 c += 'A' - 'a';
537 else if (c == '_')
538 /* Print underscore as hyphen. */
539 c = '-';
540 putc (c, out);
545 putc (')', out);
548 /* The types of globals. These are sorted roughly in decreasing alignment
549 order to avoid allocation gaps, except that functions are last. */
550 enum global_type
552 INVALID,
553 LISP_OBJECT,
554 EMACS_INTEGER,
555 BOOLEAN,
556 FUNCTION,
559 /* A single global. */
560 struct global
562 enum global_type type;
563 char *name;
564 int value;
567 /* All the variable names we saw while scanning C sources in `-g'
568 mode. */
569 int num_globals;
570 int num_globals_allocated;
571 struct global *globals;
573 static void
574 add_global (enum global_type type, char *name, int value)
576 /* Ignore the one non-symbol that can occur. */
577 if (strcmp (name, "..."))
579 ++num_globals;
581 if (num_globals_allocated == 0)
583 num_globals_allocated = 100;
584 globals = xmalloc (num_globals_allocated * sizeof (struct global));
586 else if (num_globals == num_globals_allocated)
588 num_globals_allocated *= 2;
589 globals = xrealloc (globals,
590 num_globals_allocated * sizeof (struct global));
593 globals[num_globals - 1].type = type;
594 globals[num_globals - 1].name = name;
595 globals[num_globals - 1].value = value;
599 static int
600 compare_globals (const void *a, const void *b)
602 const struct global *ga = a;
603 const struct global *gb = b;
605 if (ga->type != gb->type)
606 return ga->type - gb->type;
608 return strcmp (ga->name, gb->name);
611 static void
612 close_emacs_globals (void)
614 fprintf (outfile, "};\n");
615 fprintf (outfile, "extern struct emacs_globals globals;\n");
618 static void
619 write_globals (void)
621 int i, seen_defun = 0;
622 qsort (globals, num_globals, sizeof (struct global), compare_globals);
623 for (i = 0; i < num_globals; ++i)
625 char const *type;
627 switch (globals[i].type)
629 case EMACS_INTEGER:
630 type = "EMACS_INT";
631 break;
632 case BOOLEAN:
633 type = "bool";
634 break;
635 case LISP_OBJECT:
636 type = "Lisp_Object";
637 break;
638 case FUNCTION:
639 if (!seen_defun)
641 close_emacs_globals ();
642 fprintf (outfile, "\n");
643 seen_defun = 1;
645 break;
646 default:
647 fatal ("not a recognized DEFVAR_", 0);
650 if (globals[i].type != FUNCTION)
652 fprintf (outfile, " %s f_%s;\n", type, globals[i].name);
653 fprintf (outfile, "#define %s globals.f_%s\n",
654 globals[i].name, globals[i].name);
656 else
658 /* It would be nice to have a cleaner way to deal with these
659 special hacks. */
660 if (strcmp (globals[i].name, "Fthrow") == 0
661 || strcmp (globals[i].name, "Ftop_level") == 0
662 || strcmp (globals[i].name, "Fkill_emacs") == 0)
663 fprintf (outfile, "_Noreturn ");
664 fprintf (outfile, "EXFUN (%s, ", globals[i].name);
665 if (globals[i].value == -1)
666 fprintf (outfile, "MANY");
667 else if (globals[i].value == -2)
668 fprintf (outfile, "UNEVALLED");
669 else
670 fprintf (outfile, "%d", globals[i].value);
671 fprintf (outfile, ");\n");
674 while (i + 1 < num_globals
675 && !strcmp (globals[i].name, globals[i + 1].name))
677 if (globals[i].type == FUNCTION
678 && globals[i].value != globals[i + 1].value)
679 error ("function '%s' defined twice with differing signatures",
680 globals[i].name);
681 ++i;
685 if (!seen_defun)
686 close_emacs_globals ();
690 /* Read through a c file. If a .o file is named,
691 the corresponding .c or .m file is read instead.
692 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
693 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
695 static int
696 scan_c_file (char *filename, const char *mode)
698 FILE *infile;
699 register int c;
700 register int commas;
701 int minargs, maxargs;
702 int extension = filename[strlen (filename) - 1];
704 if (extension == 'o')
705 filename[strlen (filename) - 1] = 'c';
707 infile = fopen (filename, mode);
709 if (infile == NULL && extension == 'o')
711 /* Try .m. */
712 filename[strlen (filename) - 1] = 'm';
713 infile = fopen (filename, mode);
714 if (infile == NULL)
715 filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */
718 /* No error if non-ex input file. */
719 if (infile == NULL)
721 perror (filename);
722 return 0;
725 /* Reset extension to be able to detect duplicate files. */
726 filename[strlen (filename) - 1] = extension;
728 c = '\n';
729 while (!feof (infile))
731 int doc_keyword = 0;
732 int defunflag = 0;
733 int defvarperbufferflag = 0;
734 int defvarflag = 0;
735 enum global_type type = INVALID;
736 char *name IF_LINT (= 0);
738 if (c != '\n' && c != '\r')
740 c = getc (infile);
741 continue;
743 c = getc (infile);
744 if (c == ' ')
746 while (c == ' ')
747 c = getc (infile);
748 if (c != 'D')
749 continue;
750 c = getc (infile);
751 if (c != 'E')
752 continue;
753 c = getc (infile);
754 if (c != 'F')
755 continue;
756 c = getc (infile);
757 if (c != 'V')
758 continue;
759 c = getc (infile);
760 if (c != 'A')
761 continue;
762 c = getc (infile);
763 if (c != 'R')
764 continue;
765 c = getc (infile);
766 if (c != '_')
767 continue;
769 defvarflag = 1;
771 c = getc (infile);
772 defvarperbufferflag = (c == 'P');
773 if (generate_globals)
775 if (c == 'I')
776 type = EMACS_INTEGER;
777 else if (c == 'L')
778 type = LISP_OBJECT;
779 else if (c == 'B')
780 type = BOOLEAN;
783 c = getc (infile);
784 /* We need to distinguish between DEFVAR_BOOL and
785 DEFVAR_BUFFER_DEFAULTS. */
786 if (generate_globals && type == BOOLEAN && c != 'O')
787 type = INVALID;
789 else if (c == 'D')
791 c = getc (infile);
792 if (c != 'E')
793 continue;
794 c = getc (infile);
795 if (c != 'F')
796 continue;
797 c = getc (infile);
798 defunflag = c == 'U';
800 else continue;
802 if (generate_globals
803 && (!defvarflag || defvarperbufferflag || type == INVALID)
804 && !defunflag)
805 continue;
807 while (c != '(')
809 if (c < 0)
810 goto eof;
811 c = getc (infile);
814 /* Lisp variable or function name. */
815 c = getc (infile);
816 if (c != '"')
817 continue;
818 c = read_c_string_or_comment (infile, -1, 0, 0);
820 if (generate_globals)
822 int i = 0;
824 /* Skip "," and whitespace. */
827 c = getc (infile);
829 while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
831 /* Read in the identifier. */
834 input_buffer[i++] = c;
835 c = getc (infile);
837 while (! (c == ',' || c == ' ' || c == '\t'
838 || c == '\n' || c == '\r'));
839 input_buffer[i] = '\0';
841 name = xmalloc (i + 1);
842 memcpy (name, input_buffer, i + 1);
844 if (!defunflag)
846 add_global (type, name, 0);
847 continue;
851 /* DEFVAR_LISP ("name", addr, "doc")
852 DEFVAR_LISP ("name", addr /\* doc *\/)
853 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
855 if (defunflag)
856 commas = generate_globals ? 4 : 5;
857 else if (defvarperbufferflag)
858 commas = 3;
859 else if (defvarflag)
860 commas = 1;
861 else /* For DEFSIMPLE and DEFPRED. */
862 commas = 2;
864 while (commas)
866 if (c == ',')
868 commas--;
870 if (defunflag && (commas == 1 || commas == 2))
872 int scanned = 0;
874 c = getc (infile);
875 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
876 if (c < 0)
877 goto eof;
878 ungetc (c, infile);
879 if (commas == 2) /* Pick up minargs. */
880 scanned = fscanf (infile, "%d", &minargs);
881 else /* Pick up maxargs. */
882 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
884 if (generate_globals)
885 maxargs = (c == 'M') ? -1 : -2;
886 else
887 maxargs = -1;
889 else
890 scanned = fscanf (infile, "%d", &maxargs);
891 if (scanned < 0)
892 goto eof;
896 if (c == EOF)
897 goto eof;
898 c = getc (infile);
901 if (generate_globals)
903 add_global (FUNCTION, name, maxargs);
904 continue;
907 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
908 c = getc (infile);
910 if (c == '"')
911 c = read_c_string_or_comment (infile, 0, 0, 0);
913 while (c != EOF && c != ',' && c != '/')
914 c = getc (infile);
915 if (c == ',')
917 c = getc (infile);
918 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
919 c = getc (infile);
920 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
921 c = getc (infile);
922 if (c == ':')
924 doc_keyword = 1;
925 c = getc (infile);
926 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
927 c = getc (infile);
931 if (c == '"'
932 || (c == '/'
933 && (c = getc (infile),
934 ungetc (c, infile),
935 c == '*')))
937 int comment = c != '"';
938 int saw_usage;
940 putc (037, outfile);
941 putc (defvarflag ? 'V' : 'F', outfile);
942 fprintf (outfile, "%s\n", input_buffer);
944 if (comment)
945 getc (infile); /* Skip past `*'. */
946 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
948 /* If this is a defun, find the arguments and print them. If
949 this function takes MANY or UNEVALLED args, then the C source
950 won't give the names of the arguments, so we shouldn't bother
951 trying to find them.
953 Various doc-string styles:
954 0: DEFUN (..., "DOC") (args) [!comment]
955 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
956 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
958 if (defunflag && maxargs != -1 && !saw_usage)
960 char argbuf[1024], *p = argbuf;
962 if (!comment || doc_keyword)
963 while (c != ')')
965 if (c < 0)
966 goto eof;
967 c = getc (infile);
970 /* Skip into arguments. */
971 while (c != '(')
973 if (c < 0)
974 goto eof;
975 c = getc (infile);
977 /* Copy arguments into ARGBUF. */
978 *p++ = c;
980 *p++ = c = getc (infile);
981 while (c != ')');
982 *p = '\0';
983 /* Output them. */
984 fprintf (outfile, "\n\n");
985 write_c_args (outfile, input_buffer, argbuf, minargs, maxargs);
987 else if (defunflag && maxargs == -1 && !saw_usage)
988 /* The DOC should provide the usage form. */
989 fprintf (stderr, "Missing `usage' for function `%s'.\n",
990 input_buffer);
993 eof:
994 fclose (infile);
995 return 0;
998 /* Read a file of Lisp code, compiled or interpreted.
999 Looks for
1000 (defun NAME ARGS DOCSTRING ...)
1001 (defmacro NAME ARGS DOCSTRING ...)
1002 (defsubst NAME ARGS DOCSTRING ...)
1003 (autoload (quote NAME) FILE DOCSTRING ...)
1004 (defvar NAME VALUE DOCSTRING)
1005 (defconst NAME VALUE DOCSTRING)
1006 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
1007 (fset (quote NAME) #[... DOCSTRING ...])
1008 (defalias (quote NAME) #[... DOCSTRING ...])
1009 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
1010 starting in column zero.
1011 (quote NAME) may appear as 'NAME as well.
1013 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
1014 When we find that, we save it for the following defining-form,
1015 and we use that instead of reading a doc string within that defining-form.
1017 For defvar, defconst, and fset we skip to the docstring with a kludgy
1018 formatting convention: all docstrings must appear on the same line as the
1019 initial open-paren (the one in column zero) and must contain a backslash
1020 and a newline immediately after the initial double-quote. No newlines
1021 must appear between the beginning of the form and the first double-quote.
1022 For defun, defmacro, and autoload, we know how to skip over the
1023 arglist, but the doc string must still have a backslash and newline
1024 immediately after the double quote.
1025 The only source files that must follow this convention are preloaded
1026 uncompiled ones like loaddefs.el and bindings.el; aside
1027 from that, it is always the .elc file that we look at, and they are no
1028 problem because byte-compiler output follows this convention.
1029 The NAME and DOCSTRING are output.
1030 NAME is preceded by `F' for a function or `V' for a variable.
1031 An entry is output only if DOCSTRING has \ newline just after the opening ".
1034 static void
1035 skip_white (FILE *infile)
1037 char c = ' ';
1038 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
1039 c = getc (infile);
1040 ungetc (c, infile);
1043 static void
1044 read_lisp_symbol (FILE *infile, char *buffer)
1046 char c;
1047 char *fillp = buffer;
1049 skip_white (infile);
1050 while (1)
1052 c = getc (infile);
1053 if (c == '\\')
1054 *(++fillp) = getc (infile);
1055 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
1057 ungetc (c, infile);
1058 *fillp = 0;
1059 break;
1061 else
1062 *fillp++ = c;
1065 if (! buffer[0])
1066 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
1068 skip_white (infile);
1071 static int
1072 search_lisp_doc_at_eol (FILE *infile)
1074 char c = 0, c1 = 0, c2 = 0;
1076 /* Skip until the end of line; remember two previous chars. */
1077 while (c != '\n' && c != '\r' && c != EOF)
1079 c2 = c1;
1080 c1 = c;
1081 c = getc (infile);
1084 /* If two previous characters were " and \,
1085 this is a doc string. Otherwise, there is none. */
1086 if (c2 != '"' || c1 != '\\')
1088 #ifdef DEBUG
1089 fprintf (stderr, "## non-docstring in %s (%s)\n",
1090 buffer, filename);
1091 #endif
1092 if (c != EOF)
1093 ungetc (c, infile);
1094 return 0;
1096 return 1;
1099 static int
1100 scan_lisp_file (const char *filename, const char *mode)
1102 FILE *infile;
1103 register int c;
1104 char *saved_string = 0;
1106 if (generate_globals)
1107 fatal ("scanning lisp file when -g specified", 0);
1109 infile = fopen (filename, mode);
1110 if (infile == NULL)
1112 perror (filename);
1113 return 0; /* No error. */
1116 c = '\n';
1117 while (!feof (infile))
1119 char buffer[BUFSIZ];
1120 char type;
1122 /* If not at end of line, skip till we get to one. */
1123 if (c != '\n' && c != '\r')
1125 c = getc (infile);
1126 continue;
1128 /* Skip the line break. */
1129 while (c == '\n' || c == '\r')
1130 c = getc (infile);
1131 /* Detect a dynamic doc string and save it for the next expression. */
1132 if (c == '#')
1134 c = getc (infile);
1135 if (c == '@')
1137 size_t length = 0;
1138 size_t i;
1140 /* Read the length. */
1141 while ((c = getc (infile),
1142 c >= '0' && c <= '9'))
1144 length *= 10;
1145 length += c - '0';
1148 if (length <= 1)
1149 fatal ("invalid dynamic doc string length", "");
1151 if (c != ' ')
1152 fatal ("space not found after dynamic doc string length", "");
1154 /* The next character is a space that is counted in the length
1155 but not part of the doc string.
1156 We already read it, so just ignore it. */
1157 length--;
1159 /* Read in the contents. */
1160 free (saved_string);
1161 saved_string = (char *) xmalloc (length);
1162 for (i = 0; i < length; i++)
1163 saved_string[i] = getc (infile);
1164 /* The last character is a ^_.
1165 That is needed in the .elc file
1166 but it is redundant in DOC. So get rid of it here. */
1167 saved_string[length - 1] = 0;
1168 /* Skip the line break. */
1169 while (c == '\n' || c == '\r')
1170 c = getc (infile);
1171 /* Skip the following line. */
1172 while (c != '\n' && c != '\r')
1173 c = getc (infile);
1175 continue;
1178 if (c != '(')
1179 continue;
1181 read_lisp_symbol (infile, buffer);
1183 if (! strcmp (buffer, "defun")
1184 || ! strcmp (buffer, "defmacro")
1185 || ! strcmp (buffer, "defsubst"))
1187 type = 'F';
1188 read_lisp_symbol (infile, buffer);
1190 /* Skip the arguments: either "nil" or a list in parens. */
1192 c = getc (infile);
1193 if (c == 'n') /* nil */
1195 if ((c = getc (infile)) != 'i'
1196 || (c = getc (infile)) != 'l')
1198 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1199 buffer, filename);
1200 continue;
1203 else if (c != '(')
1205 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1206 buffer, filename);
1207 continue;
1209 else
1210 while (c != ')')
1211 c = getc (infile);
1212 skip_white (infile);
1214 /* If the next three characters aren't `dquote bslash newline'
1215 then we're not reading a docstring.
1217 if ((c = getc (infile)) != '"'
1218 || (c = getc (infile)) != '\\'
1219 || ((c = getc (infile)) != '\n' && c != '\r'))
1221 #ifdef DEBUG
1222 fprintf (stderr, "## non-docstring in %s (%s)\n",
1223 buffer, filename);
1224 #endif
1225 continue;
1229 /* defcustom can only occur in uncompiled Lisp files. */
1230 else if (! strcmp (buffer, "defvar")
1231 || ! strcmp (buffer, "defconst")
1232 || ! strcmp (buffer, "defcustom"))
1234 type = 'V';
1235 read_lisp_symbol (infile, buffer);
1237 if (saved_string == 0)
1238 if (!search_lisp_doc_at_eol (infile))
1239 continue;
1242 else if (! strcmp (buffer, "custom-declare-variable")
1243 || ! strcmp (buffer, "defvaralias")
1246 type = 'V';
1248 c = getc (infile);
1249 if (c == '\'')
1250 read_lisp_symbol (infile, buffer);
1251 else
1253 if (c != '(')
1255 fprintf (stderr,
1256 "## unparsable name in custom-declare-variable in %s\n",
1257 filename);
1258 continue;
1260 read_lisp_symbol (infile, buffer);
1261 if (strcmp (buffer, "quote"))
1263 fprintf (stderr,
1264 "## unparsable name in custom-declare-variable in %s\n",
1265 filename);
1266 continue;
1268 read_lisp_symbol (infile, buffer);
1269 c = getc (infile);
1270 if (c != ')')
1272 fprintf (stderr,
1273 "## unparsable quoted name in custom-declare-variable in %s\n",
1274 filename);
1275 continue;
1279 if (saved_string == 0)
1280 if (!search_lisp_doc_at_eol (infile))
1281 continue;
1284 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1286 type = 'F';
1288 c = getc (infile);
1289 if (c == '\'')
1290 read_lisp_symbol (infile, buffer);
1291 else
1293 if (c != '(')
1295 fprintf (stderr, "## unparsable name in fset in %s\n",
1296 filename);
1297 continue;
1299 read_lisp_symbol (infile, buffer);
1300 if (strcmp (buffer, "quote"))
1302 fprintf (stderr, "## unparsable name in fset in %s\n",
1303 filename);
1304 continue;
1306 read_lisp_symbol (infile, buffer);
1307 c = getc (infile);
1308 if (c != ')')
1310 fprintf (stderr,
1311 "## unparsable quoted name in fset in %s\n",
1312 filename);
1313 continue;
1317 if (saved_string == 0)
1318 if (!search_lisp_doc_at_eol (infile))
1319 continue;
1322 else if (! strcmp (buffer, "autoload"))
1324 type = 'F';
1325 c = getc (infile);
1326 if (c == '\'')
1327 read_lisp_symbol (infile, buffer);
1328 else
1330 if (c != '(')
1332 fprintf (stderr, "## unparsable name in autoload in %s\n",
1333 filename);
1334 continue;
1336 read_lisp_symbol (infile, buffer);
1337 if (strcmp (buffer, "quote"))
1339 fprintf (stderr, "## unparsable name in autoload in %s\n",
1340 filename);
1341 continue;
1343 read_lisp_symbol (infile, buffer);
1344 c = getc (infile);
1345 if (c != ')')
1347 fprintf (stderr,
1348 "## unparsable quoted name in autoload in %s\n",
1349 filename);
1350 continue;
1353 skip_white (infile);
1354 if ((c = getc (infile)) != '\"')
1356 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1357 buffer, filename);
1358 continue;
1360 read_c_string_or_comment (infile, 0, 0, 0);
1362 if (saved_string == 0)
1363 if (!search_lisp_doc_at_eol (infile))
1364 continue;
1367 #ifdef DEBUG
1368 else if (! strcmp (buffer, "if")
1369 || ! strcmp (buffer, "byte-code"))
1370 continue;
1371 #endif
1373 else
1375 #ifdef DEBUG
1376 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1377 buffer, filename);
1378 #endif
1379 continue;
1382 /* At this point, we should either use the previous dynamic doc string in
1383 saved_string or gobble a doc string from the input file.
1384 In the latter case, the opening quote (and leading backslash-newline)
1385 have already been read. */
1387 putc (037, outfile);
1388 putc (type, outfile);
1389 fprintf (outfile, "%s\n", buffer);
1390 if (saved_string)
1392 fputs (saved_string, outfile);
1393 /* Don't use one dynamic doc string twice. */
1394 free (saved_string);
1395 saved_string = 0;
1397 else
1398 read_c_string_or_comment (infile, 1, 0, 0);
1400 fclose (infile);
1401 return 0;
1405 /* make-docfile.c ends here */