diff options
| author | Richard M. Stallman | 1993-03-02 17:21:05 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-03-02 17:21:05 +0000 |
| commit | b3cfe0c85ac9df9f45d5ba1622774b5725bbd333 (patch) | |
| tree | a581eca4eee1e8d0b91d1d058490d4e7b46a31fd /src/syntax.c | |
| parent | 5b2468369d5c4ac2a8fade3cac74c06115c86131 (diff) | |
| download | emacs-b3cfe0c85ac9df9f45d5ba1622774b5725bbd333.tar.gz emacs-b3cfe0c85ac9df9f45d5ba1622774b5725bbd333.zip | |
(describe_syntax_1): Delete excess arg to describe_vector.
(check_syntax_table): Delete excess arg to wrong_type_argument.
(Fforward_comment): New function.
Diffstat (limited to 'src/syntax.c')
| -rw-r--r-- | src/syntax.c | 262 |
1 files changed, 260 insertions, 2 deletions
diff --git a/src/syntax.c b/src/syntax.c index 3bb9e2956cc..2af69a3d52b 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -120,7 +120,7 @@ check_syntax_table (obj) | |||
| 120 | register Lisp_Object tem; | 120 | register Lisp_Object tem; |
| 121 | while (tem = Fsyntax_table_p (obj), | 121 | while (tem = Fsyntax_table_p (obj), |
| 122 | NILP (tem)) | 122 | NILP (tem)) |
| 123 | obj = wrong_type_argument (Qsyntax_table_p, obj, 0); | 123 | obj = wrong_type_argument (Qsyntax_table_p, obj); |
| 124 | return obj; | 124 | return obj; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| @@ -449,7 +449,7 @@ describe_syntax_1 (vector) | |||
| 449 | { | 449 | { |
| 450 | struct buffer *old = current_buffer; | 450 | struct buffer *old = current_buffer; |
| 451 | set_buffer_internal (XBUFFER (Vstandard_output)); | 451 | set_buffer_internal (XBUFFER (Vstandard_output)); |
| 452 | describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil); | 452 | describe_vector (vector, Qnil, describe_syntax, 0, Qnil); |
| 453 | set_buffer_internal (old); | 453 | set_buffer_internal (old); |
| 454 | return Qnil; | 454 | return Qnil; |
| 455 | } | 455 | } |
| @@ -563,6 +563,263 @@ and nil is returned.") | |||
| 563 | return Qt; | 563 | return Qt; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | DEFUN ("forward-comment", Fforward_comment, Sforward_comment, 1, 1, 0, | ||
| 567 | "Move forward across up to N comments. If N is negative, move backward.\n\ | ||
| 568 | Set point to the far end of the last comment found.\n\ | ||
| 569 | Stop scanning if we find something other than a comment or whitespace.\n\ | ||
| 570 | If N comments are found as expected, with nothing except whitespace\n\ | ||
| 571 | between them, return t; otherwise return nil.") | ||
| 572 | (count) | ||
| 573 | int count; | ||
| 574 | { | ||
| 575 | register int from; | ||
| 576 | register int stop; | ||
| 577 | register int c; | ||
| 578 | register enum syntaxcode code; | ||
| 579 | int comstyle = 0; /* style of comment encountered */ | ||
| 580 | |||
| 581 | immediate_quit = 1; | ||
| 582 | QUIT; | ||
| 583 | |||
| 584 | from = PT; | ||
| 585 | |||
| 586 | while (count > 0) | ||
| 587 | { | ||
| 588 | stop = ZV; | ||
| 589 | while (from < stop) | ||
| 590 | { | ||
| 591 | c = FETCH_CHAR (from); | ||
| 592 | code = SYNTAX (c); | ||
| 593 | from++; | ||
| 594 | comstyle = 0; | ||
| 595 | if (from < stop && SYNTAX_COMSTART_FIRST (c) | ||
| 596 | && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))) | ||
| 597 | { | ||
| 598 | /* we have encountered a comment start sequence and we | ||
| 599 | are ignoring all text inside comments. we must record | ||
| 600 | the comment style this sequence begins so that later, | ||
| 601 | only a comment end of the same style actually ends | ||
| 602 | the comment section */ | ||
| 603 | code = Scomment; | ||
| 604 | comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)); | ||
| 605 | from++; | ||
| 606 | } | ||
| 607 | |||
| 608 | if (code == Scomment) | ||
| 609 | { | ||
| 610 | while (1) | ||
| 611 | { | ||
| 612 | if (from == stop) | ||
| 613 | { | ||
| 614 | immediate_quit = 0; | ||
| 615 | return Qnil; | ||
| 616 | } | ||
| 617 | c = FETCH_CHAR (from); | ||
| 618 | if (SYNTAX (c) == Sendcomment | ||
| 619 | && SYNTAX_COMMENT_STYLE (c) == comstyle) | ||
| 620 | /* we have encountered a comment end of the same style | ||
| 621 | as the comment sequence which began this comment | ||
| 622 | section */ | ||
| 623 | break; | ||
| 624 | from++; | ||
| 625 | if (from < stop && SYNTAX_COMEND_FIRST (c) | ||
| 626 | && SYNTAX_COMEND_SECOND (FETCH_CHAR (from)) | ||
| 627 | && SYNTAX_COMMENT_STYLE (c) == comstyle) | ||
| 628 | /* we have encountered a comment end of the same style | ||
| 629 | as the comment sequence which began this comment | ||
| 630 | section */ | ||
| 631 | { from++; break; } | ||
| 632 | } | ||
| 633 | /* We have skipped one comment. */ | ||
| 634 | break; | ||
| 635 | } | ||
| 636 | else if (code != Swhitespace) | ||
| 637 | { | ||
| 638 | immediate_quit = 0; | ||
| 639 | return Qnil; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | /* End of comment reached */ | ||
| 644 | count--; | ||
| 645 | } | ||
| 646 | |||
| 647 | while (count < 0) | ||
| 648 | { | ||
| 649 | stop = BEGV; | ||
| 650 | while (from > stop) | ||
| 651 | { | ||
| 652 | int quoted; | ||
| 653 | |||
| 654 | from--; | ||
| 655 | quoted = char_quoted (from); | ||
| 656 | if (quoted) | ||
| 657 | from--; | ||
| 658 | c = FETCH_CHAR (from); | ||
| 659 | code = SYNTAX (c); | ||
| 660 | comstyle = 0; | ||
| 661 | if (from > stop && SYNTAX_COMEND_SECOND (c) | ||
| 662 | && SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1)) | ||
| 663 | && !char_quoted (from - 1)) | ||
| 664 | { | ||
| 665 | /* we must record the comment style encountered so that | ||
| 666 | later, we can match only the proper comment begin | ||
| 667 | sequence of the same style */ | ||
| 668 | code = Sendcomment; | ||
| 669 | comstyle = SYNTAX_COMMENT_STYLE (FETCH_CHAR (from - 1)); | ||
| 670 | from--; | ||
| 671 | } | ||
| 672 | |||
| 673 | if (code == Sendcomment && !quoted) | ||
| 674 | { | ||
| 675 | if (code != SYNTAX (c)) | ||
| 676 | /* For a two-char comment ender, we can assume | ||
| 677 | it does end a comment. So scan back in a simple way. */ | ||
| 678 | { | ||
| 679 | if (from != stop) from--; | ||
| 680 | while (1) | ||
| 681 | { | ||
| 682 | if (SYNTAX (c = FETCH_CHAR (from)) == Scomment | ||
| 683 | && SYNTAX_COMMENT_STYLE (c) == comstyle) | ||
| 684 | break; | ||
| 685 | if (from == stop) | ||
| 686 | { | ||
| 687 | immediate_quit = 0; | ||
| 688 | return Qnil; | ||
| 689 | } | ||
| 690 | from--; | ||
| 691 | if (SYNTAX_COMSTART_SECOND (c) | ||
| 692 | && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from)) | ||
| 693 | && SYNTAX_COMMENT_STYLE (c) == comstyle | ||
| 694 | && !char_quoted (from)) | ||
| 695 | break; | ||
| 696 | } | ||
| 697 | break; | ||
| 698 | } | ||
| 699 | |||
| 700 | /* Look back, counting the parity of string-quotes, | ||
| 701 | and recording the comment-starters seen. | ||
| 702 | When we reach a safe place, assume that's not in a string; | ||
| 703 | then step the main scan to the earliest comment-starter seen | ||
| 704 | an even number of string quotes away from the safe place. | ||
| 705 | |||
| 706 | OFROM[I] is position of the earliest comment-starter seen | ||
| 707 | which is I+2X quotes from the comment-end. | ||
| 708 | PARITY is current parity of quotes from the comment end. */ | ||
| 709 | { | ||
| 710 | int parity = 0; | ||
| 711 | char my_stringend = 0; | ||
| 712 | int string_lossage = 0; | ||
| 713 | int comment_end = from; | ||
| 714 | int comstart_pos = 0; | ||
| 715 | int comstart_parity = 0; | ||
| 716 | |||
| 717 | /* At beginning of range to scan, we're outside of strings; | ||
| 718 | that determines quote parity to the comment-end. */ | ||
| 719 | while (from != stop) | ||
| 720 | { | ||
| 721 | /* Move back and examine a character. */ | ||
| 722 | from--; | ||
| 723 | |||
| 724 | c = FETCH_CHAR (from); | ||
| 725 | code = SYNTAX (c); | ||
| 726 | |||
| 727 | /* If this char is the second of a 2-char comment sequence, | ||
| 728 | back up and give the pair the appropriate syntax. */ | ||
| 729 | if (from > stop && SYNTAX_COMEND_SECOND (c) | ||
| 730 | && SYNTAX_COMEND_FIRST (FETCH_CHAR (from - 1))) | ||
| 731 | { | ||
| 732 | code = Sendcomment; | ||
| 733 | from--; | ||
| 734 | } | ||
| 735 | |||
| 736 | else if (from > stop && SYNTAX_COMSTART_SECOND (c) | ||
| 737 | && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1)) | ||
| 738 | && comstyle == SYNTAX_COMMENT_STYLE (c)) | ||
| 739 | { | ||
| 740 | code = Scomment; | ||
| 741 | from--; | ||
| 742 | } | ||
| 743 | |||
| 744 | /* Ignore escaped characters. */ | ||
| 745 | if (char_quoted (from)) | ||
| 746 | continue; | ||
| 747 | |||
| 748 | /* Track parity of quotes. */ | ||
| 749 | if (code == Sstring) | ||
| 750 | { | ||
| 751 | parity ^= 1; | ||
| 752 | if (my_stringend == 0) | ||
| 753 | my_stringend = c; | ||
| 754 | /* If we have two kinds of string delimiters. | ||
| 755 | There's no way to grok this scanning backwards. */ | ||
| 756 | else if (my_stringend != c) | ||
| 757 | string_lossage = 1; | ||
| 758 | } | ||
| 759 | |||
| 760 | /* Record comment-starters according to that | ||
| 761 | quote-parity to the comment-end. */ | ||
| 762 | if (code == Scomment) | ||
| 763 | { | ||
| 764 | comstart_parity = parity; | ||
| 765 | comstart_pos = from; | ||
| 766 | } | ||
| 767 | |||
| 768 | /* If we find another earlier comment-ender, | ||
| 769 | any comment-starts earier than that don't count | ||
| 770 | (because they go with the earlier comment-ender). */ | ||
| 771 | if (code == Sendcomment | ||
| 772 | && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle) | ||
| 773 | break; | ||
| 774 | |||
| 775 | /* Assume a defun-start point is outside of strings. */ | ||
| 776 | if (code == Sopen | ||
| 777 | && (from == stop || FETCH_CHAR (from - 1) == '\n')) | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | |||
| 781 | if (comstart_pos == 0) | ||
| 782 | from = comment_end; | ||
| 783 | /* If the earliest comment starter | ||
| 784 | is followed by uniform paired string quotes or none, | ||
| 785 | we know it can't be inside a string | ||
| 786 | since if it were then the comment ender would be inside one. | ||
| 787 | So it does start a comment. Skip back to it. */ | ||
| 788 | else if (comstart_parity == 0 && !string_lossage) | ||
| 789 | from = comstart_pos; | ||
| 790 | else | ||
| 791 | { | ||
| 792 | /* We had two kinds of string delimiters mixed up | ||
| 793 | together. Decode this going forwards. | ||
| 794 | Scan fwd from the previous comment ender | ||
| 795 | to the one in question; this records where we | ||
| 796 | last passed a comment starter. */ | ||
| 797 | struct lisp_parse_state state; | ||
| 798 | scan_sexps_forward (&state, find_defun_start (comment_end), | ||
| 799 | comment_end - 1, -10000, 0, Qnil); | ||
| 800 | if (state.incomment) | ||
| 801 | from = state.comstart; | ||
| 802 | else | ||
| 803 | /* We can't grok this as a comment; scan it normally. */ | ||
| 804 | from = comment_end; | ||
| 805 | } | ||
| 806 | } | ||
| 807 | } | ||
| 808 | else if (code != Swhitespace || quoted) | ||
| 809 | { | ||
| 810 | immediate_quit = 0; | ||
| 811 | return Qnil; | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | count++; | ||
| 816 | } | ||
| 817 | |||
| 818 | SET_PT (from); | ||
| 819 | immediate_quit = 0; | ||
| 820 | return Qt; | ||
| 821 | } | ||
| 822 | |||
| 566 | int parse_sexp_ignore_comments; | 823 | int parse_sexp_ignore_comments; |
| 567 | 824 | ||
| 568 | Lisp_Object | 825 | Lisp_Object |
| @@ -1418,6 +1675,7 @@ syms_of_syntax () | |||
| 1418 | 1675 | ||
| 1419 | defsubr (&Sforward_word); | 1676 | defsubr (&Sforward_word); |
| 1420 | 1677 | ||
| 1678 | defsubr (&Sforward_comment); | ||
| 1421 | defsubr (&Sscan_lists); | 1679 | defsubr (&Sscan_lists); |
| 1422 | defsubr (&Sscan_sexps); | 1680 | defsubr (&Sscan_sexps); |
| 1423 | defsubr (&Sbackward_prefix_chars); | 1681 | defsubr (&Sbackward_prefix_chars); |