diff options
| author | Richard M. Stallman | 1994-12-21 16:16:45 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-12-21 16:16:45 +0000 |
| commit | b5ff43cc2ee7a8c582aedf45f164adb5b784f0ac (patch) | |
| tree | 13259ef8198f6b20451d819724aa9f66eddf27b7 /lib-src/make-docfile.c | |
| parent | b3dcbddbfc673d8b2361ffc7af09e22875e1e0a4 (diff) | |
| download | emacs-b5ff43cc2ee7a8c582aedf45f164adb5b784f0ac.tar.gz emacs-b5ff43cc2ee7a8c582aedf45f164adb5b784f0ac.zip | |
(scan_lisp_file): Handle dynamic doc strings.
(xmalloc, fatal, error): New functions.
(progname): New variable.
(main): Set progname.
Diffstat (limited to 'lib-src/make-docfile.c')
| -rw-r--r-- | lib-src/make-docfile.c | 189 |
1 files changed, 148 insertions, 41 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index fbcebde1440..df9c6e069f5 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -53,8 +53,47 @@ int scan_file (); | |||
| 53 | int scan_lisp_file (); | 53 | int scan_lisp_file (); |
| 54 | int scan_c_file (); | 54 | int scan_c_file (); |
| 55 | 55 | ||
| 56 | /* Stdio stream for output to the DOC file. */ | ||
| 56 | FILE *outfile; | 57 | FILE *outfile; |
| 57 | 58 | ||
| 59 | /* Name this program was invoked with. */ | ||
| 60 | char *progname; | ||
| 61 | |||
| 62 | /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | ||
| 63 | |||
| 64 | /* VARARGS1 */ | ||
| 65 | void | ||
| 66 | error (s1, s2) | ||
| 67 | char *s1, *s2; | ||
| 68 | { | ||
| 69 | fprintf (stderr, "%s: ", progname); | ||
| 70 | fprintf (stderr, s1, s2); | ||
| 71 | fprintf (stderr, "\n"); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Print error message and exit. */ | ||
| 75 | |||
| 76 | /* VARARGS1 */ | ||
| 77 | void | ||
| 78 | fatal (s1, s2) | ||
| 79 | char *s1, *s2; | ||
| 80 | { | ||
| 81 | error (s1, s2); | ||
| 82 | exit (1); | ||
| 83 | } | ||
| 84 | |||
| 85 | /* Like malloc but get fatal error if memory is exhausted. */ | ||
| 86 | |||
| 87 | char * | ||
| 88 | xmalloc (size) | ||
| 89 | unsigned int size; | ||
| 90 | { | ||
| 91 | char *result = (char *) malloc (size); | ||
| 92 | if (result == NULL) | ||
| 93 | fatal ("virtual memory exhausted", 0); | ||
| 94 | return result; | ||
| 95 | } | ||
| 96 | |||
| 58 | int | 97 | int |
| 59 | main (argc, argv) | 98 | main (argc, argv) |
| 60 | int argc; | 99 | int argc; |
| @@ -64,6 +103,8 @@ main (argc, argv) | |||
| 64 | int err_count = 0; | 103 | int err_count = 0; |
| 65 | int first_infile; | 104 | int first_infile; |
| 66 | 105 | ||
| 106 | progname = argv[0]; | ||
| 107 | |||
| 67 | /* Don't put CRs in the DOC file. */ | 108 | /* Don't put CRs in the DOC file. */ |
| 68 | #ifdef MSDOS | 109 | #ifdef MSDOS |
| 69 | _fmode = O_BINARY; | 110 | _fmode = O_BINARY; |
| @@ -463,6 +504,11 @@ scan_c_file (filename, mode) | |||
| 463 | (defalias (quote NAME) #[... DOCSTRING ...]) | 504 | (defalias (quote NAME) #[... DOCSTRING ...]) |
| 464 | starting in column zero. | 505 | starting in column zero. |
| 465 | (quote NAME) may appear as 'NAME as well. | 506 | (quote NAME) may appear as 'NAME as well. |
| 507 | |||
| 508 | We also look for #@LENGTH CONTENTS^_ at the beginning of the line. | ||
| 509 | When we find that, we save it for the following defining-form, | ||
| 510 | and we use that instead of reading a doc string within that defining-form. | ||
| 511 | |||
| 466 | For defun, defmacro, and autoload, we know how to skip over the arglist. | 512 | For defun, defmacro, and autoload, we know how to skip over the arglist. |
| 467 | For defvar, defconst, and fset we skip to the docstring with a kludgy | 513 | For defvar, defconst, and fset we skip to the docstring with a kludgy |
| 468 | formatting convention: all docstrings must appear on the same line as the | 514 | formatting convention: all docstrings must appear on the same line as the |
| @@ -523,6 +569,7 @@ scan_lisp_file (filename, mode) | |||
| 523 | { | 569 | { |
| 524 | FILE *infile; | 570 | FILE *infile; |
| 525 | register int c; | 571 | register int c; |
| 572 | char *saved_string = 0; | ||
| 526 | 573 | ||
| 527 | infile = fopen (filename, mode); | 574 | infile = fopen (filename, mode); |
| 528 | if (infile == NULL) | 575 | if (infile == NULL) |
| @@ -534,7 +581,7 @@ scan_lisp_file (filename, mode) | |||
| 534 | c = '\n'; | 581 | c = '\n'; |
| 535 | while (!feof (infile)) | 582 | while (!feof (infile)) |
| 536 | { | 583 | { |
| 537 | char buffer [BUFSIZ]; | 584 | char buffer[BUFSIZ]; |
| 538 | char type; | 585 | char type; |
| 539 | 586 | ||
| 540 | if (c != '\n') | 587 | if (c != '\n') |
| @@ -543,6 +590,46 @@ scan_lisp_file (filename, mode) | |||
| 543 | continue; | 590 | continue; |
| 544 | } | 591 | } |
| 545 | c = getc (infile); | 592 | c = getc (infile); |
| 593 | /* Detect a dynamic doc string and save it for the next expression. */ | ||
| 594 | if (c == '#') | ||
| 595 | { | ||
| 596 | c = getc (infile); | ||
| 597 | if (c == '@') | ||
| 598 | { | ||
| 599 | int length = 0; | ||
| 600 | int i; | ||
| 601 | |||
| 602 | /* Read the length. */ | ||
| 603 | while ((c = getc (infile), | ||
| 604 | c >= '0' && c <= '9')) | ||
| 605 | { | ||
| 606 | length *= 10; | ||
| 607 | length += c - '0'; | ||
| 608 | } | ||
| 609 | |||
| 610 | /* The next character is a space that is counted in the length | ||
| 611 | but not part of the doc string. | ||
| 612 | We already read it, so just ignore it. */ | ||
| 613 | length--; | ||
| 614 | |||
| 615 | /* Read in the contents. */ | ||
| 616 | if (saved_string != 0) | ||
| 617 | free (saved_string); | ||
| 618 | saved_string = (char *) malloc (length); | ||
| 619 | for (i = 0; i < length; i++) | ||
| 620 | saved_string[i] = getc (infile); | ||
| 621 | /* The last character is a ^_. | ||
| 622 | That is needed in the .elc file | ||
| 623 | but it is redundant in DOC. So get rid of it here. */ | ||
| 624 | saved_string[length - 1] = 0; | ||
| 625 | /* Skip the newline. */ | ||
| 626 | c = getc (infile); | ||
| 627 | while (c != '\n') | ||
| 628 | c = getc (infile); | ||
| 629 | } | ||
| 630 | continue; | ||
| 631 | } | ||
| 632 | |||
| 546 | if (c != '(') | 633 | if (c != '(') |
| 547 | continue; | 634 | continue; |
| 548 | 635 | ||
| @@ -600,23 +687,27 @@ scan_lisp_file (filename, mode) | |||
| 600 | type = 'V'; | 687 | type = 'V'; |
| 601 | read_lisp_symbol (infile, buffer); | 688 | read_lisp_symbol (infile, buffer); |
| 602 | 689 | ||
| 603 | /* Skip until the first newline; remember the two previous chars. */ | 690 | if (saved_string == 0) |
| 604 | while (c != '\n' && c >= 0) | ||
| 605 | { | 691 | { |
| 606 | c2 = c1; | 692 | |
| 607 | c1 = c; | 693 | /* Skip until the first newline; remember the two previous chars. */ |
| 608 | c = getc (infile); | 694 | while (c != '\n' && c >= 0) |
| 609 | } | 695 | { |
| 696 | c2 = c1; | ||
| 697 | c1 = c; | ||
| 698 | c = getc (infile); | ||
| 699 | } | ||
| 610 | 700 | ||
| 611 | /* If two previous characters were " and \, | 701 | /* If two previous characters were " and \, |
| 612 | this is a doc string. Otherwise, there is none. */ | 702 | this is a doc string. Otherwise, there is none. */ |
| 613 | if (c2 != '"' || c1 != '\\') | 703 | if (c2 != '"' || c1 != '\\') |
| 614 | { | 704 | { |
| 615 | #ifdef DEBUG | 705 | #ifdef DEBUG |
| 616 | fprintf (stderr, "## non-docstring in %s (%s)\n", | 706 | fprintf (stderr, "## non-docstring in %s (%s)\n", |
| 617 | buffer, filename); | 707 | buffer, filename); |
| 618 | #endif | 708 | #endif |
| 619 | continue; | 709 | continue; |
| 710 | } | ||
| 620 | } | 711 | } |
| 621 | } | 712 | } |
| 622 | 713 | ||
| @@ -654,23 +745,26 @@ scan_lisp_file (filename, mode) | |||
| 654 | } | 745 | } |
| 655 | } | 746 | } |
| 656 | 747 | ||
| 657 | /* Skip until the first newline; remember the two previous chars. */ | 748 | if (saved_string == 0) |
| 658 | while (c != '\n' && c >= 0) | ||
| 659 | { | 749 | { |
| 660 | c2 = c1; | 750 | /* Skip until the first newline; remember the two previous chars. */ |
| 661 | c1 = c; | 751 | while (c != '\n' && c >= 0) |
| 662 | c = getc (infile); | 752 | { |
| 663 | } | 753 | c2 = c1; |
| 754 | c1 = c; | ||
| 755 | c = getc (infile); | ||
| 756 | } | ||
| 664 | 757 | ||
| 665 | /* If two previous characters were " and \, | 758 | /* If two previous characters were " and \, |
| 666 | this is a doc string. Otherwise, there is none. */ | 759 | this is a doc string. Otherwise, there is none. */ |
| 667 | if (c2 != '"' || c1 != '\\') | 760 | if (c2 != '"' || c1 != '\\') |
| 668 | { | 761 | { |
| 669 | #ifdef DEBUG | 762 | #ifdef DEBUG |
| 670 | fprintf (stderr, "## non-docstring in %s (%s)\n", | 763 | fprintf (stderr, "## non-docstring in %s (%s)\n", |
| 671 | buffer, filename); | 764 | buffer, filename); |
| 672 | #endif | 765 | #endif |
| 673 | continue; | 766 | continue; |
| 767 | } | ||
| 674 | } | 768 | } |
| 675 | } | 769 | } |
| 676 | 770 | ||
| @@ -715,18 +809,20 @@ scan_lisp_file (filename, mode) | |||
| 715 | read_c_string (infile, 0); | 809 | read_c_string (infile, 0); |
| 716 | skip_white (infile); | 810 | skip_white (infile); |
| 717 | 811 | ||
| 718 | /* If the next three characters aren't `dquote bslash newline' | 812 | if (saved_string == 0) |
| 719 | then we're not reading a docstring. | ||
| 720 | */ | ||
| 721 | if ((c = getc (infile)) != '"' || | ||
| 722 | (c = getc (infile)) != '\\' || | ||
| 723 | (c = getc (infile)) != '\n') | ||
| 724 | { | 813 | { |
| 814 | /* If the next three characters aren't `dquote bslash newline' | ||
| 815 | then we're not reading a docstring. */ | ||
| 816 | if ((c = getc (infile)) != '"' || | ||
| 817 | (c = getc (infile)) != '\\' || | ||
| 818 | (c = getc (infile)) != '\n') | ||
| 819 | { | ||
| 725 | #ifdef DEBUG | 820 | #ifdef DEBUG |
| 726 | fprintf (stderr, "## non-docstring in %s (%s)\n", | 821 | fprintf (stderr, "## non-docstring in %s (%s)\n", |
| 727 | buffer, filename); | 822 | buffer, filename); |
| 728 | #endif | 823 | #endif |
| 729 | continue; | 824 | continue; |
| 825 | } | ||
| 730 | } | 826 | } |
| 731 | } | 827 | } |
| 732 | 828 | ||
| @@ -745,14 +841,25 @@ scan_lisp_file (filename, mode) | |||
| 745 | continue; | 841 | continue; |
| 746 | } | 842 | } |
| 747 | 843 | ||
| 748 | /* At this point, there is a docstring that we should gobble. | 844 | /* At this point, we should either use the previous |
| 749 | The opening quote (and leading backslash-newline) have already | 845 | dynamic doc string in saved_string |
| 750 | been read. | 846 | or gobble a doc string from the input file. |
| 751 | */ | 847 | |
| 848 | In the latter case, the opening quote (and leading | ||
| 849 | backslash-newline) have already been read. */ | ||
| 850 | |||
| 752 | putc (037, outfile); | 851 | putc (037, outfile); |
| 753 | putc (type, outfile); | 852 | putc (type, outfile); |
| 754 | fprintf (outfile, "%s\n", buffer); | 853 | fprintf (outfile, "%s\n", buffer); |
| 755 | read_c_string (infile, 1); | 854 | if (saved_string) |
| 855 | { | ||
| 856 | fputs (saved_string, outfile); | ||
| 857 | /* Don't use one dynamic doc string twice. */ | ||
| 858 | free (saved_string); | ||
| 859 | saved_string = 0; | ||
| 860 | } | ||
| 861 | else | ||
| 862 | read_c_string (infile, 1); | ||
| 756 | } | 863 | } |
| 757 | fclose (infile); | 864 | fclose (infile); |
| 758 | return 0; | 865 | return 0; |