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)
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.
47 /* If first two args are -o FILE, output to FILE. */
49 if (argc
> i
+ 1 && !strcmp (argv
[i
], "-o"))
51 outfile
= fopen (argv
[i
+ 1], "w");
54 if (argc
> i
+ 1 && !strcmp (argv
[i
], "-a"))
56 outfile
= fopen (argv
[i
+ 1], "a");
61 err_count
+= scan_file (argv
[i
]); /* err_count seems to be {mis,un}used */
63 exit (err_count
); /* see below - shane */
67 /* Read file FILENAME and output its doc strings to outfile. */
68 /* Return 1 if file is not found, 0 if it is found. */
73 int len
= strlen (filename
);
74 if (!strcmp (filename
+ len
- 4, ".elc"))
75 return scan_lisp_file (filename
);
76 else if (!strcmp (filename
+ len
- 3, ".el"))
77 return scan_lisp_file (filename
);
79 return scan_c_file (filename
);
84 /* Skip a C string from INFILE,
85 and return the character that follows the closing ".
86 If printflag is positive, output string contents to outfile.
87 If it is negative, store contents in buf.
88 Convert escape sequences \n and \t to newline and tab;
89 discard \ followed by newline. */
91 read_c_string (infile
, printflag
)
101 while (c
!= '"' && c
!= EOF
)
118 else if (printflag
< 0)
127 else if (printflag
< 0)
138 /* Write to file OUT the argument names of the function whose text is in BUF.
139 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
141 write_c_args (out
, buf
, minargs
, maxargs
)
144 int minargs
, maxargs
;
150 fprintf (out
, "arguments: ");
152 for (p
= buf
; *p
; p
++)
157 /* Notice when we start printing a new identifier. */
158 if ((('A' <= c
&& c
<= 'Z')
159 || ('a' <= c
&& c
<= 'z')
160 || ('0' <= c
&& c
<= '9')
169 if (minargs
== 0 && maxargs
> 0)
170 fprintf (out
, "&optional ");
180 /* Print the C argument list as it would appear in lisp:
181 print underscores as hyphens, and print commas as spaces.
182 Collapse adjacent spaces into one. */
183 if (c
== '_') c
= '-';
184 if (c
== ',') c
= ' ';
186 /* In C code, `default' is a reserved word, so we spell it
187 `defalt'; unmangle that here. */
189 && strncmp (p
, "defalt", 6) == 0
190 && ! (('A' <= p
[6] && p
[6] <= 'Z')
191 || ('a' <= p
[6] && p
[6] <= 'z')
192 || ('0' <= p
[6] && p
[6] <= '9')
195 fprintf (out
, "default");
200 else if (c
!= ' ' || ! just_spaced
)
203 just_spaced
= (c
== ' ');
207 /* Read through a c file. If a .o file is named,
208 the corresponding .c file is read instead.
209 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
210 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
212 scan_c_file (filename
)
218 register int defunflag
;
219 register int defvarperbufferflag
;
220 register int defvarflag
;
221 int minargs
, maxargs
;
223 if (filename
[strlen (filename
) - 1] == 'o')
224 filename
[strlen (filename
) - 1] = 'c';
226 infile
= fopen (filename
, "r");
228 /* No error if non-ex input file */
236 while (!feof (infile
))
273 defvarperbufferflag
= (c
== 'P');
286 defunflag
= c
== 'U';
301 c
= read_c_string (infile
, -1);
305 else if (defvarperbufferflag
)
309 else /* For DEFSIMPLE and DEFPRED */
317 if (defunflag
&& (commas
== 1 || commas
== 2))
321 while (c
== ' ' || c
== '\n' || c
== '\t');
325 if (commas
== 2) /* pick up minargs */
326 fscanf (infile
, "%d", &minargs
);
327 else /* pick up maxargs */
328 if (c
== 'M' || c
== 'U') /* MANY || UNEVALLED */
331 fscanf (infile
, "%d", &maxargs
);
338 while (c
== ' ' || c
== '\n' || c
== '\t')
341 c
= read_c_string (infile
, 0);
345 while (c
== ' ' || c
== '\n' || c
== '\t')
351 putc (defvarflag
? 'V' : 'F', outfile
);
352 fprintf (outfile
, "%s\n", buf
);
353 c
= read_c_string (infile
, 1);
355 /* If this is a defun, find the arguments and print them. If
356 this function takes MANY or UNEVALLED args, then the C source
357 won't give the names of the arguments, so we shouldn't bother
358 trying to find them. */
359 if (defunflag
&& maxargs
!= -1)
361 char argbuf
[1024], *p
= argbuf
;
368 /* Skip into arguments. */
375 /* Copy arguments into ARGBUF. */
378 *p
++ = c
= getc (infile
);
382 fprintf (outfile
, "\n\n");
383 write_c_args (outfile
, argbuf
, minargs
, maxargs
);
392 /* Read a file of Lisp code, compiled or interpreted.
394 (defun NAME ARGS DOCSTRING ...)
395 (defmacro NAME ARGS DOCSTRING ...)
396 (autoload (quote NAME) FILE DOCSTRING ...)
397 (defvar NAME VALUE DOCSTRING)
398 (defconst NAME VALUE DOCSTRING)
399 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
400 (fset (quote NAME) #[... DOCSTRING ...])
401 starting in column zero.
402 (quote NAME) may appear as 'NAME as well.
403 For defun, defmacro, and autoload, we know how to skip over the arglist.
404 For defvar, defconst, and fset we skip to the docstring with a klugey
405 formatting convention: all docstrings must appear on the same line as the
406 initial open-paren (the one in column zero) and must contain a backslash
407 and a double-quote immediately after the initial double-quote. No newlines
408 must appear between the beginning of the form and the first double-quote.
409 The only source file that must follow this convention is loaddefs.el; aside
410 from that, it is always the .elc file that we look at, and they are no
411 problem because byte-compiler output follows this convention.
412 The NAME and DOCSTRING are output.
413 NAME is preceded by `F' for a function or `V' for a variable.
414 An entry is output only if DOCSTRING has \ newline just after the opening "
422 while (c
== ' ' || c
== '\t' || c
== '\n')
428 read_lisp_symbol (infile
, buffer
)
433 char *fillp
= buffer
;
440 *(++fillp
) = getc (infile
);
441 else if (c
== ' ' || c
== '\t' || c
== '\n' || c
== '(' || c
== ')')
452 fprintf (stderr
, "## expected a symbol, got '%c'\n", c
);
458 scan_lisp_file (filename
)
464 infile
= fopen (filename
, "r");
468 return 0; /* No error */
472 while (!feof (infile
))
474 char buffer
[BUFSIZ
];
475 char *fillp
= buffer
;
487 read_lisp_symbol (infile
, buffer
);
489 if (! strcmp (buffer
, "defun") ||
490 ! strcmp (buffer
, "defmacro"))
493 read_lisp_symbol (infile
, buffer
);
495 /* Skip the arguments: either "nil" or a list in parens */
498 if (c
== 'n') /* nil */
500 if ((c
= getc (infile
)) != 'i' ||
501 (c
= getc (infile
)) != 'l')
503 fprintf (stderr
, "## unparsable arglist in %s (%s)\n",
510 fprintf (stderr
, "## unparsable arglist in %s (%s)\n",
519 /* If the next three characters aren't `dquote bslash newline'
520 then we're not reading a docstring.
522 if ((c
= getc (infile
)) != '"' ||
523 (c
= getc (infile
)) != '\\' ||
524 (c
= getc (infile
)) != '\n')
527 fprintf (stderr
, "## non-docstring in %s (%s)\n",
534 else if (! strcmp (buffer
, "defvar") ||
535 ! strcmp (buffer
, "defconst"))
539 read_lisp_symbol (infile
, buffer
);
541 /* Skip until the first newline; remember the two previous chars. */
542 while (c
!= '\n' && c
>= 0)
549 /* If two previous characters were " and \,
550 this is a doc string. Otherwise, there is none. */
551 if (c2
!= '"' || c1
!= '\\')
554 fprintf (stderr
, "## non-docstring in %s (%s)\n",
561 else if (! strcmp (buffer
, "fset"))
568 read_lisp_symbol (infile
, buffer
);
573 fprintf (stderr
, "## unparsable name in fset in %s\n",
577 read_lisp_symbol (infile
, buffer
);
578 if (strcmp (buffer
, "quote"))
580 fprintf (stderr
, "## unparsable name in fset in %s\n",
584 read_lisp_symbol (infile
, buffer
);
589 "## unparsable quoted name in fset in %s\n",
595 /* Skip until the first newline; remember the two previous chars. */
596 while (c
!= '\n' && c
>= 0)
603 /* If two previous characters were " and \,
604 this is a doc string. Otherwise, there is none. */
605 if (c2
!= '"' || c1
!= '\\')
608 fprintf (stderr
, "## non-docstring in %s (%s)\n",
615 else if (! strcmp (buffer
, "autoload"))
620 read_lisp_symbol (infile
, buffer
);
625 fprintf (stderr
, "## unparsable name in autoload in %s\n",
629 read_lisp_symbol (infile
, buffer
);
630 if (strcmp (buffer
, "quote"))
632 fprintf (stderr
, "## unparsable name in autoload in %s\n",
636 read_lisp_symbol (infile
, buffer
);
641 "## unparsable quoted name in autoload in %s\n",
647 if ((c
= getc (infile
)) != '\"')
649 fprintf (stderr
, "## autoload of %s unparsable (%s)\n",
653 read_c_string (infile
, 0);
656 /* If the next three characters aren't `dquote bslash newline'
657 then we're not reading a docstring.
659 if ((c
= getc (infile
)) != '"' ||
660 (c
= getc (infile
)) != '\\' ||
661 (c
= getc (infile
)) != '\n')
664 fprintf (stderr
, "## non-docstring in %s (%s)\n",
672 else if (! strcmp (buffer
, "if") ||
673 ! strcmp (buffer
, "byte-code"))
680 fprintf (stderr
, "## unrecognised top-level form, %s (%s)\n",
686 /* At this point, there is a docstring that we should gobble.
687 The opening quote (and leading backslash-newline) have already
690 putc ('\n', outfile
);
692 putc (type
, outfile
);
693 fprintf (outfile
, "%s\n", buffer
);
694 read_c_string (infile
, 1);