Mercurial > emacs
annotate lib-src/make-docfile.c @ 9750:00490d140f2b
(line-move): Use sign of arg to choose error condition.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 30 Oct 1994 06:38:49 +0000 |
parents | 5d1e70b22a93 |
children | 20652342eb9a |
rev | line source |
---|---|
24 | 1 /* Generate doc-string file for GNU Emacs from source files. |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc. |
24 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
38 | 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 | |
638 | 8 the Free Software Foundation; either version 2, or (at your option) |
38 | 9 any later version. |
24 | 10 |
38 | 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. | |
15 | |
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. */ | |
24 | 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, 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. | |
32 */ | |
33 | |
34 #include <stdio.h> | |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
35 #ifdef MSDOS |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
36 #include <fcntl.h> |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
37 #endif /* MSDOS */ |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
38 |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
39 #ifdef MSDOS |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
40 #define READ_TEXT "rt" |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
41 #define READ_BINARY "rb" |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
42 #else /* not MSDOS */ |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
43 #define READ_TEXT "r" |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
44 #define READ_BINARY "r" |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
45 #endif /* not MSDOS */ |
24 | 46 |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
47 int scan_file (); |
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
48 int scan_lisp_file (); |
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
49 int scan_c_file (); |
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
50 |
24 | 51 FILE *outfile; |
52 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
53 int |
24 | 54 main (argc, argv) |
55 int argc; | |
56 char **argv; | |
57 { | |
58 int i; | |
59 int err_count = 0; | |
9643
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
60 int first_infile; |
24 | 61 |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
62 #ifdef MSDOS |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
63 _fmode = O_BINARY; /* all of files are treated as binary files */ |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
64 (stdout)->_flag &= ~_IOTEXT; |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
65 _setmode (fileno (stdout), O_BINARY); |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
66 #endif /* MSDOS */ |
24 | 67 outfile = stdout; |
68 | |
69 /* If first two args are -o FILE, output to FILE. */ | |
70 i = 1; | |
71 if (argc > i + 1 && !strcmp (argv[i], "-o")) | |
72 { | |
73 outfile = fopen (argv[i + 1], "w"); | |
74 i += 2; | |
75 } | |
76 if (argc > i + 1 && !strcmp (argv[i], "-a")) | |
77 { | |
78 outfile = fopen (argv[i + 1], "a"); | |
79 i += 2; | |
80 } | |
2814
0da5b58e98ed
Install patches from David J. Mackenzie to make the srcdir option
Jim Blandy <jimb@redhat.com>
parents:
2483
diff
changeset
|
81 if (argc > i + 1 && !strcmp (argv[i], "-d")) |
0da5b58e98ed
Install patches from David J. Mackenzie to make the srcdir option
Jim Blandy <jimb@redhat.com>
parents:
2483
diff
changeset
|
82 { |
0da5b58e98ed
Install patches from David J. Mackenzie to make the srcdir option
Jim Blandy <jimb@redhat.com>
parents:
2483
diff
changeset
|
83 chdir (argv[i + 1]); |
0da5b58e98ed
Install patches from David J. Mackenzie to make the srcdir option
Jim Blandy <jimb@redhat.com>
parents:
2483
diff
changeset
|
84 i += 2; |
0da5b58e98ed
Install patches from David J. Mackenzie to make the srcdir option
Jim Blandy <jimb@redhat.com>
parents:
2483
diff
changeset
|
85 } |
24 | 86 |
9643
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
87 first_infile = i; |
24 | 88 for (; i < argc; i++) |
9643
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
89 { |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
90 int j; |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
91 /* Don't process one file twice. */ |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
92 for (j = first_infile; j < i; j++) |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
93 if (! strcmp (argv[i], argv[j])) |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
94 break; |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
95 if (j == i) |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
96 err_count += scan_file (argv[i]); |
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
97 } |
24 | 98 #ifndef VMS |
9643
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
99 exit (err_count > 0); |
3028 | 100 #endif /* VMS */ |
9643
5d1e70b22a93
(main): Don't process one input file twice.
Richard M. Stallman <rms@gnu.org>
parents:
9491
diff
changeset
|
101 return err_count > 0; |
24 | 102 } |
103 | |
164 | 104 /* Read file FILENAME and output its doc strings to outfile. */ |
24 | 105 /* Return 1 if file is not found, 0 if it is found. */ |
106 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
107 int |
24 | 108 scan_file (filename) |
109 char *filename; | |
110 { | |
111 int len = strlen (filename); | |
112 if (!strcmp (filename + len - 4, ".elc")) | |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
113 return scan_lisp_file (filename, READ_BINARY); |
24 | 114 else if (!strcmp (filename + len - 3, ".el")) |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
115 return scan_lisp_file (filename, READ_TEXT); |
24 | 116 else |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
117 return scan_c_file (filename, READ_TEXT); |
24 | 118 } |
119 | |
120 char buf[128]; | |
121 | |
122 /* Skip a C string from INFILE, | |
123 and return the character that follows the closing ". | |
164 | 124 If printflag is positive, output string contents to outfile. |
24 | 125 If it is negative, store contents in buf. |
126 Convert escape sequences \n and \t to newline and tab; | |
127 discard \ followed by newline. */ | |
128 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
129 int |
24 | 130 read_c_string (infile, printflag) |
131 FILE *infile; | |
132 int printflag; | |
133 { | |
134 register int c; | |
135 char *p = buf; | |
136 | |
137 c = getc (infile); | |
138 while (c != EOF) | |
139 { | |
140 while (c != '"' && c != EOF) | |
141 { | |
142 if (c == '\\') | |
143 { | |
144 c = getc (infile); | |
145 if (c == '\n') | |
146 { | |
147 c = getc (infile); | |
148 continue; | |
149 } | |
150 if (c == 'n') | |
151 c = '\n'; | |
152 if (c == 't') | |
153 c = '\t'; | |
154 } | |
155 if (printflag > 0) | |
156 putc (c, outfile); | |
157 else if (printflag < 0) | |
158 *p++ = c; | |
159 c = getc (infile); | |
160 } | |
161 c = getc (infile); | |
162 if (c != '"') | |
163 break; | |
4987
f052db139432
(read_c_string): For "", concatenate the two strings.
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
164 /* If we had a "", concatenate the two strings. */ |
24 | 165 c = getc (infile); |
166 } | |
167 | |
168 if (printflag < 0) | |
169 *p = 0; | |
170 | |
171 return c; | |
172 } | |
173 | |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
174 /* Write to file OUT the argument names of function FUNC, whose text is in BUF. |
24 | 175 MINARGS and MAXARGS are the minimum and maximum number of arguments. */ |
176 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
177 void |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
178 write_c_args (out, func, buf, minargs, maxargs) |
24 | 179 FILE *out; |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
180 char *func, *buf; |
24 | 181 int minargs, maxargs; |
182 { | |
1206 | 183 register char *p; |
1250 | 184 int in_ident = 0; |
185 int just_spaced = 0; | |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
186 int need_space = 1; |
24 | 187 |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
188 fprintf (out, "(%s", func); |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
189 |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
190 if (*buf == '(') |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
191 ++buf; |
24 | 192 |
1206 | 193 for (p = buf; *p; p++) |
24 | 194 { |
1250 | 195 char c = *p; |
2483
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
196 int ident_start = 0; |
1250 | 197 |
198 /* Notice when we start printing a new identifier. */ | |
199 if ((('A' <= c && c <= 'Z') | |
200 || ('a' <= c && c <= 'z') | |
201 || ('0' <= c && c <= '9') | |
202 || c == '_') | |
203 != in_ident) | |
24 | 204 { |
1250 | 205 if (!in_ident) |
206 { | |
207 in_ident = 1; | |
2483
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
208 ident_start = 1; |
1206 | 209 |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
210 if (need_space) |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
211 putc (' ', out); |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
212 |
1250 | 213 if (minargs == 0 && maxargs > 0) |
214 fprintf (out, "&optional "); | |
215 just_spaced = 1; | |
1206 | 216 |
1250 | 217 minargs--; |
218 maxargs--; | |
219 } | |
220 else | |
221 in_ident = 0; | |
24 | 222 } |
638 | 223 |
1250 | 224 /* Print the C argument list as it would appear in lisp: |
225 print underscores as hyphens, and print commas as spaces. | |
226 Collapse adjacent spaces into one. */ | |
227 if (c == '_') c = '-'; | |
228 if (c == ',') c = ' '; | |
229 | |
2483
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
230 /* In C code, `default' is a reserved word, so we spell it |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
231 `defalt'; unmangle that here. */ |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
232 if (ident_start |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
233 && strncmp (p, "defalt", 6) == 0 |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
234 && ! (('A' <= p[6] && p[6] <= 'Z') |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
235 || ('a' <= p[6] && p[6] <= 'z') |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
236 || ('0' <= p[6] && p[6] <= '9') |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
237 || p[6] == '_')) |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
238 { |
7564
d5d803ffff27
(write_c_args): Put `default' in upper case.
Richard M. Stallman <rms@gnu.org>
parents:
5604
diff
changeset
|
239 fprintf (out, "DEFAULT"); |
2483
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
240 p += 5; |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
241 in_ident = 0; |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
242 just_spaced = 0; |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
243 } |
b4145a12422d
* make-docfile.c (write_c_args): Print an argument named "defalt"
Jim Blandy <jimb@redhat.com>
parents:
1676
diff
changeset
|
244 else if (c != ' ' || ! just_spaced) |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
245 { |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
246 if (c >= 'a' && c <= 'z') |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
247 /* Upcase the letter. */ |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
248 c += 'A' - 'a'; |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
249 putc (c, out); |
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
250 } |
1250 | 251 |
252 just_spaced = (c == ' '); | |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
253 need_space = 0; |
24 | 254 } |
255 } | |
256 | |
257 /* Read through a c file. If a .o file is named, | |
258 the corresponding .c file is read instead. | |
259 Looks for DEFUN constructs such as are defined in ../src/lisp.h. | |
260 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */ | |
261 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
262 int |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
263 scan_c_file (filename, mode) |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
264 char *filename, *mode; |
24 | 265 { |
266 FILE *infile; | |
267 register int c; | |
268 register int commas; | |
269 register int defunflag; | |
1676
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
270 register int defvarperbufferflag; |
24 | 271 register int defvarflag; |
272 int minargs, maxargs; | |
273 | |
274 if (filename[strlen (filename) - 1] == 'o') | |
275 filename[strlen (filename) - 1] = 'c'; | |
276 | |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
277 infile = fopen (filename, mode); |
24 | 278 |
279 /* No error if non-ex input file */ | |
280 if (infile == NULL) | |
281 { | |
282 perror (filename); | |
283 return 0; | |
284 } | |
285 | |
286 c = '\n'; | |
287 while (!feof (infile)) | |
288 { | |
289 if (c != '\n') | |
290 { | |
291 c = getc (infile); | |
292 continue; | |
293 } | |
294 c = getc (infile); | |
295 if (c == ' ') | |
296 { | |
297 while (c == ' ') | |
298 c = getc (infile); | |
299 if (c != 'D') | |
300 continue; | |
301 c = getc (infile); | |
302 if (c != 'E') | |
303 continue; | |
304 c = getc (infile); | |
305 if (c != 'F') | |
306 continue; | |
307 c = getc (infile); | |
308 if (c != 'V') | |
309 continue; | |
1676
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
310 c = getc (infile); |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
311 if (c != 'A') |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
312 continue; |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
313 c = getc (infile); |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
314 if (c != 'R') |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
315 continue; |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
316 c = getc (infile); |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
317 if (c != '_') |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
318 continue; |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
319 |
24 | 320 defvarflag = 1; |
321 defunflag = 0; | |
1676
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
322 |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
323 c = getc (infile); |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
324 defvarperbufferflag = (c == 'P'); |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
325 |
24 | 326 c = getc (infile); |
327 } | |
328 else if (c == 'D') | |
329 { | |
330 c = getc (infile); | |
331 if (c != 'E') | |
332 continue; | |
333 c = getc (infile); | |
334 if (c != 'F') | |
335 continue; | |
336 c = getc (infile); | |
337 defunflag = c == 'U'; | |
338 defvarflag = 0; | |
339 } | |
340 else continue; | |
341 | |
342 while (c != '(') | |
343 { | |
344 if (c < 0) | |
345 goto eof; | |
346 c = getc (infile); | |
347 } | |
348 | |
349 c = getc (infile); | |
350 if (c != '"') | |
351 continue; | |
352 c = read_c_string (infile, -1); | |
353 | |
354 if (defunflag) | |
355 commas = 5; | |
1676
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
356 else if (defvarperbufferflag) |
e8b3c6b52c1e
* make-docfile.c (scan_c_file): Since DEFVAR_PER_BUFFER now takes
Jim Blandy <jimb@redhat.com>
parents:
1250
diff
changeset
|
357 commas = 2; |
24 | 358 else if (defvarflag) |
359 commas = 1; | |
360 else /* For DEFSIMPLE and DEFPRED */ | |
361 commas = 2; | |
362 | |
363 while (commas) | |
364 { | |
365 if (c == ',') | |
366 { | |
367 commas--; | |
368 if (defunflag && (commas == 1 || commas == 2)) | |
369 { | |
370 do | |
371 c = getc (infile); | |
372 while (c == ' ' || c == '\n' || c == '\t'); | |
373 if (c < 0) | |
374 goto eof; | |
375 ungetc (c, infile); | |
376 if (commas == 2) /* pick up minargs */ | |
377 fscanf (infile, "%d", &minargs); | |
378 else /* pick up maxargs */ | |
379 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */ | |
380 maxargs = -1; | |
381 else | |
382 fscanf (infile, "%d", &maxargs); | |
383 } | |
384 } | |
385 if (c < 0) | |
386 goto eof; | |
387 c = getc (infile); | |
388 } | |
389 while (c == ' ' || c == '\n' || c == '\t') | |
390 c = getc (infile); | |
391 if (c == '"') | |
392 c = read_c_string (infile, 0); | |
393 while (c != ',') | |
394 c = getc (infile); | |
395 c = getc (infile); | |
396 while (c == ' ' || c == '\n' || c == '\t') | |
397 c = getc (infile); | |
398 | |
399 if (c == '"') | |
400 { | |
401 putc (037, outfile); | |
402 putc (defvarflag ? 'V' : 'F', outfile); | |
403 fprintf (outfile, "%s\n", buf); | |
168 | 404 c = read_c_string (infile, 1); |
405 | |
406 /* If this is a defun, find the arguments and print them. If | |
407 this function takes MANY or UNEVALLED args, then the C source | |
408 won't give the names of the arguments, so we shouldn't bother | |
409 trying to find them. */ | |
410 if (defunflag && maxargs != -1) | |
24 | 411 { |
412 char argbuf[1024], *p = argbuf; | |
413 while (c != ')') | |
414 { | |
415 if (c < 0) | |
416 goto eof; | |
417 c = getc (infile); | |
418 } | |
419 /* Skip into arguments. */ | |
420 while (c != '(') | |
421 { | |
422 if (c < 0) | |
423 goto eof; | |
424 c = getc (infile); | |
425 } | |
426 /* Copy arguments into ARGBUF. */ | |
427 *p++ = c; | |
428 do | |
429 *p++ = c = getc (infile); | |
430 while (c != ')'); | |
431 *p = '\0'; | |
432 /* Output them. */ | |
433 fprintf (outfile, "\n\n"); | |
5604
32ac07bd58ef
Make the argument list output look more like the Lisp docstrings do.
Roland McGrath <roland@gnu.org>
parents:
5449
diff
changeset
|
434 write_c_args (outfile, buf, argbuf, minargs, maxargs); |
24 | 435 } |
436 } | |
437 } | |
438 eof: | |
439 fclose (infile); | |
440 return 0; | |
441 } | |
442 | |
443 /* Read a file of Lisp code, compiled or interpreted. | |
444 Looks for | |
445 (defun NAME ARGS DOCSTRING ...) | |
753 | 446 (defmacro NAME ARGS DOCSTRING ...) |
447 (autoload (quote NAME) FILE DOCSTRING ...) | |
24 | 448 (defvar NAME VALUE DOCSTRING) |
449 (defconst NAME VALUE DOCSTRING) | |
753 | 450 (fset (quote NAME) (make-byte-code ... DOCSTRING ...)) |
451 (fset (quote NAME) #[... DOCSTRING ...]) | |
2966
e936d56c2354
(scan_lisp_file): Recognize defalias like fset.
Richard M. Stallman <rms@gnu.org>
parents:
2814
diff
changeset
|
452 (defalias (quote NAME) #[... DOCSTRING ...]) |
24 | 453 starting in column zero. |
753 | 454 (quote NAME) may appear as 'NAME as well. |
455 For defun, defmacro, and autoload, we know how to skip over the arglist. | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3028
diff
changeset
|
456 For defvar, defconst, and fset we skip to the docstring with a kludgy |
753 | 457 formatting convention: all docstrings must appear on the same line as the |
458 initial open-paren (the one in column zero) and must contain a backslash | |
459 and a double-quote immediately after the initial double-quote. No newlines | |
460 must appear between the beginning of the form and the first double-quote. | |
461 The only source file that must follow this convention is loaddefs.el; aside | |
462 from that, it is always the .elc file that we look at, and they are no | |
463 problem because byte-compiler output follows this convention. | |
24 | 464 The NAME and DOCSTRING are output. |
465 NAME is preceded by `F' for a function or `V' for a variable. | |
466 An entry is output only if DOCSTRING has \ newline just after the opening " | |
467 */ | |
468 | |
753 | 469 void |
470 skip_white (infile) | |
471 FILE *infile; | |
472 { | |
473 char c = ' '; | |
474 while (c == ' ' || c == '\t' || c == '\n') | |
475 c = getc (infile); | |
476 ungetc (c, infile); | |
477 } | |
478 | |
479 void | |
480 read_lisp_symbol (infile, buffer) | |
481 FILE *infile; | |
482 char *buffer; | |
483 { | |
484 char c; | |
485 char *fillp = buffer; | |
486 | |
487 skip_white (infile); | |
488 while (1) | |
489 { | |
490 c = getc (infile); | |
491 if (c == '\\') | |
492 *(++fillp) = getc (infile); | |
493 else if (c == ' ' || c == '\t' || c == '\n' || c == '(' || c == ')') | |
494 { | |
495 ungetc (c, infile); | |
496 *fillp = 0; | |
497 break; | |
498 } | |
499 else | |
500 *fillp++ = c; | |
501 } | |
502 | |
503 if (! buffer[0]) | |
504 fprintf (stderr, "## expected a symbol, got '%c'\n", c); | |
505 | |
506 skip_white (infile); | |
507 } | |
508 | |
9491
dd3b83e4ceb0
Eliminate some -Wall warnings.
David J. MacKenzie <djm@gnu.org>
parents:
7564
diff
changeset
|
509 int |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
510 scan_lisp_file (filename, mode) |
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
511 char *filename, *mode; |
24 | 512 { |
513 FILE *infile; | |
514 register int c; | |
515 | |
5449
296db649863d
[MSDOS]: Use text/binary mode as appropriate.
Richard M. Stallman <rms@gnu.org>
parents:
5317
diff
changeset
|
516 infile = fopen (filename, mode); |
24 | 517 if (infile == NULL) |
518 { | |
519 perror (filename); | |
520 return 0; /* No error */ | |
521 } | |
522 | |
523 c = '\n'; | |
524 while (!feof (infile)) | |
525 { | |
753 | 526 char buffer [BUFSIZ]; |
527 char type; | |
528 | |
24 | 529 if (c != '\n') |
530 { | |
531 c = getc (infile); | |
532 continue; | |
533 } | |
534 c = getc (infile); | |
535 if (c != '(') | |
536 continue; | |
164 | 537 |
753 | 538 read_lisp_symbol (infile, buffer); |
539 | |
540 if (! strcmp (buffer, "defun") || | |
541 ! strcmp (buffer, "defmacro")) | |
24 | 542 { |
753 | 543 type = 'F'; |
544 read_lisp_symbol (infile, buffer); | |
545 | |
546 /* Skip the arguments: either "nil" or a list in parens */ | |
24 | 547 |
548 c = getc (infile); | |
753 | 549 if (c == 'n') /* nil */ |
550 { | |
551 if ((c = getc (infile)) != 'i' || | |
552 (c = getc (infile)) != 'l') | |
553 { | |
554 fprintf (stderr, "## unparsable arglist in %s (%s)\n", | |
555 buffer, filename); | |
556 continue; | |
557 } | |
558 } | |
559 else if (c != '(') | |
560 { | |
561 fprintf (stderr, "## unparsable arglist in %s (%s)\n", | |
562 buffer, filename); | |
563 continue; | |
564 } | |
565 else | |
566 while (c != ')') | |
567 c = getc (infile); | |
568 skip_white (infile); | |
24 | 569 |
753 | 570 /* If the next three characters aren't `dquote bslash newline' |
571 then we're not reading a docstring. | |
572 */ | |
573 if ((c = getc (infile)) != '"' || | |
574 (c = getc (infile)) != '\\' || | |
575 (c = getc (infile)) != '\n') | |
24 | 576 { |
753 | 577 #ifdef DEBUG |
578 fprintf (stderr, "## non-docstring in %s (%s)\n", | |
579 buffer, filename); | |
580 #endif | |
581 continue; | |
582 } | |
583 } | |
584 | |
585 else if (! strcmp (buffer, "defvar") || | |
586 ! strcmp (buffer, "defconst")) | |
587 { | |
588 char c1 = 0, c2 = 0; | |
589 type = 'V'; | |
590 read_lisp_symbol (infile, buffer); | |
591 | |
592 /* Skip until the first newline; remember the two previous chars. */ | |
593 while (c != '\n' && c >= 0) | |
594 { | |
595 c2 = c1; | |
596 c1 = c; | |
24 | 597 c = getc (infile); |
598 } | |
753 | 599 |
600 /* If two previous characters were " and \, | |
601 this is a doc string. Otherwise, there is none. */ | |
602 if (c2 != '"' || c1 != '\\') | |
603 { | |
604 #ifdef DEBUG | |
605 fprintf (stderr, "## non-docstring in %s (%s)\n", | |
606 buffer, filename); | |
607 #endif | |
608 continue; | |
609 } | |
610 } | |
611 | |
2966
e936d56c2354
(scan_lisp_file): Recognize defalias like fset.
Richard M. Stallman <rms@gnu.org>
parents:
2814
diff
changeset
|
612 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) |
753 | 613 { |
614 char c1 = 0, c2 = 0; | |
615 type = 'F'; | |
616 | |
617 c = getc (infile); | |
618 if (c == '\'') | |
619 read_lisp_symbol (infile, buffer); | |
24 | 620 else |
621 { | |
622 if (c != '(') | |
753 | 623 { |
624 fprintf (stderr, "## unparsable name in fset in %s\n", | |
625 filename); | |
626 continue; | |
627 } | |
628 read_lisp_symbol (infile, buffer); | |
629 if (strcmp (buffer, "quote")) | |
630 { | |
631 fprintf (stderr, "## unparsable name in fset in %s\n", | |
632 filename); | |
633 continue; | |
634 } | |
635 read_lisp_symbol (infile, buffer); | |
24 | 636 c = getc (infile); |
753 | 637 if (c != ')') |
638 { | |
639 fprintf (stderr, | |
640 "## unparsable quoted name in fset in %s\n", | |
641 filename); | |
642 continue; | |
643 } | |
24 | 644 } |
164 | 645 |
753 | 646 /* Skip until the first newline; remember the two previous chars. */ |
647 while (c != '\n' && c >= 0) | |
24 | 648 { |
753 | 649 c2 = c1; |
650 c1 = c; | |
24 | 651 c = getc (infile); |
652 } | |
753 | 653 |
654 /* If two previous characters were " and \, | |
655 this is a doc string. Otherwise, there is none. */ | |
656 if (c2 != '"' || c1 != '\\') | |
24 | 657 { |
753 | 658 #ifdef DEBUG |
659 fprintf (stderr, "## non-docstring in %s (%s)\n", | |
660 buffer, filename); | |
661 #endif | |
24 | 662 continue; |
663 } | |
664 } | |
753 | 665 |
666 else if (! strcmp (buffer, "autoload")) | |
164 | 667 { |
753 | 668 type = 'F'; |
164 | 669 c = getc (infile); |
753 | 670 if (c == '\'') |
671 read_lisp_symbol (infile, buffer); | |
672 else | |
673 { | |
674 if (c != '(') | |
675 { | |
676 fprintf (stderr, "## unparsable name in autoload in %s\n", | |
677 filename); | |
678 continue; | |
679 } | |
680 read_lisp_symbol (infile, buffer); | |
681 if (strcmp (buffer, "quote")) | |
682 { | |
683 fprintf (stderr, "## unparsable name in autoload in %s\n", | |
684 filename); | |
685 continue; | |
686 } | |
687 read_lisp_symbol (infile, buffer); | |
688 c = getc (infile); | |
689 if (c != ')') | |
690 { | |
691 fprintf (stderr, | |
692 "## unparsable quoted name in autoload in %s\n", | |
693 filename); | |
694 continue; | |
695 } | |
696 } | |
697 skip_white (infile); | |
698 if ((c = getc (infile)) != '\"') | |
699 { | |
700 fprintf (stderr, "## autoload of %s unparsable (%s)\n", | |
701 buffer, filename); | |
702 continue; | |
703 } | |
704 read_c_string (infile, 0); | |
705 skip_white (infile); | |
164 | 706 |
753 | 707 /* If the next three characters aren't `dquote bslash newline' |
708 then we're not reading a docstring. | |
709 */ | |
710 if ((c = getc (infile)) != '"' || | |
711 (c = getc (infile)) != '\\' || | |
712 (c = getc (infile)) != '\n') | |
713 { | |
714 #ifdef DEBUG | |
715 fprintf (stderr, "## non-docstring in %s (%s)\n", | |
716 buffer, filename); | |
717 #endif | |
718 continue; | |
719 } | |
164 | 720 } |
24 | 721 |
753 | 722 #ifdef DEBUG |
723 else if (! strcmp (buffer, "if") || | |
724 ! strcmp (buffer, "byte-code")) | |
725 ; | |
726 #endif | |
24 | 727 |
753 | 728 else |
729 { | |
730 #ifdef DEBUG | |
731 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n", | |
732 buffer, filename); | |
733 #endif | |
734 continue; | |
735 } | |
24 | 736 |
753 | 737 /* At this point, there is a docstring that we should gobble. |
738 The opening quote (and leading backslash-newline) have already | |
739 been read. | |
740 */ | |
24 | 741 putc (037, outfile); |
753 | 742 putc (type, outfile); |
743 fprintf (outfile, "%s\n", buffer); | |
24 | 744 read_c_string (infile, 1); |
745 } | |
746 fclose (infile); | |
747 return 0; | |
748 } |