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