428
+ − 1 /* Generate doc-string file for XEmacs from source files.
930
+ − 2 Copyright (C) 1985, 86, 92, 93, 94, 97, 1999, 2000, 2001
+ − 3 Free Software Foundation, Inc.
428
+ − 4 Copyright (C) 1995 Board of Trustees, University of Illinois.
+ − 5 Copyright (C) 1998, 1999 J. Kean Johnston.
814
+ − 6 Copyright (C) 2001, 2002 Ben Wing.
930
+ − 7
+ − 8 This file is part of XEmacs.
+ − 9
+ − 10 XEmacs is free software; you can redistribute it and/or modify
+ − 11 it under the terms of the GNU General Public License as published by
+ − 12 the Free Software Foundation; either version 2, or (at your option)
+ − 13 any later version.
428
+ − 14
930
+ − 15 XEmacs is distributed in the hope that it will be useful,
+ − 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ − 18 GNU General Public License for more details.
+ − 19
+ − 20 You should have received a copy of the GNU General Public License
+ − 21 along with XEmacs; see the file COPYING. If not, write to
+ − 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 23 Boston, MA 02111-1307, USA. */
+ − 24
1618
+ − 25 /* Synched up with: FSF 21.3. */
428
+ − 26
+ − 27 /* The arguments given to this program are all the C and Lisp source files
930
+ − 28 of XEmacs. .elc and .el and .c files are allowed.
+ − 29 A .o or .obj file can also be specified; the .c file it was made from is used.
+ − 30 This helps the makefile pass the correct list of files.
+ − 31
+ − 32 The results, which go to standard output or to a file
+ − 33 specified with -a or -o (-a to append, -o to start from nothing),
+ − 34 are entries containing function or variable names and their documentation.
+ − 35 Each entry starts with a ^_ character.
+ − 36 Then comes F for a function or V for a variable.
+ − 37 Then comes the function or variable name, terminated with a newline.
+ − 38 Then comes the documentation for that function or variable.
+ − 39
+ − 40 Added 19.15/20.1: `-i site-packages' allow installer to dump extra packages
+ − 41 without modifying Makefiles, etc.
428
+ − 42 */
+ − 43
438
+ − 44 #include <config.h>
930
+ − 45 #include <sysfile.h>
428
+ − 46
+ − 47 #include <stdio.h>
+ − 48 #include <stdlib.h>
+ − 49 #include <string.h>
+ − 50 #include <ctype.h>
+ − 51
2286
+ − 52 #include "compiler.h"
+ − 53
930
+ − 54 /* XEmacs addition */
+ − 55 #define C_IDENTIFIER_CHAR_P(c) \
+ − 56 (('A' <= c && c <= 'Z') || \
+ − 57 ('a' <= c && c <= 'z') || \
+ − 58 ('0' <= c && c <= '9') || \
+ − 59 (c == '_'))
428
+ − 60
442
+ − 61 static int scan_file (const char *filename);
428
+ − 62 static int read_c_string (FILE *, int, int);
442
+ − 63 static void write_c_args (FILE *out, const char *func, char *buf, int minargs,
428
+ − 64 int maxargs);
442
+ − 65 static int scan_c_file (const char *filename, const char *mode);
428
+ − 66 static void skip_white (FILE *);
+ − 67 static void read_lisp_symbol (FILE *, char *);
442
+ − 68 static int scan_lisp_file (const char *filename, const char *mode);
428
+ − 69
930
+ − 70 /* Stdio stream for output to the DOC file. */
+ − 71 static FILE *outfile;
+ − 72
+ − 73 /* XEmacs addition */
+ − 74 enum
+ − 75 {
+ − 76 el_file,
+ − 77 elc_file,
+ − 78 c_file
+ − 79 } Current_file_type;
428
+ − 80
+ − 81 /* Name this program was invoked with. */
+ − 82 char *progname;
+ − 83
930
+ − 84 /* XEmacs addition: set to 1 if this was invoked by ellcc */
428
+ − 85 int ellcc = 0;
+ − 86
+ − 87 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
+ − 88
+ − 89 static void
442
+ − 90 error (const char *s1, const char *s2)
428
+ − 91 {
+ − 92 fprintf (stderr, "%s: ", progname);
+ − 93 fprintf (stderr, s1, s2);
+ − 94 fprintf (stderr, "\n");
+ − 95 }
+ − 96
+ − 97 /* Print error message and exit. */
+ − 98
+ − 99 static void
442
+ − 100 fatal (const char *s1, const char *s2)
428
+ − 101 {
+ − 102 error (s1, s2);
+ − 103 exit (1);
+ − 104 }
+ − 105
+ − 106 /* Like malloc but get fatal error if memory is exhausted. */
+ − 107
+ − 108 static long *
+ − 109 xmalloc (unsigned int size)
+ − 110 {
+ − 111 long *result = (long *) malloc (size);
+ − 112 if (result == NULL)
+ − 113 fatal ("virtual memory exhausted", 0);
+ − 114 return result;
+ − 115 }
+ − 116
930
+ − 117 /* XEmacs addition */
428
+ − 118 static char *
814
+ − 119 next_extra_elc (char *extra_elcs)
428
+ − 120 {
+ − 121 static FILE *fp = NULL;
+ − 122 static char line_buf[BUFSIZ];
+ − 123 char *p = line_buf+1;
+ − 124
814
+ − 125 if (!fp)
+ − 126 {
+ − 127 if (!extra_elcs)
+ − 128 return NULL;
+ − 129 else if (!(fp = fopen (extra_elcs, READ_BINARY)))
+ − 130 {
+ − 131 /* It is not an error if this file doesn't exist. */
+ − 132 /*fatal ("error opening site package file list", 0);*/
+ − 133 return NULL;
+ − 134 }
+ − 135 fgets (line_buf, BUFSIZ, fp);
+ − 136 }
+ − 137
930
+ − 138 do
814
+ − 139 {
930
+ − 140 if (!fgets (line_buf, BUFSIZ, fp))
+ − 141 {
+ − 142 fclose (fp);
+ − 143 fp = NULL;
+ − 144 return NULL;
+ − 145 }
+ − 146 line_buf[0] = '\0';
814
+ − 147 /* reject too short or too long lines */
930
+ − 148 } while (strlen (p) <= 2 || strlen (p) >= (BUFSIZ - 5));
+ − 149
814
+ − 150 p[strlen (p) - 2] = '\0';
+ − 151 strcat (p, ".elc");
428
+ − 152
+ − 153 return p;
+ − 154 }
+ − 155
+ − 156
+ − 157 int
+ − 158 main (int argc, char **argv)
+ − 159 {
+ − 160 int i;
+ − 161 int err_count = 0;
+ − 162 int first_infile;
930
+ − 163 char *extra_elcs = NULL; /* XEmacs addition */
428
+ − 164
+ − 165 progname = argv[0];
+ − 166
+ − 167 outfile = stdout;
+ − 168
+ − 169 /* Don't put CRs in the DOC file. */
442
+ − 170 #ifdef WIN32_NATIVE
428
+ − 171 _fmode = O_BINARY;
+ − 172 _setmode (fileno (stdout), O_BINARY);
442
+ − 173 #endif /* WIN32_NATIVE */
428
+ − 174
+ − 175 /* If first two args are -o FILE, output to FILE. */
+ − 176 i = 1;
+ − 177 if (argc > i + 1 && !strcmp (argv[i], "-o"))
+ − 178 {
+ − 179 outfile = fopen (argv[i + 1], WRITE_BINARY);
+ − 180 i += 2;
+ − 181 }
+ − 182 if (argc > i + 1 && !strcmp (argv[i], "-a"))
+ − 183 {
+ − 184 outfile = fopen (argv[i + 1], APPEND_BINARY);
+ − 185 i += 2;
+ − 186 }
930
+ − 187 if (argc > i + 1 && !strcmp (argv[i], "-d"))
+ − 188 {
+ − 189 chdir (argv[i + 1]);
+ − 190 i += 2;
+ − 191 }
+ − 192
+ − 193 /* Additional command line arguments for XEmacs */
428
+ − 194 if (argc > i + 1 && !strcmp (argv[i], "-E"))
+ − 195 {
+ − 196 outfile = fopen (argv[i + 1], APPEND_BINARY);
+ − 197 i += 2;
+ − 198 ellcc = 1;
+ − 199 }
814
+ − 200 if (argc > (i + 1) && !strcmp (argv[i], "-i"))
+ − 201 {
+ − 202 extra_elcs = argv[i + 1];
+ − 203 i += 2;
+ − 204 }
428
+ − 205
+ − 206 if (outfile == 0)
+ − 207 fatal ("No output file specified", "");
+ − 208
930
+ − 209 /* XEmacs addition */
428
+ − 210 if (ellcc)
+ − 211 fprintf (outfile, "{\n");
+ − 212
+ − 213 first_infile = i;
+ − 214 for (; i < argc; i++)
+ − 215 {
930
+ − 216 /* XEmacs addition: the "if" clause is new; the "else" clause is the
+ − 217 original FSF Emacs code */
771
+ − 218 if (argv[i][0] == '@')
+ − 219 {
+ − 220 /* Allow a file containing files to process, for use w/MS Windows
+ − 221 (where command-line length limits are more problematic) */
+ − 222 FILE *argfile = fopen (argv[i] + 1, READ_TEXT);
2421
+ − 223 char arg[QXE_PATH_MAX];
771
+ − 224
+ − 225 if (!argfile)
+ − 226 fatal ("Unable to open argument file %s", argv[i] + 1);
2421
+ − 227 while (fgets (arg, QXE_PATH_MAX, argfile))
771
+ − 228 {
+ − 229 if (arg[strlen (arg) - 1] == '\n')
+ − 230 arg[strlen (arg) - 1] = '\0'; /* chop \n */
+ − 231 err_count += scan_file (arg);
+ − 232 }
+ − 233 }
+ − 234 else
+ − 235 {
+ − 236 int j;
+ − 237 /* Don't process one file twice. */
+ − 238 for (j = first_infile; j < i; j++)
+ − 239 if (! strcmp (argv[i], argv[j]))
+ − 240 break;
+ − 241 if (j == i)
+ − 242 err_count += scan_file (argv[i]);
+ − 243 }
428
+ − 244 }
+ − 245
930
+ − 246 /* XEmacs addition */
814
+ − 247 if (extra_elcs)
+ − 248 {
+ − 249 char *p;
428
+ − 250
814
+ − 251 while ((p = next_extra_elc (extra_elcs)) != NULL)
+ − 252 err_count += scan_file (p);
428
+ − 253 }
+ − 254
+ − 255 putc ('\n', outfile);
+ − 256 if (ellcc)
+ − 257 fprintf (outfile, "}\n\n");
930
+ − 258 /* End XEmacs addition */
+ − 259
428
+ − 260 #ifndef VMS
+ − 261 exit (err_count > 0);
+ − 262 #endif /* VMS */
+ − 263 return err_count > 0;
+ − 264 }
+ − 265
+ − 266 /* Read file FILENAME and output its doc strings to outfile. */
+ − 267 /* Return 1 if file is not found, 0 if it is found. */
+ − 268
+ − 269 static int
442
+ − 270 scan_file (const char *filename)
428
+ − 271 {
+ − 272 int len = strlen (filename);
930
+ − 273
+ − 274 /* XEmacs change: test ellcc and set Current_file_type in each case */
428
+ − 275 if (ellcc == 0 && len > 4 && !strcmp (filename + len - 4, ".elc"))
+ − 276 {
+ − 277 Current_file_type = elc_file;
+ − 278 return scan_lisp_file (filename, READ_BINARY);
+ − 279 }
+ − 280 else if (ellcc == 0 && len > 3 && !strcmp (filename + len - 3, ".el"))
+ − 281 {
+ − 282 Current_file_type = el_file;
+ − 283 return scan_lisp_file (filename, READ_TEXT);
+ − 284 }
+ − 285 else
+ − 286 {
+ − 287 Current_file_type = c_file;
+ − 288 return scan_c_file (filename, READ_TEXT);
+ − 289 }
+ − 290 }
930
+ − 291
+ − 292 /* XEmacs addition: ISO 2022 handling */
814
+ − 293 static int
+ − 294 getc_skipping_iso2022 (FILE *file)
+ − 295 {
+ − 296 register int c;
+ − 297 /* #### Kludge -- Ignore any ISO2022 sequences */
+ − 298 c = getc (file);
+ − 299 while (c == 27)
+ − 300 {
+ − 301 c = getc (file);
+ − 302 if (c == '$')
+ − 303 c = getc (file);
+ − 304 if (c >= '(' && c <= '/')
+ − 305 c = getc (file);
+ − 306 c = getc (file);
+ − 307 }
+ − 308 return c;
+ − 309 }
+ − 310
+ − 311 enum iso2022_state
+ − 312 {
+ − 313 ISO_NOTHING,
+ − 314 ISO_ESC,
+ − 315 ISO_DOLLAR,
+ − 316 ISO_FINAL_IS_NEXT,
+ − 317 ISO_DOLLAR_AND_FINAL_IS_NEXT
+ − 318 };
+ − 319
+ − 320 static int non_ascii_p;
+ − 321
+ − 322 static int
+ − 323 getc_iso2022 (FILE *file)
+ − 324 {
+ − 325 /* #### Kludge -- Parse ISO2022 sequences (more or less) */
+ − 326 static enum iso2022_state state;
+ − 327 static int prevc;
+ − 328 register int c;
+ − 329 c = getc (file);
+ − 330 switch (state)
+ − 331 {
+ − 332 case ISO_NOTHING:
+ − 333 if (c == 27)
+ − 334 state = ISO_ESC;
+ − 335 break;
+ − 336
+ − 337 case ISO_ESC:
+ − 338 if (c == '$')
+ − 339 state = ISO_DOLLAR;
+ − 340 else if (c >= '(' && c <= '/')
+ − 341 state = ISO_FINAL_IS_NEXT;
+ − 342 else
+ − 343 state = ISO_NOTHING;
+ − 344 break;
+ − 345
+ − 346 case ISO_DOLLAR:
+ − 347 if (c >= '(' && c <= '/')
+ − 348 state = ISO_DOLLAR_AND_FINAL_IS_NEXT;
+ − 349 else if (c >= '@' && c <= 'B') /* ESC $ @ etc */
+ − 350 {
+ − 351 non_ascii_p = 1;
+ − 352 state = ISO_NOTHING;
+ − 353 }
+ − 354 else
+ − 355 state = ISO_NOTHING;
+ − 356 break;
+ − 357
+ − 358 case ISO_FINAL_IS_NEXT:
+ − 359 if (prevc == '(' && c == 'B') /* ESC ( B, invoke ASCII */
+ − 360 non_ascii_p = 0;
+ − 361 else if (prevc == '(' || prevc == ',') /* ESC ( x or ESC , x */
+ − 362 non_ascii_p = 1;
+ − 363 state = ISO_NOTHING;
+ − 364 break;
+ − 365
+ − 366 case ISO_DOLLAR_AND_FINAL_IS_NEXT:
+ − 367 if (prevc == '(' || prevc == ',') /* ESC $ ( x or ESC $ , x */
+ − 368 non_ascii_p = 1;
+ − 369 state = ISO_NOTHING;
+ − 370 break;
+ − 371 }
+ − 372
+ − 373 prevc = c;
+ − 374 return c;
+ − 375 }
+ − 376
428
+ − 377
1111
+ − 378 char globalbuf[128];
428
+ − 379
+ − 380 /* Skip a C string from INFILE,
930
+ − 381 and return the character that follows the closing ".
428
+ − 382 If printflag is positive, output string contents to outfile.
+ − 383 If it is negative, store contents in buf.
+ − 384 Convert escape sequences \n and \t to newline and tab;
+ − 385 discard \ followed by newline. */
+ − 386
814
+ − 387 #define MDGET do { prevc = c; c = getc_iso2022 (infile); } while (0)
428
+ − 388 static int
+ − 389 read_c_string (FILE *infile, int printflag, int c_docstring)
+ − 390 {
442
+ − 391 register int prevc = 0, c = 0;
1111
+ − 392 char *p = globalbuf;
930
+ − 393 int start = -1; /* XEmacs addition */
428
+ − 394
442
+ − 395 MDGET;
428
+ − 396 while (c != EOF)
+ − 397 {
814
+ − 398 while ((c_docstring || c != '"' || non_ascii_p) && c != EOF)
428
+ − 399 {
930
+ − 400 /* XEmacs addition: the first two "if" clauses are new */
814
+ − 401 if (c == '*' && !non_ascii_p)
428
+ − 402 {
442
+ − 403 int cc = getc (infile);
+ − 404 if (cc == '/')
428
+ − 405 {
442
+ − 406 if (prevc != '\n')
+ − 407 {
+ − 408 if (printflag > 0)
+ − 409 {
+ − 410 if (ellcc)
+ − 411 fprintf (outfile, "\\n\\");
+ − 412 putc ('\n', outfile);
+ − 413 }
+ − 414 else if (printflag < 0)
+ − 415 *p++ = '\n';
+ − 416 }
+ − 417 break;
428
+ − 418 }
442
+ − 419 else
+ − 420 ungetc (cc, infile);
+ − 421 }
428
+ − 422
442
+ − 423 if (start == 1)
+ − 424 {
+ − 425 if (printflag > 0)
428
+ − 426 {
442
+ − 427 if (ellcc)
+ − 428 fprintf (outfile, "\\n\\");
+ − 429 putc ('\n', outfile);
428
+ − 430 }
442
+ − 431 else if (printflag < 0)
+ − 432 *p++ = '\n';
428
+ − 433 }
930
+ − 434 /* End XEmacs addition */
428
+ − 435
814
+ − 436 if (c == '\\' && !non_ascii_p)
428
+ − 437 {
442
+ − 438 MDGET;
428
+ − 439 if (c == '\n')
+ − 440 {
442
+ − 441 MDGET;
428
+ − 442 start = 1;
+ − 443 continue;
+ − 444 }
+ − 445 if (!c_docstring && c == 'n')
+ − 446 c = '\n';
+ − 447 if (c == 't')
+ − 448 c = '\t';
+ − 449 }
930
+ − 450
+ − 451 /* XEmacs change: the "if" clause is new; the "else" clause is
+ − 452 mostly the original FSF Emacs code */
428
+ − 453 if (c == '\n')
+ − 454 start = 1;
+ − 455 else
+ − 456 {
+ − 457 start = 0;
442
+ − 458 if (printflag > 0)
+ − 459 {
814
+ − 460 if (ellcc && c == '"' && !non_ascii_p)
442
+ − 461 putc ('\\', outfile);
+ − 462 putc (c, outfile);
+ − 463 }
428
+ − 464 else if (printflag < 0)
+ − 465 *p++ = c;
+ − 466 }
442
+ − 467 MDGET;
428
+ − 468 }
930
+ − 469 /* XEmacs change: look for continuation of string */
428
+ − 470 if (Current_file_type == c_file)
+ − 471 {
442
+ − 472 do
+ − 473 {
+ − 474 MDGET;
+ − 475 }
+ − 476 while (isspace (c));
814
+ − 477 if (c != '"' || non_ascii_p)
428
+ − 478 break;
+ − 479 }
+ − 480 else
+ − 481 {
442
+ − 482 MDGET;
814
+ − 483 if (c != '"' || non_ascii_p)
428
+ − 484 break;
+ − 485 /* If we had a "", concatenate the two strings. */
+ − 486 }
442
+ − 487 MDGET;
428
+ − 488 }
930
+ − 489
428
+ − 490 if (printflag < 0)
+ − 491 *p = 0;
930
+ − 492
428
+ − 493 return c;
+ − 494 }
+ − 495
+ − 496 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
+ − 497 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
+ − 498
+ − 499 static void
2286
+ − 500 write_c_args (FILE *out, const char *UNUSED (func), char *buf,
+ − 501 int minargs, int maxargs)
428
+ − 502 {
+ − 503 register char *p;
+ − 504 int in_ident = 0;
+ − 505 int just_spaced = 0;
+ − 506 #if 0
+ − 507 int need_space = 1;
+ − 508
+ − 509 fprintf (out, "(%s", func);
+ − 510 #else
+ − 511 /* XEmacs - "arguments:" is for parsing the docstring. FSF's help system
+ − 512 doesn't parse the docstring for arguments like we do, so we're also
+ − 513 going to omit the function name to preserve compatibility with elisp
+ − 514 that parses the docstring. Finally, not prefixing the arglist with
+ − 515 anything is asking for trouble because it's not uncommon to have an
+ − 516 unescaped parenthesis at the beginning of a line. --Stig */
+ − 517 fprintf (out, "arguments: (");
+ − 518 #endif
+ − 519
930
+ − 520 if (*buf == '(')
+ − 521 ++buf;
428
+ − 522
930
+ − 523 for (p = buf; *p; p++)
428
+ − 524 {
+ − 525 char c = *p;
+ − 526 int ident_start = 0;
+ − 527
930
+ − 528 /* XEmacs addition: add support for ANSI prototypes. Hop over
428
+ − 529 "Lisp_Object" string (the only C type allowed in DEFUNs) */
+ − 530 static char lo[] = "Lisp_Object";
+ − 531 if ((C_IDENTIFIER_CHAR_P (c) != in_ident) && !in_ident &&
+ − 532 (strncmp (p, lo, sizeof (lo) - 1) == 0) &&
930
+ − 533 isspace ((unsigned char) p[sizeof (lo) - 1]))
428
+ − 534 {
+ − 535 p += (sizeof (lo) - 1);
438
+ − 536 while (isspace ((unsigned char) (*p)))
428
+ − 537 p++;
+ − 538 c = *p;
+ − 539 }
+ − 540
+ − 541 /* Notice when we start printing a new identifier. */
+ − 542 if (C_IDENTIFIER_CHAR_P (c) != in_ident)
+ − 543 {
+ − 544 if (!in_ident)
+ − 545 {
+ − 546 in_ident = 1;
+ − 547 ident_start = 1;
+ − 548 #if 0
+ − 549 /* XEmacs - This goes along with the change above. */
+ − 550 if (need_space)
+ − 551 putc (' ', out);
+ − 552 #endif
+ − 553 if (minargs == 0 && maxargs > 0)
+ − 554 fprintf (out, "&optional ");
+ − 555 just_spaced = 1;
+ − 556
+ − 557 minargs--;
+ − 558 maxargs--;
+ − 559 }
+ − 560 else
+ − 561 in_ident = 0;
+ − 562 }
+ − 563
+ − 564 /* Print the C argument list as it would appear in lisp:
930
+ − 565 print underscores as hyphens, and print commas and newlines
+ − 566 as spaces. Collapse adjacent spaces into one. */
+ − 567 if (c == '_')
+ − 568 c = '-';
1618
+ − 569 else if (c == ',' /* || c == '\n' */)
930
+ − 570 c = ' ';
1618
+ − 571 /* XEmacs change: handle \n below for readability */
428
+ − 572
930
+ − 573 #if 0
+ − 574 /* In C code, `default' is a reserved word, so we spell it
+ − 575 `defalt'; unmangle that here. */
+ − 576 if (ident_start
+ − 577 && strncmp (p, "defalt", 6) == 0
+ − 578 && ! (('A' <= p[6] && p[6] <= 'Z')
+ − 579 || ('a' <= p[6] && p[6] <= 'z')
+ − 580 || ('0' <= p[6] && p[6] <= '9')
+ − 581 || p[6] == '_'))
+ − 582 {
+ − 583 fprintf (out, "DEFAULT");
+ − 584 p += 5;
+ − 585 in_ident = 0;
+ − 586 just_spaced = 0;
+ − 587 }
+ − 588 #endif
428
+ − 589 /* If the C argument name ends with `_', change it to ' ',
+ − 590 to allow use of C reserved words or global symbols as Lisp args. */
+ − 591 if (c == '-' && ! C_IDENTIFIER_CHAR_P (p[1]))
+ − 592 {
+ − 593 in_ident = 0;
+ − 594 just_spaced = 0;
+ − 595 }
1618
+ − 596 /* XEmacs change: if the character is carriage return or linefeed,
+ − 597 escape it for the compiler */
+ − 598 else if (c == '\n')
+ − 599 {
+ − 600 putc('\\', out);
+ − 601 putc('\n', out);
+ − 602 }
+ − 603 else if (c == '\r')
+ − 604 {
+ − 605 putc('\\', out);
+ − 606 putc('\r', out);
+ − 607 }
930
+ − 608 else if (c != ' ' || !just_spaced)
428
+ − 609 {
+ − 610 if (c >= 'a' && c <= 'z')
+ − 611 /* Upcase the letter. */
+ − 612 c += 'A' - 'a';
+ − 613 putc (c, out);
+ − 614 }
+ − 615
+ − 616 just_spaced = (c == ' ');
+ − 617 #if 0
+ − 618 need_space = 0;
+ − 619 #endif
+ − 620 }
930
+ − 621 /* XEmacs addition */
428
+ − 622 if (!ellcc)
930
+ − 623 putc ('\n', out);
428
+ − 624 }
+ − 625
771
+ − 626 /* Read through a c file. If a .o or .obj file is named,
428
+ − 627 the corresponding .c file is read instead.
+ − 628 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
930
+ − 629 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED ...
+ − 630 which don't exist anymore! */
428
+ − 631
+ − 632 static int
442
+ − 633 scan_c_file (const char *filename, const char *mode)
428
+ − 634 {
+ − 635 FILE *infile;
+ − 636 register int c;
+ − 637 register int commas;
+ − 638 register int defunflag;
+ − 639 register int defvarperbufferflag = 0;
+ − 640 register int defvarflag;
+ − 641 int minargs, maxargs;
+ − 642 int l = strlen (filename);
2421
+ − 643 char f[QXE_PATH_MAX];
428
+ − 644
930
+ − 645 /* XEmacs change: different method for checking filename extension */
2421
+ − 646 if (l > QXE_PATH_MAX - 1)
647
+ − 647 {
428
+ − 648 #ifdef ENAMETOOLONG
647
+ − 649 errno = ENAMETOOLONG;
428
+ − 650 #else
647
+ − 651 errno = EINVAL;
428
+ − 652 #endif
930
+ − 653 return 0;
647
+ − 654 }
428
+ − 655
+ − 656 strcpy (f, filename);
771
+ − 657 if (l > 4 && !strcmp (f + l - 4, ".obj")) /* MS Windows */
+ − 658 strcpy (f + l - 4, ".c");
428
+ − 659 if (f[l - 1] == 'o')
+ − 660 f[l - 1] = 'c';
+ − 661 infile = fopen (f, mode);
+ − 662
+ − 663 /* No error if non-ex input file */
+ − 664 if (infile == NULL)
+ − 665 {
+ − 666 perror (f);
+ − 667 return 0;
+ − 668 }
+ − 669
930
+ − 670 #if 0
+ − 671 /* Reset extension to be able to detect duplicate files. */
+ − 672 filename[strlen (filename) - 1] = extension;
+ − 673 #endif
+ − 674
428
+ − 675 c = '\n';
+ − 676 while (!feof (infile))
+ − 677 {
+ − 678 if (c != '\n')
+ − 679 {
+ − 680 c = getc (infile);
+ − 681 continue;
+ − 682 }
+ − 683 c = getc (infile);
+ − 684 if (c == ' ')
+ − 685 {
+ − 686 while (c == ' ')
+ − 687 c = getc (infile);
+ − 688 if (c != 'D')
+ − 689 continue;
+ − 690 c = getc (infile);
+ − 691 if (c != 'E')
+ − 692 continue;
+ − 693 c = getc (infile);
+ − 694 if (c != 'F')
+ − 695 continue;
+ − 696 c = getc (infile);
+ − 697 if (c != 'V')
+ − 698 continue;
+ − 699 c = getc (infile);
+ − 700 if (c != 'A')
+ − 701 continue;
+ − 702 c = getc (infile);
+ − 703 if (c != 'R')
+ − 704 continue;
+ − 705 c = getc (infile);
+ − 706 if (c != '_')
+ − 707 continue;
+ − 708
+ − 709 defvarflag = 1;
+ − 710 defunflag = 0;
+ − 711
+ − 712 c = getc (infile);
+ − 713 /* Note that this business doesn't apply under XEmacs.
+ − 714 DEFVAR_BUFFER_LOCAL in XEmacs behaves normally. */
+ − 715 defvarperbufferflag = (c == 'P');
+ − 716
+ − 717 c = getc (infile);
+ − 718 }
+ − 719 else if (c == 'D')
+ − 720 {
+ − 721 c = getc (infile);
+ − 722 if (c != 'E')
+ − 723 continue;
+ − 724 c = getc (infile);
+ − 725 if (c != 'F')
+ − 726 continue;
+ − 727 c = getc (infile);
+ − 728 defunflag = (c == 'U');
+ − 729 defvarflag = 0;
930
+ − 730 c = getc (infile); /* XEmacs addition */
428
+ − 731 }
+ − 732 else continue;
+ − 733
+ − 734 while (c != '(')
+ − 735 {
+ − 736 if (c < 0)
+ − 737 goto eof;
+ − 738 c = getc (infile);
+ − 739 }
+ − 740
+ − 741 c = getc (infile);
+ − 742 if (c != '"')
+ − 743 continue;
+ − 744 c = read_c_string (infile, -1, 0);
+ − 745
+ − 746 if (defunflag)
+ − 747 commas = 4;
+ − 748 else if (defvarperbufferflag)
+ − 749 commas = 2;
+ − 750 else if (defvarflag)
+ − 751 commas = 1;
930
+ − 752 else /* For DEFSIMPLE and DEFPRED ... which now don't exist! */
428
+ − 753 commas = 2;
+ − 754
+ − 755 while (commas)
+ − 756 {
+ − 757 if (c == ',')
+ − 758 {
+ − 759 commas--;
+ − 760 if (defunflag && (commas == 1 || commas == 2))
+ − 761 {
+ − 762 do
+ − 763 c = getc (infile);
930
+ − 764 while (c == ' ' || c == '\n' || c == '\t');
428
+ − 765 if (c < 0)
+ − 766 goto eof;
+ − 767 ungetc (c, infile);
+ − 768 if (commas == 2) /* pick up minargs */
+ − 769 fscanf (infile, "%d", &minargs);
930
+ − 770 else /* pick up maxargs */
428
+ − 771 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
+ − 772 maxargs = -1;
+ − 773 else
+ − 774 fscanf (infile, "%d", &maxargs);
+ − 775 }
+ − 776 }
+ − 777 if (c < 0)
+ − 778 goto eof;
+ − 779 c = getc (infile);
+ − 780 }
+ − 781 while (c == ' ' || c == '\n' || c == '\t')
+ − 782 c = getc (infile);
+ − 783 if (c == '"')
+ − 784 c = read_c_string (infile, 0, 0);
930
+ − 785 /* XEmacs change */
428
+ − 786 if (defunflag | defvarflag)
+ − 787 {
+ − 788 while (c != '/')
853
+ − 789 {
+ − 790 if (c < 0)
+ − 791 goto eof;
930
+ − 792 if (defunflag && c == '(')
1111
+ − 793 fatal ("Missing doc string for DEFUN %s\n", globalbuf);
853
+ − 794 c = getc (infile);
+ − 795 }
428
+ − 796 c = getc (infile);
+ − 797 while (c == '*')
+ − 798 c = getc (infile);
+ − 799 }
+ − 800 else
+ − 801 {
+ − 802 while (c != ',')
853
+ − 803 {
+ − 804 if (c < 0)
+ − 805 goto eof;
+ − 806 c = getc (infile);
+ − 807 }
428
+ − 808 c = getc (infile);
+ − 809 }
930
+ − 810 /* End XEmacs change */
428
+ − 811 while (c == ' ' || c == '\n' || c == '\t')
+ − 812 c = getc (infile);
930
+ − 813 /* XEmacs addition */
428
+ − 814 if (defunflag | defvarflag)
+ − 815 ungetc (c, infile);
930
+ − 816 /* End XEmacs addition */
428
+ − 817
+ − 818 if (defunflag || defvarflag || c == '"')
+ − 819 {
930
+ − 820 /* XEmacs change: the original code is in the "else" clause */
814
+ − 821 if (ellcc)
+ − 822 fprintf (outfile, " CDOC%s(\"%s\", \"\\\n",
1111
+ − 823 defvarflag ? "SYM" : "SUBR", globalbuf);
814
+ − 824 else
+ − 825 {
+ − 826 putc (037, outfile);
+ − 827 putc (defvarflag ? 'V' : 'F', outfile);
1111
+ − 828 fprintf (outfile, "%s\n", globalbuf);
814
+ − 829 }
930
+ − 830 c = read_c_string (infile, 1, defunflag || defvarflag);
428
+ − 831
+ − 832 /* If this is a defun, find the arguments and print them. If
+ − 833 this function takes MANY or UNEVALLED args, then the C source
+ − 834 won't give the names of the arguments, so we shouldn't bother
+ − 835 trying to find them. */
+ − 836 if (defunflag && maxargs != -1)
+ − 837 {
+ − 838 char argbuf[1024], *p = argbuf;
814
+ − 839 #if 0 /* For old DEFUN's only */
428
+ − 840 while (c != ')')
+ − 841 {
+ − 842 if (c < 0)
+ − 843 goto eof;
+ − 844 c = getc (infile);
+ − 845 }
+ − 846 #endif
+ − 847 /* Skip into arguments. */
+ − 848 while (c != '(')
+ − 849 {
+ − 850 if (c < 0)
+ − 851 goto eof;
+ − 852 c = getc (infile);
+ − 853 }
+ − 854 /* Copy arguments into ARGBUF. */
+ − 855 *p++ = c;
+ − 856 do
853
+ − 857 {
+ − 858 *p++ = c = getc (infile);
+ − 859 if (c < 0)
+ − 860 goto eof;
+ − 861 }
428
+ − 862 while (c != ')');
+ − 863 *p = '\0';
+ − 864 /* Output them. */
814
+ − 865 if (ellcc)
+ − 866 fprintf (outfile, "\\n\\\n\\n\\\n");
+ − 867 else
+ − 868 fprintf (outfile, "\n\n");
1111
+ − 869 write_c_args (outfile, globalbuf, argbuf, minargs, maxargs);
428
+ − 870 }
814
+ − 871 if (ellcc)
+ − 872 fprintf (outfile, "\\n\");\n\n");
428
+ − 873 }
+ − 874 }
+ − 875 eof:
+ − 876 fclose (infile);
+ − 877 return 0;
+ − 878 }
+ − 879
+ − 880 /* Read a file of Lisp code, compiled or interpreted.
930
+ − 881 Looks for
+ − 882 (defun NAME ARGS DOCSTRING ...)
+ − 883 (defmacro NAME ARGS DOCSTRING ...)
+ − 884 (defsubst NAME ARGS DOCSTRING ...)
+ − 885 (autoload (quote NAME) FILE DOCSTRING ...)
+ − 886 (defvar NAME VALUE DOCSTRING)
+ − 887 (defconst NAME VALUE DOCSTRING)
+ − 888 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
+ − 889 (fset (quote NAME) #[... DOCSTRING ...])
+ − 890 (defalias (quote NAME) #[... DOCSTRING ...])
+ − 891 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
+ − 892 starting in column zero.
+ − 893 (quote NAME) may appear as 'NAME as well.
428
+ − 894
+ − 895 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
+ − 896 When we find that, we save it for the following defining-form,
+ − 897 and we use that instead of reading a doc string within that defining-form.
+ − 898
930
+ − 899 For defvar, defconst, and fset we skip to the docstring with a kludgy
428
+ − 900 formatting convention: all docstrings must appear on the same line as the
930
+ − 901 initial open-paren (the one in column zero) and must contain a backslash
+ − 902 and a newline immediately after the initial double-quote. No newlines
428
+ − 903 must appear between the beginning of the form and the first double-quote.
930
+ − 904 For defun, defmacro, and autoload, we know how to skip over the
+ − 905 arglist, but the doc string must still have a backslash and newline
+ − 906 immediately after the double quote.
+ − 907 The only source files that must follow this convention are preloaded
+ − 908 uncompiled ones like loaddefs.el and bindings.el; aside
428
+ − 909 from that, it is always the .elc file that we look at, and they are no
+ − 910 problem because byte-compiler output follows this convention.
+ − 911 The NAME and DOCSTRING are output.
+ − 912 NAME is preceded by `F' for a function or `V' for a variable.
+ − 913 An entry is output only if DOCSTRING has \ newline just after the opening "
+ − 914 */
+ − 915
+ − 916 static void
+ − 917 skip_white (FILE *infile)
+ − 918 {
+ − 919 char c = ' ';
+ − 920 while (c == ' ' || c == '\t' || c == '\n')
+ − 921 c = getc (infile);
+ − 922 ungetc (c, infile);
+ − 923 }
+ − 924
+ − 925 static void
+ − 926 read_lisp_symbol (FILE *infile, char *buffer)
+ − 927 {
+ − 928 char c;
+ − 929 char *fillp = buffer;
+ − 930
+ − 931 skip_white (infile);
+ − 932 while (1)
+ − 933 {
+ − 934 c = getc (infile);
+ − 935 if (c == '\\')
+ − 936 /* FSF has *(++fillp), which is wrong. */
+ − 937 *fillp++ = getc (infile);
+ − 938 else if (c == ' ' || c == '\t' || c == '\n' || c == '(' || c == ')')
+ − 939 {
+ − 940 ungetc (c, infile);
+ − 941 *fillp = 0;
+ − 942 break;
+ − 943 }
+ − 944 else
+ − 945 *fillp++ = c;
+ − 946 }
+ − 947
+ − 948 if (! buffer[0])
+ − 949 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
814
+ − 950
428
+ − 951 skip_white (infile);
+ − 952 }
+ − 953
+ − 954 static int
442
+ − 955 scan_lisp_file (const char *filename, const char *mode)
428
+ − 956 {
+ − 957 FILE *infile;
+ − 958 register int c;
+ − 959 char *saved_string = 0;
+ − 960
+ − 961 infile = fopen (filename, mode);
+ − 962 if (infile == NULL)
+ − 963 {
+ − 964 perror (filename);
930
+ − 965 return 0; /* No error */
428
+ − 966 }
+ − 967
+ − 968 c = '\n';
+ − 969 while (!feof (infile))
+ − 970 {
+ − 971 char buffer[BUFSIZ];
+ − 972 char type;
+ − 973
930
+ − 974 /* If not at end of line, skip till we get to one. */
428
+ − 975 if (c != '\n')
+ − 976 {
814
+ − 977 c = getc_skipping_iso2022 (infile);
428
+ − 978 continue;
+ − 979 }
930
+ − 980 /* Skip the line break. */
+ − 981 while (c == '\n')
+ − 982 c = getc_skipping_iso2022 (infile);
428
+ − 983 /* Detect a dynamic doc string and save it for the next expression. */
+ − 984 if (c == '#')
+ − 985 {
814
+ − 986 c = getc_skipping_iso2022 (infile);
428
+ − 987 if (c == '@')
+ − 988 {
+ − 989 int length = 0;
+ − 990 int i;
+ − 991
+ − 992 /* Read the length. */
814
+ − 993 while ((c = getc_skipping_iso2022 (infile),
428
+ − 994 c >= '0' && c <= '9'))
+ − 995 {
+ − 996 length *= 10;
+ − 997 length += c - '0';
+ − 998 }
+ − 999
+ − 1000 /* The next character is a space that is counted in the length
+ − 1001 but not part of the doc string.
+ − 1002 We already read it, so just ignore it. */
+ − 1003 length--;
+ − 1004
+ − 1005 /* Read in the contents. */
+ − 1006 if (saved_string != 0)
+ − 1007 free (saved_string);
+ − 1008 saved_string = (char *) xmalloc (length);
+ − 1009 for (i = 0; i < length; i++)
+ − 1010 saved_string[i] = getc (infile);
+ − 1011 /* The last character is a ^_.
+ − 1012 That is needed in the .elc file
+ − 1013 but it is redundant in DOC. So get rid of it here. */
+ − 1014 saved_string[length - 1] = 0;
930
+ − 1015 /* Skip the line break. */
+ − 1016 while (c == '\n')
+ − 1017 c = getc_skipping_iso2022 (infile);
+ − 1018 /* Skip the following line. */
428
+ − 1019 while (c != '\n')
930
+ − 1020 c = getc_skipping_iso2022 (infile);
428
+ − 1021 }
+ − 1022 continue;
+ − 1023 }
+ − 1024
+ − 1025 if (c != '(')
+ − 1026 continue;
+ − 1027
+ − 1028 read_lisp_symbol (infile, buffer);
+ − 1029
930
+ − 1030 if (! strcmp (buffer, "defun")
+ − 1031 || ! strcmp (buffer, "defmacro")
+ − 1032 || ! strcmp (buffer, "defsubst"))
428
+ − 1033 {
+ − 1034 type = 'F';
+ − 1035 read_lisp_symbol (infile, buffer);
+ − 1036
+ − 1037 /* Skip the arguments: either "nil" or a list in parens */
+ − 1038
814
+ − 1039 c = getc_skipping_iso2022 (infile);
930
+ − 1040 if (c == 'n') /* nil */
428
+ − 1041 {
814
+ − 1042 if ((c = getc_skipping_iso2022 (infile)) != 'i' ||
+ − 1043 (c = getc_skipping_iso2022 (infile)) != 'l')
428
+ − 1044 {
+ − 1045 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
+ − 1046 buffer, filename);
+ − 1047 continue;
+ − 1048 }
+ − 1049 }
+ − 1050 else if (c != '(')
+ − 1051 {
+ − 1052 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
+ − 1053 buffer, filename);
+ − 1054 continue;
+ − 1055 }
+ − 1056 else
+ − 1057 while (c != ')')
853
+ − 1058 {
+ − 1059 c = getc_skipping_iso2022 (infile);
+ − 1060 if (c < 0)
+ − 1061 continue;
+ − 1062 }
428
+ − 1063 skip_white (infile);
+ − 1064
+ − 1065 /* If the next three characters aren't `dquote bslash newline'
+ − 1066 then we're not reading a docstring.
930
+ − 1067 */
814
+ − 1068 if ((c = getc_skipping_iso2022 (infile)) != '"' ||
+ − 1069 (c = getc_skipping_iso2022 (infile)) != '\\' ||
+ − 1070 (c = getc_skipping_iso2022 (infile)) != '\n')
428
+ − 1071 {
+ − 1072 #ifdef DEBUG
+ − 1073 fprintf (stderr, "## non-docstring in %s (%s)\n",
+ − 1074 buffer, filename);
+ − 1075 #endif
+ − 1076 continue;
+ − 1077 }
+ − 1078 }
+ − 1079
930
+ − 1080 else if (! strcmp (buffer, "defvar")
+ − 1081 || ! strcmp (buffer, "defconst"))
428
+ − 1082 {
+ − 1083 char c1 = 0, c2 = 0;
+ − 1084 type = 'V';
+ − 1085 read_lisp_symbol (infile, buffer);
+ − 1086
+ − 1087 if (saved_string == 0)
+ − 1088 {
+ − 1089
930
+ − 1090 /* Skip until the end of line; remember two previous chars. */
428
+ − 1091 while (c != '\n' && c >= 0)
+ − 1092 {
+ − 1093 c2 = c1;
+ − 1094 c1 = c;
814
+ − 1095 c = getc_skipping_iso2022 (infile);
428
+ − 1096 }
930
+ − 1097
+ − 1098 /* If two previous characters were " and \,
+ − 1099 this is a doc string. Otherwise, there is none. */
+ − 1100 if (c2 != '"' || c1 != '\\')
+ − 1101 {
+ − 1102 #ifdef DEBUG
+ − 1103 fprintf (stderr, "## non-docstring in %s (%s)\n",
+ − 1104 buffer, filename);
+ − 1105 #endif
+ − 1106 continue;
+ − 1107 }
+ − 1108 }
+ − 1109 }
428
+ − 1110
930
+ − 1111 else if (! strcmp (buffer, "custom-declare-variable"))
+ − 1112 {
+ − 1113 char c1 = 0, c2 = 0;
+ − 1114 type = 'V';
+ − 1115
+ − 1116 c = getc (infile);
+ − 1117 if (c == '\'')
+ − 1118 read_lisp_symbol (infile, buffer);
+ − 1119 else
+ − 1120 {
+ − 1121 if (c != '(')
+ − 1122 {
+ − 1123 fprintf (stderr,
+ − 1124 "## unparsable name in custom-declare-variable in %s\n",
+ − 1125 filename);
+ − 1126 continue;
+ − 1127 }
+ − 1128 read_lisp_symbol (infile, buffer);
+ − 1129 if (strcmp (buffer, "quote"))
+ − 1130 {
+ − 1131 fprintf (stderr,
+ − 1132 "## unparsable name in custom-declare-variable in %s\n",
+ − 1133 filename);
+ − 1134 continue;
+ − 1135 }
+ − 1136 read_lisp_symbol (infile, buffer);
+ − 1137 c = getc (infile);
+ − 1138 if (c != ')')
+ − 1139 {
+ − 1140 fprintf (stderr,
+ − 1141 "## unparsable quoted name in custom-declare-variable in %s\n",
+ − 1142 filename);
+ − 1143 continue;
+ − 1144 }
+ − 1145 }
+ − 1146
+ − 1147 if (saved_string == 0)
+ − 1148 {
+ − 1149 /* Skip to end of line; remember the two previous chars. */
+ − 1150 while (c != '\n' && c >= 0)
+ − 1151 {
+ − 1152 c2 = c1;
+ − 1153 c1 = c;
+ − 1154 c = getc_skipping_iso2022 (infile);
+ − 1155 }
+ − 1156
428
+ − 1157 /* If two previous characters were " and \,
+ − 1158 this is a doc string. Otherwise, there is none. */
+ − 1159 if (c2 != '"' || c1 != '\\')
+ − 1160 {
+ − 1161 #ifdef DEBUG
+ − 1162 fprintf (stderr, "## non-docstring in %s (%s)\n",
+ − 1163 buffer, filename);
+ − 1164 #endif
+ − 1165 continue;
+ − 1166 }
+ − 1167 }
+ − 1168 }
+ − 1169
+ − 1170 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
+ − 1171 {
+ − 1172 char c1 = 0, c2 = 0;
+ − 1173 type = 'F';
+ − 1174
814
+ − 1175 c = getc_skipping_iso2022 (infile);
428
+ − 1176 if (c == '\'')
+ − 1177 read_lisp_symbol (infile, buffer);
+ − 1178 else
+ − 1179 {
+ − 1180 if (c != '(')
+ − 1181 {
+ − 1182 fprintf (stderr, "## unparsable name in fset in %s\n",
+ − 1183 filename);
+ − 1184 continue;
+ − 1185 }
+ − 1186 read_lisp_symbol (infile, buffer);
+ − 1187 if (strcmp (buffer, "quote"))
+ − 1188 {
+ − 1189 fprintf (stderr, "## unparsable name in fset in %s\n",
+ − 1190 filename);
+ − 1191 continue;
+ − 1192 }
+ − 1193 read_lisp_symbol (infile, buffer);
814
+ − 1194 c = getc_skipping_iso2022 (infile);
428
+ − 1195 if (c != ')')
+ − 1196 {
+ − 1197 fprintf (stderr,
+ − 1198 "## unparsable quoted name in fset in %s\n",
+ − 1199 filename);
+ − 1200 continue;
+ − 1201 }
+ − 1202 }
+ − 1203
+ − 1204 if (saved_string == 0)
+ − 1205 {
930
+ − 1206 /* Skip to end of line; remember the two previous chars. */
428
+ − 1207 while (c != '\n' && c >= 0)
+ − 1208 {
+ − 1209 c2 = c1;
+ − 1210 c1 = c;
814
+ − 1211 c = getc_skipping_iso2022 (infile);
428
+ − 1212 }
930
+ − 1213
428
+ − 1214 /* If two previous characters were " and \,
+ − 1215 this is a doc string. Otherwise, there is none. */
+ − 1216 if (c2 != '"' || c1 != '\\')
+ − 1217 {
+ − 1218 #ifdef DEBUG
+ − 1219 fprintf (stderr, "## non-docstring in %s (%s)\n",
+ − 1220 buffer, filename);
+ − 1221 #endif
+ − 1222 continue;
+ − 1223 }
+ − 1224 }
+ − 1225 }
+ − 1226
+ − 1227 else if (! strcmp (buffer, "autoload"))
+ − 1228 {
+ − 1229 type = 'F';
814
+ − 1230 c = getc_skipping_iso2022 (infile);
428
+ − 1231 if (c == '\'')
+ − 1232 read_lisp_symbol (infile, buffer);
+ − 1233 else
+ − 1234 {
+ − 1235 if (c != '(')
+ − 1236 {
+ − 1237 fprintf (stderr, "## unparsable name in autoload in %s\n",
+ − 1238 filename);
+ − 1239 continue;
+ − 1240 }
+ − 1241 read_lisp_symbol (infile, buffer);
+ − 1242 if (strcmp (buffer, "quote"))
+ − 1243 {
+ − 1244 fprintf (stderr, "## unparsable name in autoload in %s\n",
+ − 1245 filename);
+ − 1246 continue;
+ − 1247 }
+ − 1248 read_lisp_symbol (infile, buffer);
814
+ − 1249 c = getc_skipping_iso2022 (infile);
428
+ − 1250 if (c != ')')
+ − 1251 {
+ − 1252 fprintf (stderr,
+ − 1253 "## unparsable quoted name in autoload in %s\n",
+ − 1254 filename);
+ − 1255 continue;
+ − 1256 }
+ − 1257 }
+ − 1258 skip_white (infile);
814
+ − 1259 if ((c = getc_skipping_iso2022 (infile)) != '\"')
428
+ − 1260 {
+ − 1261 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
+ − 1262 buffer, filename);
+ − 1263 continue;
+ − 1264 }
+ − 1265 read_c_string (infile, 0, 0);
+ − 1266 skip_white (infile);
+ − 1267
+ − 1268 if (saved_string == 0)
+ − 1269 {
+ − 1270 /* If the next three characters aren't `dquote bslash newline'
+ − 1271 then we're not reading a docstring. */
814
+ − 1272 if ((c = getc_skipping_iso2022 (infile)) != '"' ||
+ − 1273 (c = getc_skipping_iso2022 (infile)) != '\\' ||
+ − 1274 (c = getc_skipping_iso2022 (infile)) != '\n')
428
+ − 1275 {
+ − 1276 #ifdef DEBUG
+ − 1277 fprintf (stderr, "## non-docstring in %s (%s)\n",
+ − 1278 buffer, filename);
+ − 1279 #endif
+ − 1280 continue;
+ − 1281 }
+ − 1282 }
+ − 1283 }
+ − 1284
814
+ − 1285 #if 0 /* causes crash */
930
+ − 1286 else if (! strcmp (buffer, "if")
+ − 1287 || ! strcmp (buffer, "byte-code"))
428
+ − 1288 ;
+ − 1289 #endif
+ − 1290
+ − 1291 else
+ − 1292 {
+ − 1293 #ifdef DEBUG
+ − 1294 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
+ − 1295 buffer, filename);
+ − 1296 #endif
+ − 1297 continue;
+ − 1298 }
+ − 1299
+ − 1300 /* At this point, we should either use the previous
+ − 1301 dynamic doc string in saved_string
+ − 1302 or gobble a doc string from the input file.
930
+ − 1303
428
+ − 1304 In the latter case, the opening quote (and leading
+ − 1305 backslash-newline) have already been read. */
930
+ − 1306
814
+ − 1307 putc ('\n', outfile); /* XEmacs addition */
428
+ − 1308 putc (037, outfile);
+ − 1309 putc (type, outfile);
+ − 1310 fprintf (outfile, "%s\n", buffer);
+ − 1311 if (saved_string)
+ − 1312 {
+ − 1313 fputs (saved_string, outfile);
+ − 1314 /* Don't use one dynamic doc string twice. */
+ − 1315 free (saved_string);
+ − 1316 saved_string = 0;
+ − 1317 }
+ − 1318 else
+ − 1319 read_c_string (infile, 1, 0);
+ − 1320 }
+ − 1321 fclose (infile);
+ − 1322 return 0;
+ − 1323 }