Mercurial > emacs
comparison src/syntax.c @ 1167:a9aeeaa9da8f
(scan_lists): When searching back for comment:
if comment-end is 2 chars, assume it does end a comment.
Otherwise, scan back to previous comment-end to see if there's
a comment starter between. Also record whether the string quotes
between the start and the end are paired and uniform.
If so, skip to comment starter. If not, scan from start of
defun to find comment starter if any.
(find_defun_start): New function.
| author | Richard M. Stallman <rms@gnu.org> |
|---|---|
| date | Sat, 19 Sep 1992 17:52:07 +0000 |
| parents | 91a456e52db1 |
| children | d9a103f4843e |
comparison
equal
deleted
inserted
replaced
| 1166:45fbb83b8160 | 1167:a9aeeaa9da8f |
|---|---|
| 42 int prevlevelstart; /* Char number of start of containing expression */ | 42 int prevlevelstart; /* Char number of start of containing expression */ |
| 43 int location; /* Char number at which parsing stopped. */ | 43 int location; /* Char number at which parsing stopped. */ |
| 44 int mindepth; /* Minimum depth seen while scanning. */ | 44 int mindepth; /* Minimum depth seen while scanning. */ |
| 45 int comstart; /* Position just after last comment starter. */ | 45 int comstart; /* Position just after last comment starter. */ |
| 46 }; | 46 }; |
| 47 | |
| 48 /* These variables are a cache for finding the start of a defun. | |
| 49 find_start_pos is the place for which the defun start was found. | |
| 50 find_start_value is the defun start position found for it. | |
| 51 find_start_buffer is the buffer it was found in. | |
| 52 find_start_begv is the BEGV value when it was found. | |
| 53 find_start_modiff is the value of MODIFF when it was found. */ | |
| 54 | |
| 55 static int find_start_pos; | |
| 56 static int find_start_value; | |
| 57 static struct buffer *find_start_buffer; | |
| 58 static int find_start_begv; | |
| 59 static int find_start_modiff; | |
| 60 | |
| 61 /* Find a defun-start that is the last one before POS (or nearly the last). | |
| 62 We record what we find, so that another call in the same area | |
| 63 can return the same value right away. */ | |
| 64 | |
| 65 static int | |
| 66 find_defun_start (pos) | |
| 67 int pos; | |
| 68 { | |
| 69 int tem; | |
| 70 int shortage; | |
| 71 | |
| 72 /* Use previous finding, if it's valid and applies to this inquiry. */ | |
| 73 if (current_buffer == find_start_buffer | |
| 74 /* Reuse the defun-start even if POS is a little farther on. | |
| 75 POS might be in the next defun, but that's ok. | |
| 76 Our value may not be the best possible, but will still be usable. */ | |
| 77 && pos <= find_start_pos + 1000 | |
| 78 && pos >= find_start_value | |
| 79 && BEGV == find_start_begv | |
| 80 && MODIFF == find_start_modiff) | |
| 81 return find_start_value; | |
| 82 | |
| 83 /* Back up to start of line. */ | |
| 84 tem = scan_buffer ('\n', pos, -1, &shortage); | |
| 85 /* If we found a newline, we moved back over it, so advance fwd past it. */ | |
| 86 if (shortage == 0) | |
| 87 tem++; | |
| 88 | |
| 89 while (tem > BEGV) | |
| 90 { | |
| 91 /* Open-paren at start of line means we found our defun-start. */ | |
| 92 if (SYNTAX (FETCH_CHAR (tem)) == Sopen) | |
| 93 break; | |
| 94 /* Move to beg of previous line. */ | |
| 95 tem = scan_buffer ('\n', tem, -2, &shortage); | |
| 96 if (shortage == 0) | |
| 97 tem++; | |
| 98 } | |
| 99 | |
| 100 /* Record what we found, for the next try. */ | |
| 101 find_start_value = tem; | |
| 102 find_start_buffer = current_buffer; | |
| 103 find_start_modiff = MODIFF; | |
| 104 find_start_begv = BEGV; | |
| 105 find_start_pos = pos; | |
| 106 | |
| 107 return find_start_value; | |
| 108 } | |
| 47 | 109 |
| 48 DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0, | 110 DEFUN ("syntax-table-p", Fsyntax_table_p, Ssyntax_table_p, 1, 1, 0, |
| 49 "Return t if ARG is a syntax table.\n\ | 111 "Return t if ARG is a syntax table.\n\ |
| 50 Any vector of 256 elements will do.") | 112 Any vector of 256 elements will do.") |
| 51 (obj) | 113 (obj) |
| 748 break; | 810 break; |
| 749 | 811 |
| 750 case Sendcomment: | 812 case Sendcomment: |
| 751 if (!parse_sexp_ignore_comments) | 813 if (!parse_sexp_ignore_comments) |
| 752 break; | 814 break; |
| 815 if (code != SYNTAX (c)) | |
| 816 /* For a two-char comment ender, we can assume | |
| 817 it does end a comment. So scan back in a simple way. */ | |
| 818 { | |
| 819 if (from != stop) from--; | |
| 820 while (1) | |
| 821 { | |
| 822 if (SYNTAX (c = FETCH_CHAR (from)) == Scomment | |
| 823 && SYNTAX_COMMENT_STYLE (c) == comstyle) | |
| 824 break; | |
| 825 if (from == stop) goto done; | |
| 826 from--; | |
| 827 if (SYNTAX_COMSTART_SECOND (c) | |
| 828 && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from)) | |
| 829 && SYNTAX_COMMENT_STYLE (c) == comstyle | |
| 830 && !char_quoted (from)) | |
| 831 break; | |
| 832 } | |
| 833 break; | |
| 834 } | |
| 835 | |
| 753 /* Look back, counting the parity of string-quotes, | 836 /* Look back, counting the parity of string-quotes, |
| 754 and recording the comment-starters seen. | 837 and recording the comment-starters seen. |
| 755 When we reach a safe place, assume that's not in a string; | 838 When we reach a safe place, assume that's not in a string; |
| 756 then step the main scan to the earliest comment-starter seen | 839 then step the main scan to the earliest comment-starter seen |
| 757 an even number of string quotes away from the safe place. | 840 an even number of string quotes away from the safe place. |
| 758 | 841 |
| 759 OFROM[I] is position of the earliest comment-starter seen | 842 OFROM[I] is position of the earliest comment-starter seen |
| 760 which is I+2X quotes from the comment-end. | 843 which is I+2X quotes from the comment-end. |
| 761 PARITY is current parity of quotes from the comment end. */ | 844 PARITY is current parity of quotes from the comment end. */ |
| 762 { | 845 { |
| 763 int ofrom[2]; | |
| 764 int parity = 0; | 846 int parity = 0; |
| 765 char my_stringend = 0; | 847 char my_stringend = 0; |
| 766 int string_lossage = 0; | 848 int string_lossage = 0; |
| 767 int comment_end = from; | 849 int comment_end = from; |
| 768 | 850 int comstart_pos = 0; |
| 769 ofrom[0] = ofrom[1] = from; | 851 int comstart_parity = 0; |
| 770 | 852 |
| 771 /* At beginning of range to scan, we're outside of strings; | 853 /* At beginning of range to scan, we're outside of strings; |
| 772 that determines quote parity to the comment-end. */ | 854 that determines quote parity to the comment-end. */ |
| 773 while (from != stop) | 855 while (from != stop) |
| 774 { | 856 { |
| 797 | 879 |
| 798 /* Ignore escaped characters. */ | 880 /* Ignore escaped characters. */ |
| 799 if (char_quoted (from)) | 881 if (char_quoted (from)) |
| 800 continue; | 882 continue; |
| 801 | 883 |
| 802 /* Track parity of quotes between here and comment-end. */ | 884 /* Track parity of quotes. */ |
| 803 if (code == Sstring) | 885 if (code == Sstring) |
| 804 { | 886 { |
| 805 parity ^= 1; | 887 parity ^= 1; |
| 806 if (my_stringend == 0) | 888 if (my_stringend == 0) |
| 807 my_stringend = c; | 889 my_stringend = c; |
| 808 /* We have two kinds of string delimiters. | 890 /* If we have two kinds of string delimiters. |
| 809 There's no way to grok this scanning backwards. */ | 891 There's no way to grok this scanning backwards. */ |
| 810 else if (my_stringend != c) | 892 else if (my_stringend != c) |
| 811 string_lossage = 1; | 893 string_lossage = 1; |
| 812 } | 894 } |
| 813 | 895 |
| 814 /* Record comment-starters according to that | 896 /* Record comment-starters according to that |
| 815 quote-parity to the comment-end. */ | 897 quote-parity to the comment-end. */ |
| 816 if (code == Scomment) | 898 if (code == Scomment) |
| 817 ofrom[parity] = from; | 899 { |
| 818 | 900 comstart_parity = parity; |
| 819 /* If we come to another comment-end, | 901 comstart_pos = from; |
| 820 assume it's not inside a string. | 902 } |
| 821 That determines the quote parity to the comment-end. | 903 |
| 822 Note that the comment style this character ends must | 904 /* If we find another earlier comment-ender, |
| 823 match the style that we have begun */ | 905 any comment-starts earier than that don't count |
| 906 (because they go with the earlier comment-ender). */ | |
| 824 if (code == Sendcomment | 907 if (code == Sendcomment |
| 825 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle) | 908 && SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)) == comstyle) |
| 826 break; | 909 break; |
| 910 | |
| 911 /* Assume a defun-start point is outside of strings. */ | |
| 912 if (code == Sopen | |
| 913 && (from == stop || FETCH_CHAR (from - 1) == '\n')) | |
| 914 break; | |
| 827 } | 915 } |
| 828 if (string_lossage) | 916 |
| 917 if (comstart_pos == 0) | |
| 918 from = comment_end; | |
| 919 /* If the earliest comment starter | |
| 920 is followed by uniform paired string quotes or none, | |
| 921 we know it can't be inside a string | |
| 922 since if it were then the comment ender would be inside one. | |
| 923 So it does start a comment. Skip back to it. */ | |
| 924 else if (comstart_parity == 0 && !string_lossage) | |
| 925 from = comstart_pos; | |
| 926 else | |
| 829 { | 927 { |
| 830 /* We had two kinds of string delimiters mixed up | 928 /* We had two kinds of string delimiters mixed up |
| 831 together. Decode this going forwards. | 929 together. Decode this going forwards. |
| 832 Scan fwd from the previous comment ender | 930 Scan fwd from the previous comment ender |
| 833 to the one in question; this records where we | 931 to the one in question; this records where we |
| 834 last passed a comment starter. */ | 932 last passed a comment starter. */ |
| 835 struct lisp_parse_state state; | 933 struct lisp_parse_state state; |
| 836 scan_sexps_forward (&state, from + 1, comment_end - 1, | 934 scan_sexps_forward (&state, find_defun_start (comment_end), |
| 837 -10000, 0, Qnil); | 935 comment_end - 1, -10000, 0, Qnil); |
| 838 if (state.incomment) | 936 if (state.incomment) |
| 839 from = state.comstart; | 937 from = state.comstart; |
| 840 else | 938 else |
| 841 /* We can't grok this as a comment; scan it normally. */ | 939 /* We can't grok this as a comment; scan it normally. */ |
| 842 from = comment_end; | 940 from = comment_end; |
| 843 } | 941 } |
| 844 else | |
| 845 from = ofrom[parity]; | |
| 846 } | 942 } |
| 847 break; | 943 break; |
| 848 | 944 |
| 849 case Sstring: | 945 case Sstring: |
| 850 stringterm = FETCH_CHAR (from); | 946 stringterm = FETCH_CHAR (from); |
