1: /* Generate doc-string file for GNU Emacs from source files.
2: Copyright (C) 1985 Richard M. Stallman.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is distributed in the hope that it will be useful,
7: but without any warranty. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing.
11:
12: Everyone is granted permission to copy, modify and redistribute
13: GNU Emacs, but only under the conditions described in the
14: document "GNU Emacs copying permission notice". An exact copy
15: of the document is supposed to have been given to you along with
16: GNU Emacs so that you can know how you may redistribute it all.
17: It should be in a file named COPYING. Among other things, the
18: copyright notice and this notice must be preserved on all copies. */
19:
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.
24:
25: The results, printed on standard output, are entries containing
26: function names and their documentation.
27: Each entry starts with a ^_ character.
28: Then comes the function name, terminated with a newline.
29: Then comes the documentation for that function.
30: */
31:
32: #include <stdio.h>
33:
34: main (argc, argv)
35: int argc;
36: char **argv;
37: {
38: int i;
39: int err_count = 0;
40:
41: for (i = 1; i < argc; i++)
42: err_count += scan_file (argv[i]); /* err_count seems to be {mis,un}used */
43: exit (err_count); /* see below - shane */
44: }
45:
46: /* Read file FILENAME and output its doc strings to stdout. */
47: /* Return 1 if file is not found, 0 if it is found. */
48:
49: scan_file (filename)
50: char *filename;
51: {
52: int len = strlen (filename);
53: if (!strcmp (filename + len - 4, ".elc"))
54: return scan_lisp_file (filename);
55: else if (!strcmp (filename + len - 3, ".el"))
56: return scan_lisp_file (filename);
57: else
58: return scan_c_file (filename);
59: }
60:
61: char buf[128];
62:
63: /* Skip a C string from INFILE,
64: and return the character that follows the closing ".
65: If printflag is positive, output string contents to stdout.
66: If it is negative, store contents in buf.
67: Convert escape sequences \n and \t to newline and tab;
68: discard \ followed by newline. */
69:
70: read_c_string (infile, printflag)
71: FILE *infile;
72: int printflag;
73: {
74: register int c;
75: char *p = buf;
76:
77: c = getc (infile);
78: while (1)
79: {
80: while (c != '"')
81: {
82: if (c == '\\')
83: {
84: c = getc (infile);
85: if (c == '\n')
86: {
87: c = getc (infile);
88: continue;
89: }
90: if (c == 'n')
91: c = '\n';
92: if (c == 't')
93: c = '\t';
94: }
95: if (printflag > 0)
96: putchar (c);
97: else if (printflag < 0)
98: *p++ = c;
99: c = getc (infile);
100: }
101: c = getc (infile);
102: if (c != '"')
103: break;
104: if (printflag > 0)
105: putchar (c);
106: else if (printflag < 0)
107: *p++ = c;
108: c = getc (infile);
109: }
110:
111: if (printflag < 0)
112: *p = 0;
113:
114: return c;
115: }
116:
117: /* Read through a c file. If a .o file is named,
118: the corresponding .c file is read instead.
119: Looks for DEFUN constructs such as are defined in ../src/lisp.h.
120: Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
121:
122: scan_c_file (filename)
123: char *filename;
124: {
125: FILE *infile;
126: register int c;
127: register int commas;
128: register int defunflag;
129:
130: if (filename[strlen (filename) - 1] == 'o')
131: filename[strlen (filename) - 1] = 'c';
132:
133: infile = fopen (filename, "r");
134:
135: /* No error if non-ex input file */
136: if (infile == NULL)
137: {
138: perror (filename);
139: return 0;
140: }
141:
142: c = '\n';
143: while (!feof (infile))
144: {
145: if (c != '\n')
146: {
147: c = getc (infile);
148: continue;
149: }
150: c = getc (infile);
151: if (c != 'D')
152: continue;
153: c = getc (infile);
154: if (c != 'E')
155: continue;
156: c = getc (infile);
157: if (c != 'F')
158: continue;
159: c = getc (infile);
160: defunflag = c == 'U';
161:
162: while (c != '(')
163: c = getc (infile);
164:
165: c = getc (infile);
166: if (c != '"')
167: continue;
168: c = read_c_string (infile, -1, 0);
169:
170: if (defunflag)
171: commas = 5;
172: else
173: commas = 2;
174:
175: while (commas)
176: {
177: if (c == ',') commas --;
178: c = getc (infile);
179: }
180: while (c == ' ' || c == '\n' || c == '\t')
181: c = getc (infile);
182: if (c == '"')
183: c = read_c_string (infile, 0, 0);
184: while (c != ',')
185: c = getc (infile);
186: c = getc (infile);
187: while (c == ' ' || c == '\n' || c == '\t')
188: c = getc (infile);
189:
190: if (c == '"')
191: {
192: putchar (037);
193: puts (buf);
194: read_c_string (infile, 1, 0);
195: }
196: }
197: fclose (infile);
198: /* return 1; /* - This says there was an error to caller - breaks make - shane */
199: return 0; /* - So I changed it to this instead. */
200: }
201:
202: /* Read a file of Lisp code, compiled or interpreted.
203: Looks for
204: (defun NAME ARGS DOCSTRING ...) or
205: (autoload 'NAME FILE DOCSTRING ...)
206: either one starting in column zero.
207: ARGS or FILE is ignored;
208: the NAME and DOCSTRING are output.
209: An entry is output only if DOCSTRING has \ newline just after the opening "
210: */
211:
212: scan_lisp_file (filename)
213: char *filename;
214: {
215: FILE *infile;
216: register int c;
217: register int commas;
218: register char *p;
219:
220: infile = fopen (filename, "r");
221: if (infile == NULL)
222: {
223: perror (infile);
224: return 0; /* No error */
225: }
226:
227: c = '\n';
228: while (!feof (infile))
229: {
230: if (c != '\n')
231: {
232: c = getc (infile);
233: continue;
234: }
235: c = getc (infile);
236: if (c != '(')
237: continue;
238: c = getc (infile);
239: if (c == 'a')
240: {
241: c = getc (infile);
242: if (c != 'u')
243: continue;
244: c = getc (infile);
245: if (c != 't')
246: continue;
247: c = getc (infile);
248: if (c != 'o')
249: continue;
250: c = getc (infile);
251: if (c != 'l')
252: continue;
253: c = getc (infile);
254: if (c != 'o')
255: continue;
256: c = getc (infile);
257: if (c != 'a')
258: continue;
259: c = getc (infile);
260: if (c != 'd')
261: continue;
262:
263: while (c != '\'')
264: c = getc (infile);
265: c = getc (infile);
266:
267: p = buf;
268: while (c != ' ')
269: {
270: *p++ = c;
271: c = getc (infile);
272: }
273: *p = 0;
274:
275: while (c != '"')
276: c = getc (infile);
277: c = read_c_string (infile, 0, 0);
278: }
279: else if (c == 'd')
280: {
281: c = getc (infile);
282: if (c != 'e')
283: continue;
284: c = getc (infile);
285: if (c != 'f')
286: continue;
287: c = getc (infile);
288: if (c != 'u')
289: continue;
290: c = getc (infile);
291: if (c != 'n')
292: continue;
293:
294: /* Recognize anything that starts with "defun" */
295: while (c != ' ' && c != '\n' && c != '\t')
296: c = getc (infile);
297:
298: while (c == ' ' || c == '\n' || c == '\t')
299: c = getc (infile);
300:
301: /* Store name of function being defined. */
302: p = buf;
303: while (c != ' ' && c != '\n' && c != '\t')
304: {
305: *p++ = c;
306: c = getc (infile);
307: }
308: *p = 0;
309:
310: while (c == ' ' || c == '\n' || c == '\t')
311: c = getc (infile);
312:
313: /* Skip the arguments: either "nil" or a list in parens */
314: if (c == 'n')
315: {
316: while (c != ' ' && c != '\n' && c != '\t')
317: c = getc (infile);
318: }
319: else
320: {
321: while (c != '(')
322: c = getc (infile);
323: while (c != ')')
324: c = getc (infile);
325: }
326: c = getc (infile);
327: }
328: else
329: continue;
330:
331: /* Skip whitespace */
332:
333: while (c == ' ' || c == '\n' || c == '\t')
334: c = getc (infile);
335:
336: /* " followed by \ and newline means a doc string we should gobble */
337: if (c != '"')
338: continue;
339: c = getc (infile);
340: if (c != '\\')
341: continue;
342: c = getc (infile);
343: if (c != '\n')
344: continue;
345:
346: putchar (037);
347: puts (buf);
348: read_c_string (infile, 1, 0);
349: }
350: fclose (infile);
351: /* return 1; /* - This says there was an error to caller - breaks make - shane */
352: return 0; /* - So I changed it to this instead. */
353: }
Defined functions
main
defined in line
34;
never used
Defined variables
buf
defined in line
61; used 5 times