Mercurial > emacs
comparison lib-src/make-docfile.c @ 10199:3e2571e22b61
(scan_lisp_file): Handle dynamic doc strings.
(xmalloc, fatal, error): New functions.
(progname): New variable.
(main): Set progname.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Wed, 21 Dec 1994 16:16:45 +0000 |
parents | 20652342eb9a |
children | 9cd115f44483 |
comparison
equal
deleted
inserted
replaced
10198:aa59550d809f | 10199:3e2571e22b61 |
---|---|
51 | 51 |
52 int scan_file (); | 52 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; |
61 char **argv; | 100 char **argv; |
62 { | 101 { |
63 int i; | 102 int i; |
64 int err_count = 0; | 103 int err_count = 0; |
65 int first_infile; | 104 int first_infile; |
105 | |
106 progname = argv[0]; | |
66 | 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; |
70 (stdout)->_flag &= ~_IOTEXT; | 111 (stdout)->_flag &= ~_IOTEXT; |
461 (fset (quote NAME) (make-byte-code ... DOCSTRING ...)) | 502 (fset (quote NAME) (make-byte-code ... DOCSTRING ...)) |
462 (fset (quote NAME) #[... DOCSTRING ...]) | 503 (fset (quote NAME) #[... DOCSTRING ...]) |
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 |
469 initial open-paren (the one in column zero) and must contain a backslash | 515 initial open-paren (the one in column zero) and must contain a backslash |
470 and a double-quote immediately after the initial double-quote. No newlines | 516 and a double-quote immediately after the initial double-quote. No newlines |
521 scan_lisp_file (filename, mode) | 567 scan_lisp_file (filename, mode) |
522 char *filename, *mode; | 568 char *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) |
529 { | 576 { |
530 perror (filename); | 577 perror (filename); |
532 } | 579 } |
533 | 580 |
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') |
541 { | 588 { |
542 c = getc (infile); | 589 c = getc (infile); |
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 |
549 read_lisp_symbol (infile, buffer); | 636 read_lisp_symbol (infile, buffer); |
550 | 637 |
598 { | 685 { |
599 char c1 = 0, c2 = 0; | 686 char c1 = 0, c2 = 0; |
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) | 691 { |
605 { | 692 |
606 c2 = c1; | 693 /* Skip until the first newline; remember the two previous chars. */ |
607 c1 = c; | 694 while (c != '\n' && c >= 0) |
608 c = getc (infile); | 695 { |
609 } | 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 |
623 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) | 714 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) |
624 { | 715 { |
652 filename); | 743 filename); |
653 continue; | 744 continue; |
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) | 749 { |
659 { | 750 /* Skip until the first newline; remember the two previous chars. */ |
660 c2 = c1; | 751 while (c != '\n' && c >= 0) |
661 c1 = c; | 752 { |
662 c = getc (infile); | 753 c2 = c1; |
663 } | 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 |
677 else if (! strcmp (buffer, "autoload")) | 771 else if (! strcmp (buffer, "autoload")) |
678 { | 772 { |
713 continue; | 807 continue; |
714 } | 808 } |
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. | 813 { |
720 */ | 814 /* If the next three characters aren't `dquote bslash newline' |
721 if ((c = getc (infile)) != '"' || | 815 then we're not reading a docstring. */ |
722 (c = getc (infile)) != '\\' || | 816 if ((c = getc (infile)) != '"' || |
723 (c = getc (infile)) != '\n') | 817 (c = getc (infile)) != '\\' || |
724 { | 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 |
733 #ifdef DEBUG | 829 #ifdef DEBUG |
734 else if (! strcmp (buffer, "if") || | 830 else if (! strcmp (buffer, "if") || |
743 buffer, filename); | 839 buffer, filename); |
744 #endif | 840 #endif |
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; |
759 } | 866 } |