aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorJim Blandy1992-07-08 22:47:39 +0000
committerJim Blandy1992-07-08 22:47:39 +0000
commit23d6b5a6ee9ddd1d6bffe06d4b73e7ec16e0396f (patch)
tree94e62f3af94e981b958884ce6336708390baa5d5 /lib-src
parentbe53b4110027210bd96008798b29478b6701e11d (diff)
downloademacs-23d6b5a6ee9ddd1d6bffe06d4b73e7ec16e0396f.tar.gz
emacs-23d6b5a6ee9ddd1d6bffe06d4b73e7ec16e0396f.zip
*** empty log message ***
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/make-docfile.c568
1 files changed, 221 insertions, 347 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index d8e9377f321..676f29cb9c7 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -348,35 +348,74 @@ scan_c_file (filename)
348/* Read a file of Lisp code, compiled or interpreted. 348/* Read a file of Lisp code, compiled or interpreted.
349 Looks for 349 Looks for
350 (defun NAME ARGS DOCSTRING ...) 350 (defun NAME ARGS DOCSTRING ...)
351 (autoload 'NAME FILE DOCSTRING ...) 351 (defmacro NAME ARGS DOCSTRING ...)
352 (autoload (quote NAME) FILE DOCSTRING ...)
352 (defvar NAME VALUE DOCSTRING) 353 (defvar NAME VALUE DOCSTRING)
353 (defconst NAME VALUE DOCSTRING) 354 (defconst NAME VALUE DOCSTRING)
354 (fset (quote NAME) (make-byte-code (quote ARGS) ... "\ 355 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
355 DOCSTRING") 356 (fset (quote NAME) #[... DOCSTRING ...])
356 starting in column zero. 357 starting in column zero.
357 ARGS, FILE or VALUE is ignored. We do not know how to parse Lisp code 358 (quote NAME) may appear as 'NAME as well.
358 so we use a kludge to skip them: 359 For defun, defmacro, and autoload, we know how to skip over the arglist.
359 In a function definition, the form of ARGS of FILE is known, and we 360 For defvar, defconst, and fset we skip to the docstring with a klugey
360 can skip it. 361 formatting convention: all docstrings must appear on the same line as the
361 In a variable definition, we use a formatting convention: 362 initial open-paren (the one in column zero) and must contain a backslash
362 the DOCSTRING, if present, must be followed by a closeparen and a newline, 363 and a double-quote immediately after the initial double-quote. No newlines
363 and no newline must appear between the defvar or defconst and the docstring, 364 must appear between the beginning of the form and the first double-quote.
364 The only source file that must follow this convention is loaddefs.el; 365 The only source file that must follow this convention is loaddefs.el; aside
365 aside from that, it is always the .elc file that we look at, and 366 from that, it is always the .elc file that we look at, and they are no
366 they are no problem because byte-compiler output follows this convention. 367 problem because byte-compiler output follows this convention.
367 The NAME and DOCSTRING are output. 368 The NAME and DOCSTRING are output.
368 NAME is preceded by `F' for a function or `V' for a variable. 369 NAME is preceded by `F' for a function or `V' for a variable.
369 An entry is output only if DOCSTRING has \ newline just after the opening " 370 An entry is output only if DOCSTRING has \ newline just after the opening "
370 */ 371 */
371 372
373void
374skip_white (infile)
375 FILE *infile;
376{
377 char c = ' ';
378 while (c == ' ' || c == '\t' || c == '\n')
379 c = getc (infile);
380 ungetc (c, infile);
381}
382
383void
384read_lisp_symbol (infile, buffer)
385 FILE *infile;
386 char *buffer;
387{
388 char c;
389 char *fillp = buffer;
390
391 skip_white (infile);
392 while (1)
393 {
394 c = getc (infile);
395 if (c == '\\')
396 *(++fillp) = getc (infile);
397 else if (c == ' ' || c == '\t' || c == '\n' || c == '(' || c == ')')
398 {
399 ungetc (c, infile);
400 *fillp = 0;
401 break;
402 }
403 else
404 *fillp++ = c;
405 }
406
407 if (! buffer[0])
408 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
409
410 skip_white (infile);
411}
412
413
372scan_lisp_file (filename) 414scan_lisp_file (filename)
373 char *filename; 415 char *filename;
374{ 416{
375 FILE *infile; 417 FILE *infile;
376 register int c; 418 register int c;
377 register int commas;
378 register char *p;
379 int defvarflag;
380 419
381 infile = fopen (filename, "r"); 420 infile = fopen (filename, "r");
382 if (infile == NULL) 421 if (infile == NULL)
@@ -388,6 +427,10 @@ scan_lisp_file (filename)
388 c = '\n'; 427 c = '\n';
389 while (!feof (infile)) 428 while (!feof (infile))
390 { 429 {
430 char buffer [BUFSIZ];
431 char *fillp = buffer;
432 char type;
433
391 if (c != '\n') 434 if (c != '\n')
392 { 435 {
393 c = getc (infile); 436 c = getc (infile);
@@ -397,382 +440,213 @@ scan_lisp_file (filename)
397 if (c != '(') 440 if (c != '(')
398 continue; 441 continue;
399 442
400 /* Handle an autoload. */ 443 read_lisp_symbol (infile, buffer);
401 c = getc (infile); 444
402 if (c == 'a') 445 if (! strcmp (buffer, "defun") ||
446 ! strcmp (buffer, "defmacro"))
403 { 447 {
404 c = getc (infile); 448 type = 'F';
405 if (c != 'u') 449 read_lisp_symbol (infile, buffer);
406 continue;
407 c = getc (infile);
408 if (c != 't')
409 continue;
410 c = getc (infile);
411 if (c != 'o')
412 continue;
413 c = getc (infile);
414 if (c != 'l')
415 continue;
416 c = getc (infile);
417 if (c != 'o')
418 continue;
419 c = getc (infile);
420 if (c != 'a')
421 continue;
422 c = getc (infile);
423 if (c != 'd')
424 continue;
425 450
426 c = getc (infile); 451 /* Skip the arguments: either "nil" or a list in parens */
427 while (c == ' ')
428 c = getc (infile);
429 452
430 if (c == '\'') 453 c = getc (infile);
454 if (c == 'n') /* nil */
431 { 455 {
432 c = getc (infile); 456 if ((c = getc (infile)) != 'i' ||
457 (c = getc (infile)) != 'l')
458 {
459 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
460 buffer, filename);
461 continue;
462 }
433 } 463 }
434 else 464 else if (c != '(')
435 { 465 {
436 if (c != '(') 466 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
437 continue; 467 buffer, filename);
438 c = getc (infile); 468 continue;
439 if (c != 'q')
440 continue;
441 c = getc (infile);
442 if (c != 'u')
443 continue;
444 c = getc (infile);
445 if (c != 'o')
446 continue;
447 c = getc (infile);
448 if (c != 't')
449 continue;
450 c = getc (infile);
451 if (c != 'e')
452 continue;
453 c = getc (infile);
454 if (c != ' ')
455 continue;
456 while (c == ' ')
457 c = getc (infile);
458 } 469 }
459 470 else
460 p = buf; 471 while (c != ')')
461 while (c != ' ' && c != ')')
462 {
463 if (c == EOF)
464 return 1;
465 if (c == '\\')
466 c = getc (infile);
467 *p++ = c;
468 c = getc (infile); 472 c = getc (infile);
469 } 473 skip_white (infile);
470 *p = 0; 474
471 475 /* If the next three characters aren't `dquote bslash newline'
472 while (c != '"') 476 then we're not reading a docstring.
477 */
478 if ((c = getc (infile)) != '"' ||
479 (c = getc (infile)) != '\\' ||
480 (c = getc (infile)) != '\n')
473 { 481 {
474 if (c == EOF) 482#ifdef DEBUG
475 return 1; 483 fprintf (stderr, "## non-docstring in %s (%s)\n",
476 c = getc (infile); 484 buffer, filename);
485#endif
486 continue;
477 } 487 }
478 c = read_c_string (infile, 0);
479 } 488 }
480 489
481 /* Handle def* clauses. */ 490 else if (! strcmp (buffer, "defvar") ||
482 else if (c == 'd') 491 ! strcmp (buffer, "defconst"))
483 { 492 {
484 c = getc (infile); 493 char c1 = 0, c2 = 0;
485 if (c != 'e') 494 type = 'V';
486 continue; 495 read_lisp_symbol (infile, buffer);
487 c = getc (infile);
488 if (c != 'f')
489 continue;
490 c = getc (infile);
491 496
492 /* Is this a defun? */ 497 /* Skip until the first newline; remember the two previous chars. */
493 if (c == 'u') 498 while (c != '\n' && c >= 0)
494 { 499 {
500 c2 = c1;
501 c1 = c;
495 c = getc (infile); 502 c = getc (infile);
496 if (c != 'n')
497 continue;
498 defvarflag = 0;
499 } 503 }
500 504
501 /* Or a defvar? */ 505 /* If two previous characters were " and \,
502 else if (c == 'v') 506 this is a doc string. Otherwise, there is none. */
507 if (c2 != '"' || c1 != '\\')
503 { 508 {
504 c = getc (infile); 509#ifdef DEBUG
505 if (c != 'a') 510 fprintf (stderr, "## non-docstring in %s (%s)\n",
506 continue; 511 buffer, filename);
507 c = getc (infile); 512#endif
508 if (c != 'r') 513 continue;
509 continue;
510 defvarflag = 1;
511 } 514 }
515 }
516
517 else if (! strcmp (buffer, "fset"))
518 {
519 char c1 = 0, c2 = 0;
520 type = 'F';
512 521
513 /* Or a defconst? */ 522 c = getc (infile);
514 else if (c == 'c') 523 if (c == '\'')
524 read_lisp_symbol (infile, buffer);
525 else
515 { 526 {
527 if (c != '(')
528 {
529 fprintf (stderr, "## unparsable name in fset in %s\n",
530 filename);
531 continue;
532 }
533 read_lisp_symbol (infile, buffer);
534 if (strcmp (buffer, "quote"))
535 {
536 fprintf (stderr, "## unparsable name in fset in %s\n",
537 filename);
538 continue;
539 }
540 read_lisp_symbol (infile, buffer);
516 c = getc (infile); 541 c = getc (infile);
517 if (c != 'o') 542 if (c != ')')
518 continue; 543 {
519 c = getc (infile); 544 fprintf (stderr,
520 if (c != 'n') 545 "## unparsable quoted name in fset in %s\n",
521 continue; 546 filename);
522 c = getc (infile); 547 continue;
523 if (c != 's') 548 }
524 continue;
525 c = getc (infile);
526 if (c != 't')
527 continue;
528 defvarflag = 1;
529 } 549 }
530 else
531 continue;
532
533 /* Now we have seen "defun" or "defvar" or "defconst". */
534 550
535 while (c != ' ' && c != '\n' && c != '\t') 551 /* Skip until the first newline; remember the two previous chars. */
536 c = getc (infile); 552 while (c != '\n' && c >= 0)
537
538 while (c == ' ' || c == '\n' || c == '\t')
539 c = getc (infile);
540
541 /* Read and store name of function or variable being defined
542 Discard backslashes that are for quoting. */
543 p = buf;
544 while (c != ' ' && c != '\n' && c != '\t')
545 { 553 {
546 if (c == '\\') 554 c2 = c1;
547 c = getc (infile); 555 c1 = c;
548 *p++ = c;
549 c = getc (infile); 556 c = getc (infile);
550 } 557 }
551 *p = 0; 558
552 559 /* If two previous characters were " and \,
553 while (c == ' ' || c == '\n' || c == '\t') 560 this is a doc string. Otherwise, there is none. */
554 c = getc (infile); 561 if (c2 != '"' || c1 != '\\')
562 {
563#ifdef DEBUG
564 fprintf (stderr, "## non-docstring in %s (%s)\n",
565 buffer, filename);
566#endif
567 continue;
568 }
569 }
555 570
556 if (! defvarflag) 571 else if (! strcmp (buffer, "autoload"))
572 {
573 type = 'F';
574 c = getc (infile);
575 if (c == '\'')
576 read_lisp_symbol (infile, buffer);
577 else
557 { 578 {
558 /* A function: */ 579 if (c != '(')
559 /* Skip the arguments: either "nil" or a list in parens */
560 if (c == 'n')
561 { 580 {
562 while (c != ' ' && c != '\n' && c != '\t') 581 fprintf (stderr, "## unparsable name in autoload in %s\n",
563 c = getc (infile); 582 filename);
583 continue;
564 } 584 }
565 else 585 read_lisp_symbol (infile, buffer);
586 if (strcmp (buffer, "quote"))
566 { 587 {
567 while (c != '(') 588 fprintf (stderr, "## unparsable name in autoload in %s\n",
568 c = getc (infile); 589 filename);
569 while (c != ')') 590 continue;
570 c = getc (infile);
571 } 591 }
592 read_lisp_symbol (infile, buffer);
572 c = getc (infile); 593 c = getc (infile);
573 } 594 if (c != ')')
574 else
575 {
576 /* A variable: */
577
578 /* Skip until the first newline; remember
579 the two previous characters. */
580 char c1 = 0, c2 = 0;
581
582 while (c != '\n' && c >= 0)
583 { 595 {
584 c2 = c1; 596 fprintf (stderr,
585 c1 = c; 597 "## unparsable quoted name in autoload in %s\n",
586 c = getc (infile); 598 filename);
587 } 599 continue;
588
589 /* If two previous characters were " and \,
590 this is a doc string. Otherwise, there is none. */
591 if (c2 == '"' && c1 == '\\')
592 {
593 putc (037, outfile);
594 putc ('V', outfile);
595 fprintf (outfile, "%s\n", buf);
596 read_c_string (infile, 1);
597 } 600 }
601 }
602 skip_white (infile);
603 if ((c = getc (infile)) != '\"')
604 {
605 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
606 buffer, filename);
598 continue; 607 continue;
599 } 608 }
600 } 609 read_c_string (infile, 0);
601 610 skip_white (infile);
602 /* Handle an fset clause. */ 611
603 else if (c == 'f') 612 /* If the next three characters aren't `dquote bslash newline'
604 { 613 then we're not reading a docstring.
605 c = getc (infile); 614 */
606 if (c != 's') 615 if ((c = getc (infile)) != '"' ||
607 continue; 616 (c = getc (infile)) != '\\' ||
608 c = getc (infile); 617 (c = getc (infile)) != '\n')
609 if (c != 'e')
610 continue;
611 c = getc (infile);
612 if (c != 't')
613 continue;
614
615 /* Skip white space */
616 do
617 c = getc (infile);
618 while (c == ' ' || c == '\n' || c == '\t');
619
620 /* Recognize "(quote". */
621 if (c != '(')
622 continue;
623 c = getc (infile);
624 if (c != 'q')
625 continue;
626 c = getc (infile);
627 if (c != 'u')
628 continue;
629 c = getc (infile);
630 if (c != 'o')
631 continue;
632 c = getc (infile);
633 if (c != 't')
634 continue;
635 c = getc (infile);
636 if (c != 'e')
637 continue;
638
639 /* Skip white space */
640 do
641 c = getc (infile);
642 while (c == ' ' || c == '\n' || c == '\t');
643
644 /* Read and store name of function or variable being defined
645 Discard backslashes that are for quoting. */
646 p = buf;
647 while (c != ')' && c != ' ' && c != '\n' && c != '\t')
648 { 618 {
649 if (c == '\\') 619#ifdef DEBUG
650 c = getc (infile); 620 fprintf (stderr, "## non-docstring in %s (%s)\n",
651 *p++ = c; 621 buffer, filename);
652 c = getc (infile); 622#endif
623 continue;
653 } 624 }
654 *p = '\0';
655
656 /* Skip white space */
657 do
658 c = getc (infile);
659 while (c == ' ' || c == '\n' || c == '\t');
660
661 /* Recognize "(make-byte-code". */
662 if (c != '(')
663 continue;
664 c = getc (infile);
665 if (c != 'm')
666 continue;
667 c = getc (infile);
668 if (c != 'a')
669 continue;
670 c = getc (infile);
671 if (c != 'k')
672 continue;
673 c = getc (infile);
674 if (c != 'e')
675 continue;
676 c = getc (infile);
677 if (c != '-')
678 continue;
679 c = getc (infile);
680 if (c != 'b')
681 continue;
682 c = getc (infile);
683 if (c != 'y')
684 continue;
685 c = getc (infile);
686 if (c != 't')
687 continue;
688 c = getc (infile);
689 if (c != 'e')
690 continue;
691 c = getc (infile);
692 if (c != '-')
693 continue;
694 c = getc (infile);
695 if (c != 'c')
696 continue;
697 c = getc (infile);
698 if (c != 'o')
699 continue;
700 c = getc (infile);
701 if (c != 'd')
702 continue;
703 c = getc (infile);
704 if (c != 'e')
705 continue;
706
707 /* Scan for a \" followed by a newline, or for )) followed by
708 a newline. If we find the latter first, this function has
709 no docstring. */
710 {
711 char c1 = 0, c2 = 0;
712
713 for (;;)
714 {
715
716 /* Find newlines, and remember the two previous characters. */
717 for (;;)
718 {
719 c = getc (infile);
720
721 if (c == '\n' || c < 0)
722 break;
723
724 c2 = c1;
725 c1 = c;
726 }
727
728 /* If we've hit eof, quit. */
729 if (c == EOF)
730 break;
731
732 /* If the last two characters were \", this is a docstring. */
733 else if (c2 == '"' && c1 == '\\')
734 {
735 putc (037, outfile);
736 putc ('F', outfile);
737 fprintf (outfile, "%s\n", buf);
738 read_c_string (infile, 1);
739 break;
740 }
741
742 /* If the last two characters were )), there is no
743 docstring. */
744 else if (c2 == ')' && c1 == ')')
745 break;
746 }
747 continue;
748 }
749 } 625 }
750 else
751 continue;
752
753 /* Here for a function definition.
754 We have skipped the file name or arguments
755 and arrived at where the doc string is,
756 if there is a doc string. */
757
758 /* Skip whitespace */
759 626
760 while (c == ' ' || c == '\n' || c == '\t') 627#ifdef DEBUG
761 c = getc (infile); 628 else if (! strcmp (buffer, "if") ||
629 ! strcmp (buffer, "byte-code"))
630 ;
631#endif
762 632
763 /* " followed by \ and newline means a doc string we should gobble */ 633 else
764 if (c != '"') 634 {
765 continue; 635#ifdef DEBUG
766 c = getc (infile); 636 fprintf (stderr, "## unrecognised top-level form, %s (%s)\n",
767 if (c != '\\') 637 buffer, filename);
768 continue; 638#endif
769 c = getc (infile); 639 continue;
770 if (c != '\n') 640 }
771 continue;
772 641
642 /* At this point, there is a docstring that we should gobble.
643 The opening quote (and leading backslash-newline) have already
644 been read.
645 */
646 putc ('\n', outfile);
773 putc (037, outfile); 647 putc (037, outfile);
774 putc ('F', outfile); 648 putc (type, outfile);
775 fprintf (outfile, "%s\n", buf); 649 fprintf (outfile, "%s\n", buffer);
776 read_c_string (infile, 1); 650 read_c_string (infile, 1);
777 } 651 }
778 fclose (infile); 652 fclose (infile);