(x-invocation-args): Add defvar.
[emacs.git] / lib-src / make-docfile.c
blobee149b503edc0b496dd378c0aaa75c500987064b
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* The arguments given to this program are all the C and Lisp source files
21 of GNU Emacs. .elc and .el and .c files are allowed.
22 A .o file can also be specified; the .c file it was made from is used.
23 This helps the makefile pass the correct list of files.
25 The results, which go to standard output or to a file
26 specified with -a or -o (-a to append, -o to start from nothing),
27 are entries containing function or variable names and their documentation.
28 Each entry starts with a ^_ character.
29 Then comes F for a function or V for a variable.
30 Then comes the function or variable name, terminated with a newline.
31 Then comes the documentation for that function or variable.
34 #include <stdio.h>
36 FILE *outfile;
38 main (argc, argv)
39 int argc;
40 char **argv;
42 int i;
43 int err_count = 0;
45 outfile = stdout;
47 /* If first two args are -o FILE, output to FILE. */
48 i = 1;
49 if (argc > i + 1 && !strcmp (argv[i], "-o"))
51 outfile = fopen (argv[i + 1], "w");
52 i += 2;
54 if (argc > i + 1 && !strcmp (argv[i], "-a"))
56 outfile = fopen (argv[i + 1], "a");
57 i += 2;
59 if (argc > i + 1 && !strcmp (argv[i], "-d"))
61 chdir (argv[i + 1]);
62 i += 2;
65 for (; i < argc; i++)
66 err_count += scan_file (argv[i]); /* err_count seems to be {mis,un}used */
67 #ifndef VMS
68 exit (err_count); /* see below - shane */
69 #endif /* VMS */
72 /* Read file FILENAME and output its doc strings to outfile. */
73 /* Return 1 if file is not found, 0 if it is found. */
75 scan_file (filename)
76 char *filename;
78 int len = strlen (filename);
79 if (!strcmp (filename + len - 4, ".elc"))
80 return scan_lisp_file (filename);
81 else if (!strcmp (filename + len - 3, ".el"))
82 return scan_lisp_file (filename);
83 else
84 return scan_c_file (filename);
87 char buf[128];
89 /* Skip a C string from INFILE,
90 and return the character that follows the closing ".
91 If printflag is positive, output string contents to outfile.
92 If it is negative, store contents in buf.
93 Convert escape sequences \n and \t to newline and tab;
94 discard \ followed by newline. */
96 read_c_string (infile, printflag)
97 FILE *infile;
98 int printflag;
100 register int c;
101 char *p = buf;
103 c = getc (infile);
104 while (c != EOF)
106 while (c != '"' && c != EOF)
108 if (c == '\\')
110 c = getc (infile);
111 if (c == '\n')
113 c = getc (infile);
114 continue;
116 if (c == 'n')
117 c = '\n';
118 if (c == 't')
119 c = '\t';
121 if (printflag > 0)
122 putc (c, outfile);
123 else if (printflag < 0)
124 *p++ = c;
125 c = getc (infile);
127 c = getc (infile);
128 if (c != '"')
129 break;
130 if (printflag > 0)
131 putc (c, outfile);
132 else if (printflag < 0)
133 *p++ = c;
134 c = getc (infile);
137 if (printflag < 0)
138 *p = 0;
140 return c;
143 /* Write to file OUT the argument names of the function whose text is in BUF.
144 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
146 write_c_args (out, buf, minargs, maxargs)
147 FILE *out;
148 char *buf;
149 int minargs, maxargs;
151 register char *p;
152 int in_ident = 0;
153 int just_spaced = 0;
155 fprintf (out, "arguments: ");
157 for (p = buf; *p; p++)
159 char c = *p;
160 int ident_start = 0;
162 /* Notice when we start printing a new identifier. */
163 if ((('A' <= c && c <= 'Z')
164 || ('a' <= c && c <= 'z')
165 || ('0' <= c && c <= '9')
166 || c == '_')
167 != in_ident)
169 if (!in_ident)
171 in_ident = 1;
172 ident_start = 1;
174 if (minargs == 0 && maxargs > 0)
175 fprintf (out, "&optional ");
176 just_spaced = 1;
178 minargs--;
179 maxargs--;
181 else
182 in_ident = 0;
185 /* Print the C argument list as it would appear in lisp:
186 print underscores as hyphens, and print commas as spaces.
187 Collapse adjacent spaces into one. */
188 if (c == '_') c = '-';
189 if (c == ',') c = ' ';
191 /* In C code, `default' is a reserved word, so we spell it
192 `defalt'; unmangle that here. */
193 if (ident_start
194 && strncmp (p, "defalt", 6) == 0
195 && ! (('A' <= p[6] && p[6] <= 'Z')
196 || ('a' <= p[6] && p[6] <= 'z')
197 || ('0' <= p[6] && p[6] <= '9')
198 || p[6] == '_'))
200 fprintf (out, "default");
201 p += 5;
202 in_ident = 0;
203 just_spaced = 0;
205 else if (c != ' ' || ! just_spaced)
206 putc (c, out);
208 just_spaced = (c == ' ');
212 /* Read through a c file. If a .o file is named,
213 the corresponding .c file is read instead.
214 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
215 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
217 scan_c_file (filename)
218 char *filename;
220 FILE *infile;
221 register int c;
222 register int commas;
223 register int defunflag;
224 register int defvarperbufferflag;
225 register int defvarflag;
226 int minargs, maxargs;
228 if (filename[strlen (filename) - 1] == 'o')
229 filename[strlen (filename) - 1] = 'c';
231 infile = fopen (filename, "r");
233 /* No error if non-ex input file */
234 if (infile == NULL)
236 perror (filename);
237 return 0;
240 c = '\n';
241 while (!feof (infile))
243 if (c != '\n')
245 c = getc (infile);
246 continue;
248 c = getc (infile);
249 if (c == ' ')
251 while (c == ' ')
252 c = getc (infile);
253 if (c != 'D')
254 continue;
255 c = getc (infile);
256 if (c != 'E')
257 continue;
258 c = getc (infile);
259 if (c != 'F')
260 continue;
261 c = getc (infile);
262 if (c != 'V')
263 continue;
264 c = getc (infile);
265 if (c != 'A')
266 continue;
267 c = getc (infile);
268 if (c != 'R')
269 continue;
270 c = getc (infile);
271 if (c != '_')
272 continue;
274 defvarflag = 1;
275 defunflag = 0;
277 c = getc (infile);
278 defvarperbufferflag = (c == 'P');
280 c = getc (infile);
282 else if (c == 'D')
284 c = getc (infile);
285 if (c != 'E')
286 continue;
287 c = getc (infile);
288 if (c != 'F')
289 continue;
290 c = getc (infile);
291 defunflag = c == 'U';
292 defvarflag = 0;
294 else continue;
296 while (c != '(')
298 if (c < 0)
299 goto eof;
300 c = getc (infile);
303 c = getc (infile);
304 if (c != '"')
305 continue;
306 c = read_c_string (infile, -1);
308 if (defunflag)
309 commas = 5;
310 else if (defvarperbufferflag)
311 commas = 2;
312 else if (defvarflag)
313 commas = 1;
314 else /* For DEFSIMPLE and DEFPRED */
315 commas = 2;
317 while (commas)
319 if (c == ',')
321 commas--;
322 if (defunflag && (commas == 1 || commas == 2))
325 c = getc (infile);
326 while (c == ' ' || c == '\n' || c == '\t');
327 if (c < 0)
328 goto eof;
329 ungetc (c, infile);
330 if (commas == 2) /* pick up minargs */
331 fscanf (infile, "%d", &minargs);
332 else /* pick up maxargs */
333 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
334 maxargs = -1;
335 else
336 fscanf (infile, "%d", &maxargs);
339 if (c < 0)
340 goto eof;
341 c = getc (infile);
343 while (c == ' ' || c == '\n' || c == '\t')
344 c = getc (infile);
345 if (c == '"')
346 c = read_c_string (infile, 0);
347 while (c != ',')
348 c = getc (infile);
349 c = getc (infile);
350 while (c == ' ' || c == '\n' || c == '\t')
351 c = getc (infile);
353 if (c == '"')
355 putc (037, outfile);
356 putc (defvarflag ? 'V' : 'F', outfile);
357 fprintf (outfile, "%s\n", buf);
358 c = read_c_string (infile, 1);
360 /* If this is a defun, find the arguments and print them. If
361 this function takes MANY or UNEVALLED args, then the C source
362 won't give the names of the arguments, so we shouldn't bother
363 trying to find them. */
364 if (defunflag && maxargs != -1)
366 char argbuf[1024], *p = argbuf;
367 while (c != ')')
369 if (c < 0)
370 goto eof;
371 c = getc (infile);
373 /* Skip into arguments. */
374 while (c != '(')
376 if (c < 0)
377 goto eof;
378 c = getc (infile);
380 /* Copy arguments into ARGBUF. */
381 *p++ = c;
383 *p++ = c = getc (infile);
384 while (c != ')');
385 *p = '\0';
386 /* Output them. */
387 fprintf (outfile, "\n\n");
388 write_c_args (outfile, argbuf, minargs, maxargs);
392 eof:
393 fclose (infile);
394 return 0;
397 /* Read a file of Lisp code, compiled or interpreted.
398 Looks for
399 (defun NAME ARGS DOCSTRING ...)
400 (defmacro NAME ARGS DOCSTRING ...)
401 (autoload (quote NAME) FILE DOCSTRING ...)
402 (defvar NAME VALUE DOCSTRING)
403 (defconst NAME VALUE DOCSTRING)
404 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
405 (fset (quote NAME) #[... DOCSTRING ...])
406 (defalias (quote NAME) #[... DOCSTRING ...])
407 starting in column zero.
408 (quote NAME) may appear as 'NAME as well.
409 For defun, defmacro, and autoload, we know how to skip over the arglist.
410 For defvar, defconst, and fset we skip to the docstring with a klugey
411 formatting convention: all docstrings must appear on the same line as the
412 initial open-paren (the one in column zero) and must contain a backslash
413 and a double-quote immediately after the initial double-quote. No newlines
414 must appear between the beginning of the form and the first double-quote.
415 The only source file that must follow this convention is loaddefs.el; aside
416 from that, it is always the .elc file that we look at, and they are no
417 problem because byte-compiler output follows this convention.
418 The NAME and DOCSTRING are output.
419 NAME is preceded by `F' for a function or `V' for a variable.
420 An entry is output only if DOCSTRING has \ newline just after the opening "
423 void
424 skip_white (infile)
425 FILE *infile;
427 char c = ' ';
428 while (c == ' ' || c == '\t' || c == '\n')
429 c = getc (infile);
430 ungetc (c, infile);
433 void
434 read_lisp_symbol (infile, buffer)
435 FILE *infile;
436 char *buffer;
438 char c;
439 char *fillp = buffer;
441 skip_white (infile);
442 while (1)
444 c = getc (infile);
445 if (c == '\\')
446 *(++fillp) = getc (infile);
447 else if (c == ' ' || c == '\t' || c == '\n' || c == '(' || c == ')')
449 ungetc (c, infile);
450 *fillp = 0;
451 break;
453 else
454 *fillp++ = c;
457 if (! buffer[0])
458 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
460 skip_white (infile);
464 scan_lisp_file (filename)
465 char *filename;
467 FILE *infile;
468 register int c;
470 infile = fopen (filename, "r");
471 if (infile == NULL)
473 perror (filename);
474 return 0; /* No error */
477 c = '\n';
478 while (!feof (infile))
480 char buffer [BUFSIZ];
481 char *fillp = buffer;
482 char type;
484 if (c != '\n')
486 c = getc (infile);
487 continue;
489 c = getc (infile);
490 if (c != '(')
491 continue;
493 read_lisp_symbol (infile, buffer);
495 if (! strcmp (buffer, "defun") ||
496 ! strcmp (buffer, "defmacro"))
498 type = 'F';
499 read_lisp_symbol (infile, buffer);
501 /* Skip the arguments: either "nil" or a list in parens */
503 c = getc (infile);
504 if (c == 'n') /* nil */
506 if ((c = getc (infile)) != 'i' ||
507 (c = getc (infile)) != 'l')
509 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
510 buffer, filename);
511 continue;
514 else if (c != '(')
516 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
517 buffer, filename);
518 continue;
520 else
521 while (c != ')')
522 c = getc (infile);
523 skip_white (infile);
525 /* If the next three characters aren't `dquote bslash newline'
526 then we're not reading a docstring.
528 if ((c = getc (infile)) != '"' ||
529 (c = getc (infile)) != '\\' ||
530 (c = getc (infile)) != '\n')
532 #ifdef DEBUG
533 fprintf (stderr, "## non-docstring in %s (%s)\n",
534 buffer, filename);
535 #endif
536 continue;
540 else if (! strcmp (buffer, "defvar") ||
541 ! strcmp (buffer, "defconst"))
543 char c1 = 0, c2 = 0;
544 type = 'V';
545 read_lisp_symbol (infile, buffer);
547 /* Skip until the first newline; remember the two previous chars. */
548 while (c != '\n' && c >= 0)
550 c2 = c1;
551 c1 = c;
552 c = getc (infile);
555 /* If two previous characters were " and \,
556 this is a doc string. Otherwise, there is none. */
557 if (c2 != '"' || c1 != '\\')
559 #ifdef DEBUG
560 fprintf (stderr, "## non-docstring in %s (%s)\n",
561 buffer, filename);
562 #endif
563 continue;
567 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
569 char c1 = 0, c2 = 0;
570 type = 'F';
572 c = getc (infile);
573 if (c == '\'')
574 read_lisp_symbol (infile, buffer);
575 else
577 if (c != '(')
579 fprintf (stderr, "## unparsable name in fset in %s\n",
580 filename);
581 continue;
583 read_lisp_symbol (infile, buffer);
584 if (strcmp (buffer, "quote"))
586 fprintf (stderr, "## unparsable name in fset in %s\n",
587 filename);
588 continue;
590 read_lisp_symbol (infile, buffer);
591 c = getc (infile);
592 if (c != ')')
594 fprintf (stderr,
595 "## unparsable quoted name in fset in %s\n",
596 filename);
597 continue;
601 /* Skip until the first newline; remember the two previous chars. */
602 while (c != '\n' && c >= 0)
604 c2 = c1;
605 c1 = c;
606 c = getc (infile);
609 /* If two previous characters were " and \,
610 this is a doc string. Otherwise, there is none. */
611 if (c2 != '"' || c1 != '\\')
613 #ifdef DEBUG
614 fprintf (stderr, "## non-docstring in %s (%s)\n",
615 buffer, filename);
616 #endif
617 continue;
621 else if (! strcmp (buffer, "autoload"))
623 type = 'F';
624 c = getc (infile);
625 if (c == '\'')
626 read_lisp_symbol (infile, buffer);
627 else
629 if (c != '(')
631 fprintf (stderr, "## unparsable name in autoload in %s\n",
632 filename);
633 continue;
635 read_lisp_symbol (infile, buffer);
636 if (strcmp (buffer, "quote"))
638 fprintf (stderr, "## unparsable name in autoload in %s\n",
639 filename);
640 continue;
642 read_lisp_symbol (infile, buffer);
643 c = getc (infile);
644 if (c != ')')
646 fprintf (stderr,
647 "## unparsable quoted name in autoload in %s\n",
648 filename);
649 continue;
652 skip_white (infile);
653 if ((c = getc (infile)) != '\"')
655 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
656 buffer, filename);
657 continue;
659 read_c_string (infile, 0);
660 skip_white (infile);
662 /* If the next three characters aren't `dquote bslash newline'
663 then we're not reading a docstring.
665 if ((c = getc (infile)) != '"' ||
666 (c = getc (infile)) != '\\' ||
667 (c = getc (infile)) != '\n')
669 #ifdef DEBUG
670 fprintf (stderr, "## non-docstring in %s (%s)\n",
671 buffer, filename);
672 #endif
673 continue;
677 #ifdef DEBUG
678 else if (! strcmp (buffer, "if") ||
679 ! strcmp (buffer, "byte-code"))
681 #endif
683 else
685 #ifdef DEBUG
686 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
687 buffer, filename);
688 #endif
689 continue;
692 /* At this point, there is a docstring that we should gobble.
693 The opening quote (and leading backslash-newline) have already
694 been read.
696 putc ('\n', outfile);
697 putc (037, outfile);
698 putc (type, outfile);
699 fprintf (outfile, "%s\n", buffer);
700 read_c_string (infile, 1);
702 fclose (infile);
703 return 0;