aboutsummaryrefslogtreecommitdiffstats
path: root/src/syntax.c
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-02 17:21:05 +0000
committerRichard M. Stallman1993-03-02 17:21:05 +0000
commitb3cfe0c85ac9df9f45d5ba1622774b5725bbd333 (patch)
treea581eca4eee1e8d0b91d1d058490d4e7b46a31fd /src/syntax.c
parent5b2468369d5c4ac2a8fade3cac74c06115c86131 (diff)
downloademacs-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.c262
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
566DEFUN ("forward-comment", Fforward_comment, Sforward_comment, 1, 1, 0,
567 "Move forward across up to N comments. If N is negative, move backward.\n\
568Set point to the far end of the last comment found.\n\
569Stop scanning if we find something other than a comment or whitespace.\n\
570If N comments are found as expected, with nothing except whitespace\n\
571between 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
566int parse_sexp_ignore_comments; 823int parse_sexp_ignore_comments;
567 824
568Lisp_Object 825Lisp_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);