Mercurial > hg > xemacs-beta
comparison src/syntax.c @ 460:223736d75acb r21-2-45
Import from CVS: tag r21-2-45
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:43:24 +0200 |
parents | 1ccc32a20af4 |
children | 0784d089fdc9 |
comparison
equal
deleted
inserted
replaced
459:9d4fd877b885 | 460:223736d75acb |
---|---|
26 #include <config.h> | 26 #include <config.h> |
27 #include "lisp.h" | 27 #include "lisp.h" |
28 | 28 |
29 #include "buffer.h" | 29 #include "buffer.h" |
30 #include "syntax.h" | 30 #include "syntax.h" |
31 #include "extents.h" | |
31 | 32 |
32 /* Here is a comment from Ken'ichi HANDA <handa@etl.go.jp> | 33 /* Here is a comment from Ken'ichi HANDA <handa@etl.go.jp> |
33 explaining the purpose of the Sextword syntax category: | 34 explaining the purpose of the Sextword syntax category: |
34 | 35 |
35 Japanese words are not separated by spaces, which makes finding word | 36 Japanese words are not separated by spaces, which makes finding word |
53 two such characters. */ | 54 two such characters. */ |
54 | 55 |
55 /* Mule 2.4 doesn't seem to have Sextword - I'm removing it -- mrb */ | 56 /* Mule 2.4 doesn't seem to have Sextword - I'm removing it -- mrb */ |
56 /* Recovered by tomo */ | 57 /* Recovered by tomo */ |
57 | 58 |
59 #define ST_COMMENT_STYLE 0x101 | |
60 #define ST_STRING_STYLE 0x102 | |
61 | |
62 Lisp_Object Qsyntax_table; | |
63 int lookup_syntax_properties; | |
64 | |
58 Lisp_Object Qsyntax_table_p; | 65 Lisp_Object Qsyntax_table_p; |
59 | 66 |
60 int words_include_escapes; | 67 int words_include_escapes; |
61 | 68 |
62 int parse_sexp_ignore_comments; | 69 int parse_sexp_ignore_comments; |
72 | 79 |
73 /* Tell the regex routines which buffer to access for SYNTAX() lookups | 80 /* Tell the regex routines which buffer to access for SYNTAX() lookups |
74 and the like. */ | 81 and the like. */ |
75 struct buffer *regex_emacs_buffer; | 82 struct buffer *regex_emacs_buffer; |
76 | 83 |
77 /* Tell the regex routines whether buffer is used or not. */ | 84 /* In Emacs, this is the string or buffer in which we |
78 int regex_emacs_buffer_p; | 85 are matching. It is used for looking up syntax properties. */ |
86 Lisp_Object regex_match_object; | |
79 | 87 |
80 Lisp_Object Vstandard_syntax_table; | 88 Lisp_Object Vstandard_syntax_table; |
81 | 89 |
82 Lisp_Object Vsyntax_designator_chars_string; | 90 Lisp_Object Vsyntax_designator_chars_string; |
83 | 91 |
86 struct lisp_parse_state | 94 struct lisp_parse_state |
87 { | 95 { |
88 int depth; /* Depth at end of parsing */ | 96 int depth; /* Depth at end of parsing */ |
89 Emchar instring; /* -1 if not within string, else desired terminator */ | 97 Emchar instring; /* -1 if not within string, else desired terminator */ |
90 int incomment; /* Nonzero if within a comment at end of parsing */ | 98 int incomment; /* Nonzero if within a comment at end of parsing */ |
91 int comstyle; /* comment style a=0, or b=1 */ | 99 int comstyle; /* comment style a=0, or b=1, or ST_COMMENT_STYLE */ |
92 int quoted; /* Nonzero if just after an escape char at end of | 100 int quoted; /* Nonzero if just after an escape char at end of |
93 parsing */ | 101 parsing */ |
94 Bufpos thislevelstart;/* Char number of most recent start-of-expression | 102 Bufpos thislevelstart;/* Char number of most recent start-of-expression |
95 at current level */ | 103 at current level */ |
96 Bufpos prevlevelstart;/* Char number of start of containing expression */ | 104 Bufpos prevlevelstart;/* Char number of start of containing expression */ |
97 Bufpos location; /* Char number at which parsing stopped */ | 105 Bufpos location; /* Char number at which parsing stopped */ |
98 int mindepth; /* Minimum depth seen while scanning */ | 106 int mindepth; /* Minimum depth seen while scanning */ |
99 Bufpos comstart; /* Position just after last comment starter */ | 107 Bufpos comstr_start; /* Position just after last comment/string starter */ |
108 Lisp_Object levelstarts; /* Char numbers of starts-of-expression | |
109 of levels (starting from outermost). */ | |
100 }; | 110 }; |
101 | 111 |
102 /* These variables are a cache for finding the start of a defun. | 112 /* These variables are a cache for finding the start of a defun. |
103 find_start_pos is the place for which the defun start was found. | 113 find_start_pos is the place for which the defun start was found. |
104 find_start_value is the defun start position found for it. | 114 find_start_value is the defun start position found for it. |
118 | 128 |
119 static Bufpos | 129 static Bufpos |
120 find_defun_start (struct buffer *buf, Bufpos pos) | 130 find_defun_start (struct buffer *buf, Bufpos pos) |
121 { | 131 { |
122 Bufpos tem; | 132 Bufpos tem; |
123 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
124 | 133 |
125 /* Use previous finding, if it's valid and applies to this inquiry. */ | 134 /* Use previous finding, if it's valid and applies to this inquiry. */ |
126 if (buf == find_start_buffer | 135 if (buf == find_start_buffer |
127 /* Reuse the defun-start even if POS is a little farther on. | 136 /* Reuse the defun-start even if POS is a little farther on. |
128 POS might be in the next defun, but that's ok. | 137 POS might be in the next defun, but that's ok. |
134 return find_start_value; | 143 return find_start_value; |
135 | 144 |
136 /* Back up to start of line. */ | 145 /* Back up to start of line. */ |
137 tem = find_next_newline (buf, pos, -1); | 146 tem = find_next_newline (buf, pos, -1); |
138 | 147 |
148 SETUP_SYNTAX_CACHE (tem, 1); | |
139 while (tem > BUF_BEGV (buf)) | 149 while (tem > BUF_BEGV (buf)) |
140 { | 150 { |
151 UPDATE_SYNTAX_CACHE_BACKWARD(tem); | |
152 | |
141 /* Open-paren at start of line means we found our defun-start. */ | 153 /* Open-paren at start of line means we found our defun-start. */ |
142 if (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, tem)) == Sopen) | 154 if (SYNTAX_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, tem)) == Sopen) |
143 break; | 155 break; |
144 /* Move to beg of previous line. */ | 156 /* Move to beg of previous line. */ |
145 tem = find_next_newline (buf, tem, -2); | 157 tem = find_next_newline (buf, tem, -2); |
146 } | 158 } |
147 | 159 |
219 buf->syntax_table = syntax_table; | 231 buf->syntax_table = syntax_table; |
220 buf->mirror_syntax_table = XCHAR_TABLE (syntax_table)->mirror_table; | 232 buf->mirror_syntax_table = XCHAR_TABLE (syntax_table)->mirror_table; |
221 /* Indicate that this buffer now has a specified syntax table. */ | 233 /* Indicate that this buffer now has a specified syntax table. */ |
222 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table); | 234 buf->local_var_flags |= XINT (buffer_local_flags.syntax_table); |
223 return syntax_table; | 235 return syntax_table; |
236 } | |
237 | |
238 /* The current syntax state */ | |
239 struct syntax_cache syntax_cache; | |
240 | |
241 | |
242 /* | |
243 Update syntax_cache to an appropriate setting for position POS | |
244 | |
245 The sign of COUNT gives the relative position of POS wrt the | |
246 previously valid interval. (not currently used) | |
247 | |
248 `syntax_cache.*_change' are the next and previous positions at | |
249 which syntax_code and c_s_t will need to be recalculated. | |
250 | |
251 #### Currently this code uses 'get-char-property', which will | |
252 return the "last smallest" extent at a given position. In cases | |
253 where overlapping extents are defined, this code will simply use | |
254 whatever is returned by get-char-property. | |
255 | |
256 It might be worth it at some point to merge provided syntax tables | |
257 outward to the current buffer. */ | |
258 | |
259 void | |
260 update_syntax_cache (int pos, int count, int init) | |
261 { | |
262 Lisp_Object tmp_table; | |
263 | |
264 if (init) | |
265 { | |
266 syntax_cache.prev_change = -1; | |
267 syntax_cache.next_change = -1; | |
268 } | |
269 | |
270 if (pos > syntax_cache.prev_change && | |
271 pos < syntax_cache.next_change) | |
272 { | |
273 /* do nothing */ | |
274 } | |
275 else | |
276 { | |
277 if (NILP (syntax_cache.object) || EQ (syntax_cache.object, Qt)) | |
278 { | |
279 int get_change_before = pos + 1; | |
280 | |
281 tmp_table = Fget_char_property (make_int(pos), Qsyntax_table, | |
282 make_buffer (syntax_cache.buffer), Qnil); | |
283 syntax_cache.next_change = | |
284 XINT (Fnext_extent_change (make_int (pos > 0 ? pos : 1), | |
285 make_buffer (syntax_cache.buffer))); | |
286 | |
287 if (get_change_before < 1) | |
288 get_change_before = 1; | |
289 else if (get_change_before > BUF_ZV (syntax_cache.buffer)) | |
290 get_change_before = BUF_ZV (syntax_cache.buffer); | |
291 | |
292 syntax_cache.prev_change = | |
293 XINT (Fprevious_extent_change (make_int (get_change_before), | |
294 make_buffer (syntax_cache.buffer))); | |
295 } | |
296 else | |
297 { | |
298 int get_change_before = pos + 1; | |
299 | |
300 tmp_table = Fget_char_property (make_int(pos), Qsyntax_table, | |
301 syntax_cache.object, Qnil); | |
302 syntax_cache.next_change = | |
303 XINT (Fnext_extent_change (make_int (pos >= 0 ? pos : 0), | |
304 syntax_cache.object)); | |
305 | |
306 if (get_change_before < 0) | |
307 get_change_before = 0; | |
308 else if (get_change_before > XSTRING_LENGTH(syntax_cache.object)) | |
309 get_change_before = XSTRING_LENGTH(syntax_cache.object); | |
310 | |
311 syntax_cache.prev_change = | |
312 XINT (Fprevious_extent_change (make_int (pos >= 0 ? pos : 0), | |
313 syntax_cache.object)); | |
314 } | |
315 | |
316 if (EQ (Fsyntax_table_p (tmp_table), Qt)) | |
317 { | |
318 syntax_cache.use_code = 0; | |
319 syntax_cache.current_syntax_table = | |
320 XCHAR_TABLE (tmp_table)->mirror_table; | |
321 } | |
322 else if (CONSP (tmp_table) && INTP (XCAR (tmp_table))) | |
323 { | |
324 syntax_cache.use_code = 1; | |
325 syntax_cache.syntax_code = XINT (XCAR(tmp_table)); | |
326 } | |
327 else | |
328 { | |
329 syntax_cache.use_code = 0; | |
330 syntax_cache.current_syntax_table = | |
331 syntax_cache.buffer->mirror_syntax_table; | |
332 } | |
333 } | |
224 } | 334 } |
225 | 335 |
226 /* Convert a letter which signifies a syntax code | 336 /* Convert a letter which signifies a syntax code |
227 into the code it signifies. | 337 into the code it signifies. |
228 This is used by modify-syntax-entry, and other things. */ | 338 This is used by modify-syntax-entry, and other things. */ |
244 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, | 354 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, |
245 0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol, | 355 0377, 0377, 0377, 0377, (char) Sescape, 0377, 0377, (char) Ssymbol, |
246 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* `, a, ... */ | 356 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, /* `, a, ... */ |
247 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, | 357 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, |
248 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, | 358 0377, 0377, 0377, 0377, 0377, 0377, 0377, (char) Sword, |
249 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377 | 359 0377, 0377, 0377, 0377, (char) Sstring_fence, 0377, 0377, 0377 |
250 }; | 360 }; |
251 | 361 |
252 const unsigned char syntax_code_spec[] = " .w_()'\"$\\/<>@"; | 362 const unsigned char syntax_code_spec[] = " .w_()'\"$\\/<>@!|"; |
253 | 363 |
254 DEFUN ("syntax-designator-chars", Fsyntax_designator_chars, 0, 0, 0, /* | 364 DEFUN ("syntax-designator-chars", Fsyntax_designator_chars, 0, 0, 0, /* |
255 Return a string of the recognized syntax designator chars. | 365 Return a string of the recognized syntax designator chars. |
256 The chars are ordered by their internal syntax codes, which are | 366 The chars are ordered by their internal syntax codes, which are |
257 numbered starting at 0. | 367 numbered starting at 0. |
349 | 459 |
350 Bufpos | 460 Bufpos |
351 scan_words (struct buffer *buf, Bufpos from, int count) | 461 scan_words (struct buffer *buf, Bufpos from, int count) |
352 { | 462 { |
353 Bufpos limit = count > 0 ? BUF_ZV (buf) : BUF_BEGV (buf); | 463 Bufpos limit = count > 0 ? BUF_ZV (buf) : BUF_BEGV (buf); |
354 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
355 Emchar ch0, ch1; | 464 Emchar ch0, ch1; |
356 enum syntaxcode code; | 465 enum syntaxcode code; |
357 | 466 |
467 SETUP_SYNTAX_CACHE_FOR_BUFFER (buf, from, count); | |
468 | |
358 /* #### is it really worth it to hand expand both cases? JV */ | 469 /* #### is it really worth it to hand expand both cases? JV */ |
359 while (count > 0) | 470 while (count > 0) |
360 { | 471 { |
361 QUIT; | 472 QUIT; |
362 | 473 |
363 while (1) | 474 while (1) |
364 { | 475 { |
365 if (from == limit) | 476 if (from == limit) |
366 return 0; | 477 return 0; |
367 | 478 |
479 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
368 ch0 = BUF_FETCH_CHAR (buf, from); | 480 ch0 = BUF_FETCH_CHAR (buf, from); |
369 code = SYNTAX_UNSAFE (mirrortab, ch0); | 481 code = SYNTAX_FROM_CACHE (mirrortab, ch0); |
370 | 482 |
371 from++; | 483 from++; |
372 if (words_include_escapes | 484 if (words_include_escapes |
373 && (code == Sescape || code == Scharquote)) | 485 && (code == Sescape || code == Scharquote)) |
374 break; | 486 break; |
378 | 490 |
379 QUIT; | 491 QUIT; |
380 | 492 |
381 while (from != limit) | 493 while (from != limit) |
382 { | 494 { |
495 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
383 ch1 = BUF_FETCH_CHAR (buf, from); | 496 ch1 = BUF_FETCH_CHAR (buf, from); |
384 code = SYNTAX_UNSAFE (mirrortab, ch1); | 497 code = SYNTAX_FROM_CACHE (mirrortab, ch1); |
385 if (!(words_include_escapes | 498 if (!(words_include_escapes |
386 && (code == Sescape || code == Scharquote))) | 499 && (code == Sescape || code == Scharquote))) |
387 if (code != Sword | 500 if (code != Sword |
388 #ifdef MULE | 501 #ifdef MULE |
389 || WORD_BOUNDARY_P (ch0, ch1) | 502 || WORD_BOUNDARY_P (ch0, ch1) |
405 while (1) | 518 while (1) |
406 { | 519 { |
407 if (from == limit) | 520 if (from == limit) |
408 return 0; | 521 return 0; |
409 | 522 |
523 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); | |
410 ch1 = BUF_FETCH_CHAR (buf, from - 1); | 524 ch1 = BUF_FETCH_CHAR (buf, from - 1); |
411 code = SYNTAX_UNSAFE (mirrortab, ch1); | 525 code = SYNTAX_FROM_CACHE (mirrortab, ch1); |
412 | |
413 from--; | 526 from--; |
527 | |
414 if (words_include_escapes | 528 if (words_include_escapes |
415 && (code == Sescape || code == Scharquote)) | 529 && (code == Sescape || code == Scharquote)) |
416 break; | 530 break; |
417 if (code == Sword) | 531 if (code == Sword) |
418 break; | 532 break; |
420 | 534 |
421 QUIT; | 535 QUIT; |
422 | 536 |
423 while (from != limit) | 537 while (from != limit) |
424 { | 538 { |
539 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); | |
425 ch0 = BUF_FETCH_CHAR (buf, from - 1); | 540 ch0 = BUF_FETCH_CHAR (buf, from - 1); |
426 code = SYNTAX_UNSAFE (mirrortab, ch0); | 541 code = SYNTAX_FROM_CACHE (mirrortab, ch0); |
542 | |
427 if (!(words_include_escapes | 543 if (!(words_include_escapes |
428 && (code == Sescape || code == Scharquote))) | 544 && (code == Sescape || code == Scharquote))) |
429 if (code != Sword | 545 if (code != Sword |
430 #ifdef MULE | 546 #ifdef MULE |
431 || WORD_BOUNDARY_P (ch0, ch1) | 547 || WORD_BOUNDARY_P (ch0, ch1) |
483 int targetdepth, int stopbefore, | 599 int targetdepth, int stopbefore, |
484 Lisp_Object oldstate, | 600 Lisp_Object oldstate, |
485 int commentstop); | 601 int commentstop); |
486 | 602 |
487 static int | 603 static int |
488 find_start_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask) | 604 find_start_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, |
605 int comstyle) | |
489 { | 606 { |
490 Emchar c; | 607 Emchar c; |
491 enum syntaxcode code; | 608 enum syntaxcode code; |
492 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
493 | 609 |
494 /* Look back, counting the parity of string-quotes, | 610 /* Look back, counting the parity of string-quotes, |
495 and recording the comment-starters seen. | 611 and recording the comment-starters seen. |
496 When we reach a safe place, assume that's not in a string; | 612 When we reach a safe place, assume that's not in a string; |
497 then step the main scan to the earliest comment-starter seen | 613 then step the main scan to the earliest comment-starter seen |
505 int string_lossage = 0; | 621 int string_lossage = 0; |
506 Bufpos comment_end = from; | 622 Bufpos comment_end = from; |
507 Bufpos comstart_pos = 0; | 623 Bufpos comstart_pos = 0; |
508 int comstart_parity = 0; | 624 int comstart_parity = 0; |
509 int styles_match_p = 0; | 625 int styles_match_p = 0; |
626 /* mask to match comment styles against; for ST_COMMENT_STYLE, this | |
627 will get set to SYNTAX_COMMENT_STYLE_B, but never get checked */ | |
628 int mask = comstyle ? SYNTAX_COMMENT_STYLE_B : SYNTAX_COMMENT_STYLE_A; | |
510 | 629 |
511 /* At beginning of range to scan, we're outside of strings; | 630 /* At beginning of range to scan, we're outside of strings; |
512 that determines quote parity to the comment-end. */ | 631 that determines quote parity to the comment-end. */ |
513 while (from != stop) | 632 while (from != stop) |
514 { | 633 { |
634 int syncode; | |
635 | |
515 /* Move back and examine a character. */ | 636 /* Move back and examine a character. */ |
516 from--; | 637 from--; |
638 UPDATE_SYNTAX_CACHE_BACKWARD (from); | |
517 | 639 |
518 c = BUF_FETCH_CHAR (buf, from); | 640 c = BUF_FETCH_CHAR (buf, from); |
519 code = SYNTAX_UNSAFE (mirrortab, c); | 641 code = SYNTAX_FROM_CACHE (mirrortab, c); |
642 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
520 | 643 |
521 /* is this a 1-char comment end sequence? if so, try | 644 /* is this a 1-char comment end sequence? if so, try |
522 to see if style matches previously extracted mask */ | 645 to see if style matches previously extracted mask */ |
523 if (code == Sendcomment) | 646 if (code == Sendcomment) |
524 { | 647 { |
525 styles_match_p = SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask); | |
526 } | |
527 | |
528 /* otherwise, is this a 2-char comment end sequence? */ | |
529 else if (from >= stop | |
530 && SYNTAX_END_P (mirrortab, c, BUF_FETCH_CHAR (buf, from+1))) | |
531 { | |
532 code = Sendcomment; | |
533 styles_match_p = | 648 styles_match_p = |
534 SYNTAX_STYLES_MATCH_END_P (mirrortab, c, | 649 SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) & mask; |
535 BUF_FETCH_CHAR (buf, from+1), | |
536 mask); | |
537 } | 650 } |
538 | 651 |
539 /* or are we looking at a 1-char comment start sequence | 652 /* or are we looking at a 1-char comment start sequence |
540 of the style matching mask? */ | 653 of the style matching mask? */ |
541 else if (code == Scomment | 654 else if (code == Scomment) |
542 && SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask)) | 655 { |
543 { | 656 styles_match_p = |
544 styles_match_p = 1; | 657 SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) & mask; |
545 } | 658 } |
546 | 659 |
547 /* or possibly, a 2-char comment start sequence */ | 660 /* otherwise, is this a 2-char comment end or start sequence? */ |
548 else if (from >= stop | 661 else if (from > stop) |
549 && SYNTAX_STYLES_MATCH_START_P (mirrortab, c, | 662 do |
550 BUF_FETCH_CHAR (buf, from+1), | 663 { |
551 mask)) | 664 /* 2-char comment end sequence? */ |
552 { | 665 if (SYNTAX_CODE_END_SECOND_P (syncode)) |
553 code = Scomment; | 666 { |
554 styles_match_p = 1; | 667 int prev_syncode; |
555 } | 668 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); |
669 prev_syncode = | |
670 SYNTAX_CODE_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from - 1)); | |
671 | |
672 if (SYNTAX_CODES_END_P (prev_syncode, syncode)) | |
673 { | |
674 code = Sendcomment; | |
675 styles_match_p = | |
676 SYNTAX_CODES_COMMENT_MASK_END (prev_syncode, syncode); | |
677 from--; | |
678 UPDATE_SYNTAX_CACHE_BACKWARD (from); | |
679 c = BUF_FETCH_CHAR (buf, from); | |
680 | |
681 /* Found a comment-end sequence, so skip past the | |
682 check for a comment-start */ | |
683 break; | |
684 } | |
685 } | |
686 | |
687 /* 2-char comment start sequence? */ | |
688 if (SYNTAX_CODE_START_SECOND_P (syncode)) | |
689 { | |
690 int prev_syncode; | |
691 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); | |
692 prev_syncode = | |
693 SYNTAX_CODE_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from - 1)); | |
694 | |
695 if (SYNTAX_CODES_START_P (prev_syncode, syncode)) | |
696 { | |
697 code = Scomment; | |
698 styles_match_p = | |
699 SYNTAX_CODES_COMMENT_MASK_START (prev_syncode, syncode); | |
700 from--; | |
701 UPDATE_SYNTAX_CACHE_BACKWARD (from); | |
702 c = BUF_FETCH_CHAR (buf, from); | |
703 } | |
704 } | |
705 } while (0); | |
556 | 706 |
557 /* Ignore escaped characters. */ | 707 /* Ignore escaped characters. */ |
558 if (char_quoted (buf, from)) | 708 if (char_quoted (buf, from)) |
559 continue; | 709 continue; |
560 | 710 |
565 if (my_stringend == 0) | 715 if (my_stringend == 0) |
566 my_stringend = c; | 716 my_stringend = c; |
567 /* If we have two kinds of string delimiters. | 717 /* If we have two kinds of string delimiters. |
568 There's no way to grok this scanning backwards. */ | 718 There's no way to grok this scanning backwards. */ |
569 else if (my_stringend != c) | 719 else if (my_stringend != c) |
720 string_lossage = 1; | |
721 } | |
722 | |
723 if (code == Sstring_fence || code == Scomment_fence) | |
724 { | |
725 parity ^= 1; | |
726 if (my_stringend == 0) | |
727 my_stringend = | |
728 code == Sstring_fence ? ST_STRING_STYLE : ST_COMMENT_STYLE; | |
729 /* If we have two kinds of string delimiters. | |
730 There's no way to grok this scanning backwards. */ | |
731 else if (my_stringend != (code == Sstring_fence | |
732 ? ST_STRING_STYLE : ST_COMMENT_STYLE)) | |
570 string_lossage = 1; | 733 string_lossage = 1; |
571 } | 734 } |
572 | 735 |
573 /* Record comment-starters according to that | 736 /* Record comment-starters according to that |
574 quote-parity to the comment-end. */ | 737 quote-parity to the comment-end. */ |
609 | 772 |
610 struct lisp_parse_state state; | 773 struct lisp_parse_state state; |
611 scan_sexps_forward (buf, &state, find_defun_start (buf, comment_end), | 774 scan_sexps_forward (buf, &state, find_defun_start (buf, comment_end), |
612 comment_end - 1, -10000, 0, Qnil, 0); | 775 comment_end - 1, -10000, 0, Qnil, 0); |
613 if (state.incomment) | 776 if (state.incomment) |
614 from = state.comstart; | 777 from = state.comstr_start; |
615 else | 778 else |
616 /* We can't grok this as a comment; scan it normally. */ | 779 /* We can't grok this as a comment; scan it normally. */ |
617 from = comment_end; | 780 from = comment_end; |
781 UPDATE_SYNTAX_CACHE_FORWARD (from - 1); | |
618 } | 782 } |
619 return from; | 783 return from; |
620 } | 784 } |
621 | 785 |
622 static Bufpos | 786 static Bufpos |
623 find_end_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int mask) | 787 find_end_of_comment (struct buffer *buf, Bufpos from, Bufpos stop, int comstyle) |
624 { | 788 { |
625 int c; | 789 int c; |
626 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | 790 int prev_code; |
627 | 791 /* mask to match comment styles against; for ST_COMMENT_STYLE, this |
792 will get set to SYNTAX_COMMENT_STYLE_B, but never get checked */ | |
793 int mask = comstyle ? SYNTAX_COMMENT_STYLE_B : SYNTAX_COMMENT_STYLE_A; | |
794 | |
795 /* This is only called by functions which have already set up the | |
796 syntax_cache and are keeping it up-to-date */ | |
628 while (1) | 797 while (1) |
629 { | 798 { |
630 if (from == stop) | 799 if (from == stop) |
631 { | 800 { |
632 return -1; | 801 return -1; |
633 } | 802 } |
803 | |
804 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
634 c = BUF_FETCH_CHAR (buf, from); | 805 c = BUF_FETCH_CHAR (buf, from); |
635 if (SYNTAX_UNSAFE (mirrortab, c) == Sendcomment | 806 |
636 && SYNTAX_STYLES_MATCH_1CHAR_P (mirrortab, c, mask)) | 807 /* Test for generic comments */ |
808 if (comstyle == ST_COMMENT_STYLE) | |
809 { | |
810 if (SYNTAX_FROM_CACHE (mirrortab, c) == Scomment_fence) | |
811 { | |
812 from++; | |
813 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
814 break; | |
815 } | |
816 from++; | |
817 continue; /* No need to test other comment styles in a | |
818 generic comment */ | |
819 } | |
820 else | |
821 | |
822 if (SYNTAX_FROM_CACHE (mirrortab, c) == Sendcomment | |
823 && SYNTAX_CODE_MATCHES_1CHAR_P | |
824 (SYNTAX_CODE_FROM_CACHE (mirrortab, c), mask)) | |
637 /* we have encountered a comment end of the same style | 825 /* we have encountered a comment end of the same style |
638 as the comment sequence which began this comment | 826 as the comment sequence which began this comment |
639 section */ | 827 section */ |
640 break; | 828 { |
641 | 829 from++; |
830 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
831 break; | |
832 } | |
833 | |
834 prev_code = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
642 from++; | 835 from++; |
836 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
643 if (from < stop | 837 if (from < stop |
644 && SYNTAX_STYLES_MATCH_END_P (mirrortab, c, | 838 && SYNTAX_CODES_MATCH_END_P |
645 BUF_FETCH_CHAR (buf, from), mask)) | 839 (prev_code, |
840 SYNTAX_CODE_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from)), | |
841 mask) | |
842 | |
843 ) | |
646 /* we have encountered a comment end of the same style | 844 /* we have encountered a comment end of the same style |
647 as the comment sequence which began this comment | 845 as the comment sequence which began this comment |
648 section */ | 846 section */ |
649 { from++; break; } | 847 { |
848 from++; | |
849 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
850 break; | |
851 } | |
650 } | 852 } |
651 return from; | 853 return from; |
652 } | 854 } |
653 | 855 |
654 | 856 |
672 { | 874 { |
673 Bufpos from; | 875 Bufpos from; |
674 Bufpos stop; | 876 Bufpos stop; |
675 Emchar c; | 877 Emchar c; |
676 enum syntaxcode code; | 878 enum syntaxcode code; |
879 int syncode; | |
677 EMACS_INT n; | 880 EMACS_INT n; |
678 struct buffer *buf = decode_buffer (buffer, 0); | 881 struct buffer *buf = decode_buffer (buffer, 0); |
679 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
680 | 882 |
681 if (NILP (count)) | 883 if (NILP (count)) |
682 n = 1; | 884 n = 1; |
683 else | 885 else |
684 { | 886 { |
686 n = XINT (count); | 888 n = XINT (count); |
687 } | 889 } |
688 | 890 |
689 from = BUF_PT (buf); | 891 from = BUF_PT (buf); |
690 | 892 |
893 SETUP_SYNTAX_CACHE (from, n); | |
691 while (n > 0) | 894 while (n > 0) |
692 { | 895 { |
693 QUIT; | 896 QUIT; |
694 | 897 |
695 stop = BUF_ZV (buf); | 898 stop = BUF_ZV (buf); |
696 while (from < stop) | 899 while (from < stop) |
697 { | 900 { |
698 int mask = 0; /* mask for finding matching comment style */ | 901 int comstyle = 0; /* mask for finding matching comment style */ |
699 | 902 |
700 if (char_quoted (buf, from)) | 903 if (char_quoted (buf, from)) |
701 { | 904 { |
702 from++; | 905 from++; |
703 continue; | 906 continue; |
704 } | 907 } |
705 | 908 |
909 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
706 c = BUF_FETCH_CHAR (buf, from); | 910 c = BUF_FETCH_CHAR (buf, from); |
707 code = SYNTAX (mirrortab, c); | 911 code = SYNTAX_FROM_CACHE (mirrortab, c); |
912 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
708 | 913 |
709 if (code == Scomment) | 914 if (code == Scomment) |
710 { | 915 { |
711 /* we have encountered a single character comment start | 916 /* we have encountered a single character comment start |
712 sequence, and we are ignoring all text inside comments. | 917 sequence, and we are ignoring all text inside comments. |
713 we must record the comment style this character begins | 918 we must record the comment style this character begins |
714 so that later, only a comment end of the same style actually | 919 so that later, only a comment end of the same style actually |
715 ends the comment section */ | 920 ends the comment section */ |
716 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c); | 921 comstyle = SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) |
717 } | 922 == SYNTAX_COMMENT_STYLE_A ? 0 : 1; |
923 } | |
924 | |
925 else if (code == Scomment_fence) | |
926 { | |
927 from++; | |
928 code = Scomment; | |
929 comstyle = ST_COMMENT_STYLE; | |
930 } | |
718 | 931 |
719 else if (from < stop | 932 else if (from < stop |
720 && SYNTAX_START_P (mirrortab, c, BUF_FETCH_CHAR (buf, from+1))) | 933 && SYNTAX_CODE_START_FIRST_P (syncode)) |
721 { | 934 { |
722 /* we have encountered a 2char comment start sequence and we | 935 int next_syncode; |
723 are ignoring all text inside comments. we must record | 936 UPDATE_SYNTAX_CACHE_FORWARD (from + 1); |
724 the comment style this sequence begins so that later, | 937 next_syncode = |
725 only a comment end of the same style actually ends | 938 SYNTAX_CODE_FROM_CACHE (mirrortab, |
726 the comment section */ | 939 BUF_FETCH_CHAR (buf, from + 1)); |
727 code = Scomment; | 940 |
728 mask = SYNTAX_COMMENT_MASK_START (mirrortab, c, | 941 if (SYNTAX_CODES_START_P (syncode, next_syncode)) |
729 BUF_FETCH_CHAR (buf, from+1)); | 942 { |
730 from++; | 943 /* we have encountered a 2char comment start sequence and we |
944 are ignoring all text inside comments. we must record | |
945 the comment style this sequence begins so that later, | |
946 only a comment end of the same style actually ends | |
947 the comment section */ | |
948 code = Scomment; | |
949 comstyle = | |
950 SYNTAX_CODES_COMMENT_MASK_START (syncode, next_syncode) | |
951 == SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
952 from++; | |
953 } | |
731 } | 954 } |
732 | 955 |
733 if (code == Scomment) | 956 if (code == Scomment) |
734 { | 957 { |
735 Bufpos newfrom; | 958 Bufpos newfrom = find_end_of_comment (buf, from, stop, comstyle); |
736 | |
737 newfrom = find_end_of_comment (buf, from, stop, mask); | |
738 if (newfrom < 0) | 959 if (newfrom < 0) |
739 { | 960 { |
740 /* we stopped because from==stop */ | 961 /* we stopped because from==stop */ |
741 BUF_SET_PT (buf, stop); | 962 BUF_SET_PT (buf, stop); |
742 return Qnil; | 963 return Qnil; |
765 QUIT; | 986 QUIT; |
766 | 987 |
767 stop = BUF_BEGV (buf); | 988 stop = BUF_BEGV (buf); |
768 while (from > stop) | 989 while (from > stop) |
769 { | 990 { |
770 int mask = 0; /* mask for finding matching comment style */ | 991 int comstyle = 0; /* mask for finding matching comment style */ |
771 | 992 |
772 from--; | 993 from--; |
773 if (char_quoted (buf, from)) | 994 if (char_quoted (buf, from)) |
774 { | 995 { |
775 from--; | 996 from--; |
776 continue; | 997 continue; |
777 } | 998 } |
778 | 999 |
779 c = BUF_FETCH_CHAR (buf, from); | 1000 c = BUF_FETCH_CHAR (buf, from); |
780 code = SYNTAX (mirrortab, c); | 1001 code = SYNTAX_FROM_CACHE (mirrortab, c); |
1002 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
781 | 1003 |
782 if (code == Sendcomment) | 1004 if (code == Sendcomment) |
783 { | 1005 { |
784 /* we have found a single char end comment. we must record | 1006 /* we have found a single char end comment. we must record |
785 the comment style encountered so that later, we can match | 1007 the comment style encountered so that later, we can match |
786 only the proper comment begin sequence of the same style */ | 1008 only the proper comment begin sequence of the same style */ |
787 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c); | 1009 comstyle = SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) |
1010 == SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
1011 } | |
1012 | |
1013 else if (code == Scomment_fence) | |
1014 { | |
1015 code = Sendcomment; | |
1016 comstyle = ST_COMMENT_STYLE; | |
788 } | 1017 } |
789 | 1018 |
790 else if (from > stop | 1019 else if (from > stop |
791 && SYNTAX_END_P (mirrortab, BUF_FETCH_CHAR (buf, from - 1), c) | 1020 && SYNTAX_CODE_END_SECOND_P (syncode)) |
792 && !char_quoted (buf, from - 1)) | 1021 { |
793 { | 1022 int prev_syncode; |
794 /* We must record the comment style encountered so that | 1023 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); |
795 later, we can match only the proper comment begin | 1024 prev_syncode = |
796 sequence of the same style. */ | 1025 SYNTAX_CODE_FROM_CACHE (mirrortab, |
797 code = Sendcomment; | 1026 BUF_FETCH_CHAR (buf, from - 1)); |
798 mask = SYNTAX_COMMENT_MASK_END (mirrortab, | 1027 if (SYNTAX_CODES_END_P (prev_syncode, syncode)) |
799 BUF_FETCH_CHAR (buf, from - 1), | 1028 { |
800 c); | 1029 /* We must record the comment style encountered so that |
801 from--; | 1030 later, we can match only the proper comment begin |
1031 sequence of the same style. */ | |
1032 code = Sendcomment; | |
1033 comstyle = SYNTAX_CODES_COMMENT_MASK_END | |
1034 (prev_syncode, syncode) == SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
1035 from--; | |
1036 } | |
802 } | 1037 } |
803 | 1038 |
804 if (code == Sendcomment) | 1039 if (code == Sendcomment) |
805 { | 1040 { |
806 from = find_start_of_comment (buf, from, stop, mask); | 1041 from = find_start_of_comment (buf, from, stop, comstyle); |
807 break; | 1042 break; |
808 } | 1043 } |
809 | 1044 |
810 else if (code != Swhitespace | 1045 else if (code != Swhitespace |
811 && SYNTAX (mirrortab, c) != Scomment | 1046 && code != Scomment |
812 && SYNTAX (mirrortab, c) != Sendcomment) | 1047 && code != Sendcomment) |
813 { | 1048 { |
814 BUF_SET_PT (buf, from + 1); | 1049 BUF_SET_PT (buf, from + 1); |
815 return Qnil; | 1050 return Qnil; |
816 } | 1051 } |
817 } | 1052 } |
831 Bufpos stop; | 1066 Bufpos stop; |
832 Emchar c; | 1067 Emchar c; |
833 int quoted; | 1068 int quoted; |
834 int mathexit = 0; | 1069 int mathexit = 0; |
835 enum syntaxcode code; | 1070 enum syntaxcode code; |
1071 int syncode; | |
836 int min_depth = depth; /* Err out if depth gets less than this. */ | 1072 int min_depth = depth; /* Err out if depth gets less than this. */ |
837 Lisp_Object syntaxtab = buf->syntax_table; | |
838 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
839 | 1073 |
840 if (depth > 0) min_depth = 0; | 1074 if (depth > 0) min_depth = 0; |
841 | 1075 |
1076 SETUP_SYNTAX_CACHE_FOR_BUFFER (buf, from, count); | |
842 while (count > 0) | 1077 while (count > 0) |
843 { | 1078 { |
844 QUIT; | 1079 QUIT; |
845 | 1080 |
846 stop = BUF_ZV (buf); | 1081 stop = BUF_ZV (buf); |
847 while (from < stop) | 1082 while (from < stop) |
848 { | 1083 { |
849 int mask = 0; /* mask for finding matching comment style */ | 1084 int comstyle = 0; /* mask for finding matching comment style */ |
850 | 1085 |
1086 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
851 c = BUF_FETCH_CHAR (buf, from); | 1087 c = BUF_FETCH_CHAR (buf, from); |
852 code = SYNTAX_UNSAFE (mirrortab, c); | 1088 code = SYNTAX_FROM_CACHE (mirrortab, c); |
1089 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
853 from++; | 1090 from++; |
854 | 1091 |
855 /* a 1-char comment start sequence */ | 1092 /* a 1-char comment start sequence */ |
856 if (code == Scomment && parse_sexp_ignore_comments) | 1093 if (code == Scomment && parse_sexp_ignore_comments) |
857 { | 1094 { |
858 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c); | 1095 comstyle = SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) == |
1096 SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
859 } | 1097 } |
860 | 1098 |
861 /* else, a 2-char comment start sequence? */ | 1099 /* else, a 2-char comment start sequence? */ |
862 else if (from < stop | 1100 else if (from < stop |
863 && SYNTAX_START_P (mirrortab, c, BUF_FETCH_CHAR (buf, from)) | 1101 && SYNTAX_CODE_START_FIRST_P (syncode) |
864 && parse_sexp_ignore_comments) | 1102 && parse_sexp_ignore_comments) |
865 { | 1103 { |
1104 int next_syncode; | |
1105 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
1106 next_syncode = | |
1107 SYNTAX_CODE_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from)); | |
1108 | |
1109 if (SYNTAX_CODES_START_P (syncode, next_syncode)) | |
1110 { | |
866 /* we have encountered a comment start sequence and we | 1111 /* we have encountered a comment start sequence and we |
867 are ignoring all text inside comments. we must record | 1112 are ignoring all text inside comments. we must record |
868 the comment style this sequence begins so that later, | 1113 the comment style this sequence begins so that later, |
869 only a comment end of the same style actually ends | 1114 only a comment end of the same style actually ends |
870 the comment section */ | 1115 the comment section */ |
871 code = Scomment; | 1116 code = Scomment; |
872 mask = SYNTAX_COMMENT_MASK_START (mirrortab, c, | 1117 comstyle = SYNTAX_CODES_COMMENT_MASK_START |
873 BUF_FETCH_CHAR (buf, from)); | 1118 (syncode, next_syncode) == SYNTAX_COMMENT_STYLE_A ? 0 : 1; |
874 from++; | 1119 from++; |
875 } | 1120 } |
876 | 1121 } |
877 if (SYNTAX_PREFIX_UNSAFE (mirrortab, c)) | 1122 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1123 | |
1124 if (SYNTAX_CODE_PREFIX (syncode)) | |
878 continue; | 1125 continue; |
879 | 1126 |
880 switch (code) | 1127 switch (code) |
881 { | 1128 { |
882 case Sescape: | 1129 case Sescape: |
888 case Ssymbol: | 1135 case Ssymbol: |
889 if (depth || !sexpflag) break; | 1136 if (depth || !sexpflag) break; |
890 /* This word counts as a sexp; return at end of it. */ | 1137 /* This word counts as a sexp; return at end of it. */ |
891 while (from < stop) | 1138 while (from < stop) |
892 { | 1139 { |
893 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from))) | 1140 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1141 switch (SYNTAX_FROM_CACHE (mirrortab, | |
1142 BUF_FETCH_CHAR (buf, from))) | |
894 { | 1143 { |
895 case Scharquote: | 1144 case Scharquote: |
896 case Sescape: | 1145 case Sescape: |
897 from++; | 1146 from++; |
898 if (from == stop) goto lose; | 1147 if (from == stop) goto lose; |
906 } | 1155 } |
907 from++; | 1156 from++; |
908 } | 1157 } |
909 goto done; | 1158 goto done; |
910 | 1159 |
1160 case Scomment_fence: | |
1161 comstyle = ST_COMMENT_STYLE; | |
911 case Scomment: | 1162 case Scomment: |
912 if (!parse_sexp_ignore_comments) | 1163 if (!parse_sexp_ignore_comments) |
913 break; | 1164 break; |
1165 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
914 { | 1166 { |
915 Bufpos newfrom = find_end_of_comment (buf, from, stop, mask); | 1167 Bufpos newfrom = |
1168 find_end_of_comment (buf, from, stop, comstyle); | |
916 if (newfrom < 0) | 1169 if (newfrom < 0) |
917 { | 1170 { |
918 /* we stopped because from == stop in search forward */ | 1171 /* we stopped because from == stop in search forward */ |
919 from = stop; | 1172 from = stop; |
920 if (depth == 0) | 1173 if (depth == 0) |
950 return Qnil; | 1203 return Qnil; |
951 error ("Containing expression ends prematurely"); | 1204 error ("Containing expression ends prematurely"); |
952 } | 1205 } |
953 break; | 1206 break; |
954 | 1207 |
1208 case Sstring_fence: | |
955 case Sstring: | 1209 case Sstring: |
956 { | 1210 { |
1211 Emchar stringterm; | |
1212 | |
1213 if (code != Sstring_fence) | |
1214 { | |
957 /* XEmacs change: call syntax_match on character */ | 1215 /* XEmacs change: call syntax_match on character */ |
958 Emchar ch = BUF_FETCH_CHAR (buf, from - 1); | 1216 Emchar ch = BUF_FETCH_CHAR (buf, from - 1); |
959 Lisp_Object stermobj = syntax_match (syntaxtab, ch); | 1217 Lisp_Object stermobj = |
960 Emchar stringterm; | 1218 syntax_match (syntax_cache.current_syntax_table, ch); |
961 | 1219 |
962 if (CHARP (stermobj)) | 1220 if (CHARP (stermobj)) |
963 stringterm = XCHAR (stermobj); | 1221 stringterm = XCHAR (stermobj); |
964 else | 1222 else |
965 stringterm = ch; | 1223 stringterm = ch; |
1224 } | |
1225 else | |
1226 stringterm = '\0'; /* avoid compiler warnings */ | |
966 | 1227 |
967 while (1) | 1228 while (1) |
968 { | 1229 { |
969 if (from >= stop) | 1230 if (from >= stop) |
970 goto lose; | 1231 goto lose; |
971 if (BUF_FETCH_CHAR (buf, from) == stringterm) | 1232 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1233 c = BUF_FETCH_CHAR (buf, from); | |
1234 if (code == Sstring | |
1235 ? c == stringterm | |
1236 : SYNTAX_FROM_CACHE (mirrortab, c) == Sstring_fence) | |
972 break; | 1237 break; |
973 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from))) | 1238 |
1239 switch (SYNTAX_FROM_CACHE (mirrortab, c)) | |
974 { | 1240 { |
975 case Scharquote: | 1241 case Scharquote: |
976 case Sescape: | 1242 case Sescape: |
977 from++; | 1243 from++; |
978 break; | 1244 break; |
1007 QUIT; | 1273 QUIT; |
1008 | 1274 |
1009 stop = BUF_BEGV (buf); | 1275 stop = BUF_BEGV (buf); |
1010 while (from > stop) | 1276 while (from > stop) |
1011 { | 1277 { |
1012 int mask = 0; /* mask for finding matching comment style */ | 1278 int comstyle = 0; /* mask for finding matching comment style */ |
1013 | 1279 |
1014 from--; | 1280 from--; |
1281 UPDATE_SYNTAX_CACHE_BACKWARD (from); | |
1015 quoted = char_quoted (buf, from); | 1282 quoted = char_quoted (buf, from); |
1016 if (quoted) | 1283 if (quoted) |
1284 { | |
1017 from--; | 1285 from--; |
1286 UPDATE_SYNTAX_CACHE_BACKWARD (from); | |
1287 } | |
1018 | 1288 |
1019 c = BUF_FETCH_CHAR (buf, from); | 1289 c = BUF_FETCH_CHAR (buf, from); |
1020 code = SYNTAX_UNSAFE (mirrortab, c); | 1290 code = SYNTAX_FROM_CACHE (mirrortab, c); |
1291 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
1021 | 1292 |
1022 if (code == Sendcomment && parse_sexp_ignore_comments) | 1293 if (code == Sendcomment && parse_sexp_ignore_comments) |
1023 { | 1294 { |
1024 /* we have found a single char end comment. we must record | 1295 /* we have found a single char end comment. we must record |
1025 the comment style encountered so that later, we can match | 1296 the comment style encountered so that later, we can match |
1026 only the proper comment begin sequence of the same style */ | 1297 only the proper comment begin sequence of the same style */ |
1027 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, c); | 1298 comstyle = SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) |
1299 == SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
1028 } | 1300 } |
1029 | 1301 |
1030 else if (from > stop | 1302 else if (from > stop |
1031 && SYNTAX_END_P (mirrortab, BUF_FETCH_CHAR (buf, from-1), c) | 1303 && SYNTAX_CODE_END_SECOND_P (syncode) |
1032 && !char_quoted (buf, from - 1) | 1304 && !char_quoted (buf, from - 1) |
1033 && parse_sexp_ignore_comments) | 1305 && parse_sexp_ignore_comments) |
1034 { | 1306 { |
1307 int prev_syncode; | |
1308 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); | |
1309 prev_syncode = SYNTAX_CODE_FROM_CACHE | |
1310 (mirrortab, BUF_FETCH_CHAR (buf, from - 1)); | |
1311 | |
1312 if (SYNTAX_CODES_END_P (prev_syncode, syncode)) | |
1313 { | |
1035 /* we must record the comment style encountered so that | 1314 /* we must record the comment style encountered so that |
1036 later, we can match only the proper comment begin | 1315 later, we can match only the proper comment begin |
1037 sequence of the same style */ | 1316 sequence of the same style */ |
1038 code = Sendcomment; | 1317 code = Sendcomment; |
1039 mask = SYNTAX_COMMENT_MASK_END (mirrortab, | 1318 comstyle = SYNTAX_CODES_COMMENT_MASK_END |
1040 BUF_FETCH_CHAR (buf, from - 1), | 1319 (prev_syncode, syncode) == SYNTAX_COMMENT_STYLE_A ? 0 : 1; |
1041 c); | |
1042 from--; | 1320 from--; |
1043 } | 1321 } |
1044 | 1322 } |
1045 if (SYNTAX_PREFIX_UNSAFE (mirrortab, c)) | 1323 |
1324 if (SYNTAX_CODE_PREFIX (syncode)) | |
1046 continue; | 1325 continue; |
1047 | 1326 |
1048 switch (quoted ? Sword : code) | 1327 switch (quoted ? Sword : code) |
1049 { | 1328 { |
1050 case Sword: | 1329 case Sword: |
1052 if (depth || !sexpflag) break; | 1331 if (depth || !sexpflag) break; |
1053 /* This word counts as a sexp; count object finished after | 1332 /* This word counts as a sexp; count object finished after |
1054 passing it. */ | 1333 passing it. */ |
1055 while (from > stop) | 1334 while (from > stop) |
1056 { | 1335 { |
1057 enum syntaxcode syncode; | 1336 UPDATE_SYNTAX_CACHE_BACKWARD (from); |
1058 quoted = char_quoted (buf, from - 1); | 1337 quoted = char_quoted (buf, from - 1); |
1059 | 1338 |
1060 if (quoted) | 1339 if (quoted) |
1061 from--; | 1340 from--; |
1062 if (! (quoted | 1341 if (! (quoted |
1063 || (syncode = | 1342 || (syncode = |
1064 SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from - 1))) | 1343 SYNTAX_FROM_CACHE (mirrortab, |
1344 BUF_FETCH_CHAR (buf, from - 1))) | |
1065 == Sword | 1345 == Sword |
1066 || syncode == Ssymbol | 1346 || syncode == Ssymbol |
1067 || syncode == Squote)) | 1347 || syncode == Squote)) |
1068 goto done2; | 1348 goto done2; |
1069 from--; | 1349 from--; |
1095 return Qnil; | 1375 return Qnil; |
1096 error ("Containing expression ends prematurely"); | 1376 error ("Containing expression ends prematurely"); |
1097 } | 1377 } |
1098 break; | 1378 break; |
1099 | 1379 |
1380 case Scomment_fence: | |
1381 comstyle = ST_COMMENT_STYLE; | |
1100 case Sendcomment: | 1382 case Sendcomment: |
1101 if (parse_sexp_ignore_comments) | 1383 if (parse_sexp_ignore_comments) |
1102 from = find_start_of_comment (buf, from, stop, mask); | 1384 from = find_start_of_comment (buf, from, stop, comstyle); |
1103 break; | 1385 break; |
1104 | 1386 |
1387 case Sstring_fence: | |
1105 case Sstring: | 1388 case Sstring: |
1106 { | 1389 { |
1390 Emchar stringterm; | |
1391 | |
1392 if (code != Sstring_fence) | |
1393 { | |
1107 /* XEmacs change: call syntax_match() on character */ | 1394 /* XEmacs change: call syntax_match() on character */ |
1108 Emchar ch = BUF_FETCH_CHAR (buf, from); | 1395 Emchar ch = BUF_FETCH_CHAR (buf, from); |
1109 Lisp_Object stermobj = syntax_match (syntaxtab, ch); | 1396 Lisp_Object stermobj = |
1110 Emchar stringterm; | 1397 syntax_match (syntax_cache.current_syntax_table, ch); |
1111 | 1398 |
1112 if (CHARP (stermobj)) | 1399 if (CHARP (stermobj)) |
1113 stringterm = XCHAR (stermobj); | 1400 stringterm = XCHAR (stermobj); |
1114 else | 1401 else |
1115 stringterm = ch; | 1402 stringterm = ch; |
1403 } | |
1404 else | |
1405 stringterm = '\0'; /* avoid compiler warnings */ | |
1116 | 1406 |
1117 while (1) | 1407 while (1) |
1118 { | 1408 { |
1119 if (from == stop) goto lose; | 1409 if (from == stop) goto lose; |
1120 if (!char_quoted (buf, from - 1) | 1410 |
1121 && stringterm == BUF_FETCH_CHAR (buf, from - 1)) | 1411 UPDATE_SYNTAX_CACHE_BACKWARD (from - 1); |
1412 c = BUF_FETCH_CHAR (buf, from - 1); | |
1413 | |
1414 if ((code == Sstring | |
1415 ? c == stringterm | |
1416 : SYNTAX_FROM_CACHE (mirrortab, c) == Sstring_fence) | |
1417 && !char_quoted (buf, from - 1)) | |
1418 { | |
1122 break; | 1419 break; |
1420 } | |
1421 | |
1123 from--; | 1422 from--; |
1124 } | 1423 } |
1125 from--; | 1424 from--; |
1126 if (!depth && sexpflag) goto done2; | 1425 if (!depth && sexpflag) goto done2; |
1127 break; | 1426 break; |
1152 char_quoted (struct buffer *buf, Bufpos pos) | 1451 char_quoted (struct buffer *buf, Bufpos pos) |
1153 { | 1452 { |
1154 enum syntaxcode code; | 1453 enum syntaxcode code; |
1155 Bufpos beg = BUF_BEGV (buf); | 1454 Bufpos beg = BUF_BEGV (buf); |
1156 int quoted = 0; | 1455 int quoted = 0; |
1157 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | 1456 Bufpos startpos = pos; |
1158 | 1457 |
1159 while (pos > beg | 1458 while (pos > beg) |
1160 && ((code = SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1))) | 1459 { |
1161 == Scharquote | 1460 UPDATE_SYNTAX_CACHE_BACKWARD (pos - 1); |
1162 || code == Sescape)) | 1461 code = SYNTAX_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, pos - 1)); |
1163 pos--, quoted = !quoted; | 1462 |
1463 if (code != Scharquote && code != Sescape) | |
1464 break; | |
1465 pos--; | |
1466 quoted = !quoted; | |
1467 } | |
1468 | |
1469 UPDATE_SYNTAX_CACHE (startpos); | |
1164 return quoted; | 1470 return quoted; |
1165 } | 1471 } |
1166 | 1472 |
1167 DEFUN ("scan-lists", Fscan_lists, 3, 5, 0, /* | 1473 DEFUN ("scan-lists", Fscan_lists, 3, 5, 0, /* |
1168 Scan from character number FROM by COUNT lists. | 1474 Scan from character number FROM by COUNT lists. |
1234 (buffer)) | 1540 (buffer)) |
1235 { | 1541 { |
1236 struct buffer *buf = decode_buffer (buffer, 0); | 1542 struct buffer *buf = decode_buffer (buffer, 0); |
1237 Bufpos beg = BUF_BEGV (buf); | 1543 Bufpos beg = BUF_BEGV (buf); |
1238 Bufpos pos = BUF_PT (buf); | 1544 Bufpos pos = BUF_PT (buf); |
1545 #ifndef emacs | |
1239 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | 1546 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); |
1547 #endif | |
1548 Emchar c = '\0'; /* initialize to avoid compiler warnings */ | |
1549 | |
1550 | |
1551 SETUP_SYNTAX_CACHE_FOR_BUFFER (buf, pos, -1); | |
1240 | 1552 |
1241 while (pos > beg && !char_quoted (buf, pos - 1) | 1553 while (pos > beg && !char_quoted (buf, pos - 1) |
1242 && (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1)) == Squote | 1554 /* Previous statement updates syntax table. */ |
1243 || SYNTAX_PREFIX (mirrortab, BUF_FETCH_CHAR (buf, pos - 1)))) | 1555 && (SYNTAX_FROM_CACHE (mirrortab, c = BUF_FETCH_CHAR (buf, pos - 1)) == Squote |
1556 || SYNTAX_CODE_PREFIX (SYNTAX_CODE_FROM_CACHE (mirrortab, c)))) | |
1244 pos--; | 1557 pos--; |
1245 | 1558 |
1246 BUF_SET_PT (buf, pos); | 1559 BUF_SET_PT (buf, pos); |
1247 | 1560 |
1248 return Qnil; | 1561 return Qnil; |
1271 int depth; /* Paren depth of current scanning location. | 1584 int depth; /* Paren depth of current scanning location. |
1272 level - levelstart equals this except | 1585 level - levelstart equals this except |
1273 when the depth becomes negative. */ | 1586 when the depth becomes negative. */ |
1274 int mindepth; /* Lowest DEPTH value seen. */ | 1587 int mindepth; /* Lowest DEPTH value seen. */ |
1275 int start_quoted = 0; /* Nonzero means starting after a char quote */ | 1588 int start_quoted = 0; /* Nonzero means starting after a char quote */ |
1589 int boundary_stop = commentstop == -1; | |
1276 Lisp_Object tem; | 1590 Lisp_Object tem; |
1277 int mask; /* comment mask */ | 1591 |
1278 Lisp_Object syntaxtab = buf->syntax_table; | 1592 SETUP_SYNTAX_CACHE (from, 1); |
1279 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | |
1280 | |
1281 if (NILP (oldstate)) | 1593 if (NILP (oldstate)) |
1282 { | 1594 { |
1283 depth = 0; | 1595 depth = 0; |
1284 state.instring = -1; | 1596 state.instring = -1; |
1285 state.incomment = 0; | 1597 state.incomment = 0; |
1286 state.comstyle = 0; /* comment style a by default */ | 1598 state.comstyle = 0; /* comment style a by default */ |
1287 mask = SYNTAX_COMMENT_STYLE_A; | 1599 state.comstr_start = -1; /* no comment/string seen. */ |
1288 } | 1600 } |
1289 else | 1601 else |
1290 { | 1602 { |
1291 tem = Fcar (oldstate); /* elt 0, depth */ | 1603 tem = Fcar (oldstate); /* elt 0, depth */ |
1292 if (!NILP (tem)) | 1604 if (!NILP (tem)) |
1296 | 1608 |
1297 oldstate = Fcdr (oldstate); | 1609 oldstate = Fcdr (oldstate); |
1298 oldstate = Fcdr (oldstate); | 1610 oldstate = Fcdr (oldstate); |
1299 oldstate = Fcdr (oldstate); | 1611 oldstate = Fcdr (oldstate); |
1300 tem = Fcar (oldstate); /* elt 3, instring */ | 1612 tem = Fcar (oldstate); /* elt 3, instring */ |
1301 state.instring = !NILP (tem) ? XINT (tem) : -1; | 1613 state.instring = ( !NILP (tem) |
1302 | 1614 ? ( INTP (tem) ? XINT (tem) : ST_STRING_STYLE) |
1303 oldstate = Fcdr (oldstate); /* elt 4, incomment */ | 1615 : -1); |
1304 tem = Fcar (oldstate); | 1616 |
1617 oldstate = Fcdr (oldstate); | |
1618 tem = Fcar (oldstate); /* elt 4, incomment */ | |
1305 state.incomment = !NILP (tem); | 1619 state.incomment = !NILP (tem); |
1306 | 1620 |
1307 oldstate = Fcdr (oldstate); | 1621 oldstate = Fcdr (oldstate); |
1308 tem = Fcar (oldstate); /* elt 5, follows-quote */ | 1622 tem = Fcar (oldstate); /* elt 5, follows-quote */ |
1309 start_quoted = !NILP (tem); | 1623 start_quoted = !NILP (tem); |
1310 | 1624 |
1311 /* if the eighth element of the list is nil, we are in comment style | 1625 /* if the eighth element of the list is nil, we are in comment style |
1312 a. if it is non-nil, we are in comment style b */ | 1626 a; if it is t, we are in comment style b; if it is 'syntax-table, |
1627 we are in a generic comment */ | |
1313 oldstate = Fcdr (oldstate); | 1628 oldstate = Fcdr (oldstate); |
1314 oldstate = Fcdr (oldstate); | 1629 oldstate = Fcdr (oldstate); |
1630 tem = Fcar (oldstate); /* elt 7, comment style a/b/fence */ | |
1631 state.comstyle = NILP (tem) ? 0 : ( EQ (tem, Qsyntax_table) | |
1632 ? ST_COMMENT_STYLE : 1 ); | |
1633 | |
1634 oldstate = Fcdr (oldstate); /* elt 8, start of last comment/string */ | |
1635 tem = Fcar (oldstate); | |
1636 state.comstr_start = NILP (tem) ? -1 : XINT (tem); | |
1637 | |
1638 /* elt 9, char numbers of starts-of-expression of levels | |
1639 (starting from outermost). */ | |
1315 oldstate = Fcdr (oldstate); | 1640 oldstate = Fcdr (oldstate); |
1316 tem = Fcar (oldstate); /* elt 8, comment style a */ | 1641 tem = Fcar (oldstate); /* elt 9, intermediate data for |
1317 state.comstyle = !NILP (tem); | 1642 continuation of parsing (subject |
1318 mask = state.comstyle ? SYNTAX_COMMENT_STYLE_B : SYNTAX_COMMENT_STYLE_A; | 1643 to change). */ |
1644 while (!NILP (tem)) /* >= second enclosing sexps. */ | |
1645 { | |
1646 curlevel->last = XINT (Fcar (tem)); | |
1647 if (++curlevel == endlevel) | |
1648 error ("Nesting too deep for parser"); | |
1649 curlevel->prev = -1; | |
1650 curlevel->last = -1; | |
1651 tem = Fcdr (tem); | |
1652 } | |
1319 } | 1653 } |
1320 state.quoted = 0; | 1654 state.quoted = 0; |
1321 mindepth = depth; | 1655 mindepth = depth; |
1322 | 1656 |
1323 curlevel->prev = -1; | 1657 curlevel->prev = -1; |
1333 } | 1667 } |
1334 if (start_quoted) goto startquoted; | 1668 if (start_quoted) goto startquoted; |
1335 | 1669 |
1336 while (from < end) | 1670 while (from < end) |
1337 { | 1671 { |
1672 Emchar c; | |
1673 int syncode; | |
1674 | |
1338 QUIT; | 1675 QUIT; |
1339 | 1676 |
1340 code = SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from)); | 1677 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1678 c = BUF_FETCH_CHAR (buf, from); | |
1679 code = SYNTAX_FROM_CACHE (mirrortab, c); | |
1680 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
1341 from++; | 1681 from++; |
1342 | 1682 |
1343 if (code == Scomment) | |
1344 { | |
1345 /* record the comment style we have entered so that only the | 1683 /* record the comment style we have entered so that only the |
1346 comment-ender sequence (or single char) of the same style | 1684 comment-ender sequence (or single char) of the same style |
1347 actually terminates the comment section. */ | 1685 actually terminates the comment section. */ |
1348 mask = SYNTAX_COMMENT_1CHAR_MASK (mirrortab, | 1686 if (code == Scomment) |
1349 BUF_FETCH_CHAR (buf, from-1)); | 1687 { |
1350 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B); | 1688 state.comstyle = |
1351 state.comstart = from - 1; | 1689 SYNTAX_CODE_COMMENT_1CHAR_MASK (syncode) |
1690 == SYNTAX_COMMENT_STYLE_A ? 0 : 1; | |
1691 state.comstr_start = from - 1; | |
1692 } | |
1693 | |
1694 /* a generic comment delimiter? */ | |
1695 else if (code == Scomment_fence) | |
1696 { | |
1697 state.comstyle = ST_COMMENT_STYLE; | |
1698 state.comstr_start = from - 1; | |
1699 code = Scomment; | |
1352 } | 1700 } |
1353 | 1701 |
1354 else if (from < end && | 1702 else if (from < end && |
1355 SYNTAX_START_P (mirrortab, BUF_FETCH_CHAR (buf, from-1), | 1703 SYNTAX_CODE_START_FIRST_P (syncode)) |
1356 BUF_FETCH_CHAR (buf, from))) | 1704 { |
1357 { | 1705 int next_syncode; |
1358 /* Record the comment style we have entered so that only | 1706 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1359 the comment-end sequence of the same style actually | 1707 next_syncode = |
1360 terminates the comment section. */ | 1708 SYNTAX_CODE_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from)); |
1709 | |
1710 if (SYNTAX_CODES_START_P (syncode, next_syncode)) | |
1711 { | |
1361 code = Scomment; | 1712 code = Scomment; |
1362 mask = SYNTAX_COMMENT_MASK_START (mirrortab, | 1713 state.comstyle = SYNTAX_CODES_COMMENT_MASK_START |
1363 BUF_FETCH_CHAR (buf, from-1), | 1714 (syncode, next_syncode) == SYNTAX_COMMENT_STYLE_A ? 0 : 1; |
1364 BUF_FETCH_CHAR (buf, from)); | 1715 state.comstr_start = from - 1; |
1365 state.comstyle = (mask == SYNTAX_COMMENT_STYLE_B); | |
1366 state.comstart = from-1; | |
1367 from++; | 1716 from++; |
1368 } | 1717 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1369 | 1718 } |
1370 if (SYNTAX_PREFIX (mirrortab, BUF_FETCH_CHAR (buf, from - 1))) | 1719 } |
1720 | |
1721 if (SYNTAX_CODE_PREFIX (syncode)) | |
1371 continue; | 1722 continue; |
1372 switch (code) | 1723 switch (code) |
1373 { | 1724 { |
1374 case Sescape: | 1725 case Sescape: |
1375 case Scharquote: | 1726 case Scharquote: |
1385 if (stopbefore) goto stop; /* this arg means stop at sexp start */ | 1736 if (stopbefore) goto stop; /* this arg means stop at sexp start */ |
1386 curlevel->last = from - 1; | 1737 curlevel->last = from - 1; |
1387 symstarted: | 1738 symstarted: |
1388 while (from < end) | 1739 while (from < end) |
1389 { | 1740 { |
1390 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from))) | 1741 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1742 switch (SYNTAX_FROM_CACHE (mirrortab, BUF_FETCH_CHAR (buf, from))) | |
1391 { | 1743 { |
1392 case Scharquote: | 1744 case Scharquote: |
1393 case Sescape: | 1745 case Sescape: |
1394 from++; | 1746 from++; |
1395 if (from == end) goto endquoted; | 1747 if (from == end) goto endquoted; |
1407 curlevel->prev = curlevel->last; | 1759 curlevel->prev = curlevel->last; |
1408 break; | 1760 break; |
1409 | 1761 |
1410 case Scomment: | 1762 case Scomment: |
1411 state.incomment = 1; | 1763 state.incomment = 1; |
1764 if (commentstop || boundary_stop) goto done; | |
1412 startincomment: | 1765 startincomment: |
1413 if (commentstop) | 1766 if (commentstop == 1) |
1414 goto done; | 1767 goto done; |
1768 UPDATE_SYNTAX_CACHE_FORWARD (from); | |
1415 { | 1769 { |
1416 Bufpos newfrom = find_end_of_comment (buf, from, end, mask); | 1770 Bufpos newfrom = find_end_of_comment (buf, from, end, state.comstyle); |
1417 if (newfrom < 0) | 1771 if (newfrom < 0) |
1418 { | 1772 { |
1419 /* we terminated search because from == end */ | 1773 /* we terminated search because from == end */ |
1420 from = end; | 1774 from = end; |
1421 goto done; | 1775 goto done; |
1422 } | 1776 } |
1423 from = newfrom; | 1777 from = newfrom; |
1424 } | 1778 } |
1425 state.incomment = 0; | 1779 state.incomment = 0; |
1426 state.comstyle = 0; /* reset the comment style */ | 1780 state.comstyle = 0; /* reset the comment style */ |
1427 mask = 0; | 1781 if (boundary_stop) goto done; |
1428 break; | 1782 break; |
1429 | 1783 |
1430 case Sopen: | 1784 case Sopen: |
1431 if (stopbefore) goto stop; /* this arg means stop at sexp start */ | 1785 if (stopbefore) goto stop; /* this arg means stop at sexp start */ |
1432 depth++; | 1786 depth++; |
1448 curlevel->prev = curlevel->last; | 1802 curlevel->prev = curlevel->last; |
1449 if (targetdepth == depth) goto done; | 1803 if (targetdepth == depth) goto done; |
1450 break; | 1804 break; |
1451 | 1805 |
1452 case Sstring: | 1806 case Sstring: |
1453 { | 1807 case Sstring_fence: |
1454 Emchar ch; | 1808 state.comstr_start = from - 1; |
1455 if (stopbefore) goto stop; /* this arg means stop at sexp start */ | 1809 if (stopbefore) goto stop; /* this arg means stop at sexp start */ |
1456 curlevel->last = from - 1; | 1810 curlevel->last = from - 1; |
1457 /* XEmacs change: call syntax_match() on character */ | 1811 if (code == Sstring_fence) |
1458 ch = BUF_FETCH_CHAR (buf, from - 1); | 1812 { |
1459 { | 1813 state.instring = ST_STRING_STYLE; |
1460 Lisp_Object stermobj = syntax_match (syntaxtab, ch); | 1814 } |
1815 else | |
1816 { | |
1817 /* XEmacs change: call syntax_match() on character */ | |
1818 Emchar ch = BUF_FETCH_CHAR (buf, from - 1); | |
1819 Lisp_Object stermobj = | |
1820 syntax_match (syntax_cache.current_syntax_table, ch); | |
1461 | 1821 |
1462 if (CHARP (stermobj)) | 1822 if (CHARP (stermobj)) |
1463 state.instring = XCHAR (stermobj); | 1823 state.instring = XCHAR (stermobj); |
1464 else | 1824 else |
1465 state.instring = ch; | 1825 state.instring = ch; |
1466 } | |
1467 } | 1826 } |
1827 if (boundary_stop) goto done; | |
1468 startinstring: | 1828 startinstring: |
1469 while (1) | 1829 while (1) |
1470 { | 1830 { |
1831 enum syntaxcode temp_code; | |
1832 | |
1471 if (from >= end) goto done; | 1833 if (from >= end) goto done; |
1472 if (BUF_FETCH_CHAR (buf, from) == state.instring) break; | 1834 |
1473 switch (SYNTAX (mirrortab, BUF_FETCH_CHAR (buf, from))) | 1835 UPDATE_SYNTAX_CACHE_FORWARD (from); |
1836 c = BUF_FETCH_CHAR (buf, from); | |
1837 temp_code = SYNTAX_FROM_CACHE (mirrortab, c); | |
1838 | |
1839 if ( | |
1840 state.instring != ST_STRING_STYLE && | |
1841 temp_code == Sstring && | |
1842 c == state.instring) break; | |
1843 | |
1844 switch (temp_code) | |
1474 { | 1845 { |
1846 case Sstring_fence: | |
1847 if (state.instring == ST_STRING_STYLE) | |
1848 goto string_end; | |
1849 break; | |
1475 case Scharquote: | 1850 case Scharquote: |
1476 case Sescape: | 1851 case Sescape: |
1477 { | 1852 { |
1478 from++; | 1853 from++; |
1479 startquotedinstring: | 1854 startquotedinstring: |
1483 default: | 1858 default: |
1484 break; | 1859 break; |
1485 } | 1860 } |
1486 from++; | 1861 from++; |
1487 } | 1862 } |
1863 string_end: | |
1488 state.instring = -1; | 1864 state.instring = -1; |
1489 curlevel->prev = curlevel->last; | 1865 curlevel->prev = curlevel->last; |
1490 from++; | 1866 from++; |
1867 if (boundary_stop) goto done; | |
1491 break; | 1868 break; |
1492 | 1869 |
1493 case Smath: | 1870 case Smath: |
1494 break; | 1871 break; |
1495 | 1872 |
1496 case Swhitespace: | 1873 case Swhitespace: |
1497 case Spunct: | 1874 case Spunct: |
1498 case Squote: | 1875 case Squote: |
1499 case Sendcomment: | 1876 case Sendcomment: |
1877 case Scomment_fence: | |
1500 case Sinherit: | 1878 case Sinherit: |
1501 case Smax: | 1879 case Smax: |
1502 break; | 1880 break; |
1503 } | 1881 } |
1504 } | 1882 } |
1515 state.mindepth = mindepth; | 1893 state.mindepth = mindepth; |
1516 state.thislevelstart = curlevel->prev; | 1894 state.thislevelstart = curlevel->prev; |
1517 state.prevlevelstart | 1895 state.prevlevelstart |
1518 = (curlevel == levelstart) ? -1 : (curlevel - 1)->last; | 1896 = (curlevel == levelstart) ? -1 : (curlevel - 1)->last; |
1519 state.location = from; | 1897 state.location = from; |
1898 state.levelstarts = Qnil; | |
1899 while (--curlevel >= levelstart) | |
1900 state.levelstarts = Fcons (make_int (curlevel->last), | |
1901 state.levelstarts); | |
1520 | 1902 |
1521 *stateptr = state; | 1903 *stateptr = state; |
1522 } | 1904 } |
1523 | 1905 |
1524 DEFUN ("parse-partial-sexp", Fparse_partial_sexp, 2, 7, 0, /* | 1906 DEFUN ("parse-partial-sexp", Fparse_partial_sexp, 2, 7, 0, /* |
1525 Parse Lisp syntax starting at FROM until TO; return status of parse at TO. | 1907 Parse Lisp syntax starting at FROM until TO; return status of parse at TO. |
1526 Parsing stops at TO or when certain criteria are met; | 1908 Parsing stops at TO or when certain criteria are met; |
1527 point is set to where parsing stops. | 1909 point is set to where parsing stops. |
1528 If fifth arg OLDSTATE is omitted or nil, | 1910 If fifth arg OLDSTATE is omitted or nil, |
1529 parsing assumes that FROM is the beginning of a function. | 1911 parsing assumes that FROM is the beginning of a function. |
1530 Value is a list of eight elements describing final state of parsing: | 1912 Value is a list of nine elements describing final state of parsing: |
1531 0. depth in parens. | 1913 0. depth in parens. |
1532 1. character address of start of innermost containing list; nil if none. | 1914 1. character address of start of innermost containing list; nil if none. |
1533 2. character address of start of last complete sexp terminated. | 1915 2. character address of start of last complete sexp terminated. |
1534 3. non-nil if inside a string. | 1916 3. non-nil if inside a string. |
1535 (It is the character that will terminate the string.) | 1917 (It is the character that will terminate the string, |
1918 or t if the string should be terminated by an explicit | |
1919 `syntax-table' property.) | |
1536 4. t if inside a comment. | 1920 4. t if inside a comment. |
1537 5. t if following a quote character. | 1921 5. t if following a quote character. |
1538 6. the minimum paren-depth encountered during this scan. | 1922 6. the minimum paren-depth encountered during this scan. |
1539 7. nil if in comment style a, or not in a comment; t if in comment style b | 1923 7. nil if in comment style a, or not in a comment; t if in comment style b; |
1924 `syntax-table' if given by an explicit `syntax-table' property. | |
1925 8. character address of start of last comment or string; nil if none. | |
1926 9. Intermediate data for continuation of parsing (subject to change). | |
1540 If third arg TARGETDEPTH is non-nil, parsing stops if the depth | 1927 If third arg TARGETDEPTH is non-nil, parsing stops if the depth |
1541 in parentheses becomes equal to TARGETDEPTH. | 1928 in parentheses becomes equal to TARGETDEPTH. |
1542 Fourth arg STOPBEFORE non-nil means stop when come to | 1929 Fourth arg STOPBEFORE non-nil means stop when come to |
1543 any character that starts a sexp. | 1930 any character that starts a sexp. |
1544 Fifth arg OLDSTATE is an eight-element list like what this function returns. | 1931 Fifth arg OLDSTATE is a nine-element list like what this function returns. |
1545 It is used to initialize the state of the parse. Its second and third | 1932 It is used to initialize the state of the parse. Its second and third |
1546 elements are ignored. | 1933 elements are ignored. |
1547 Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. | 1934 Sixth arg COMMENTSTOP non-nil means stop at the start of a comment. If it |
1935 is `syntax-table', stop after the start of a comment or a string, or after | |
1936 the end of a comment or string. | |
1548 */ | 1937 */ |
1549 (from, to, targetdepth, stopbefore, oldstate, commentstop, buffer)) | 1938 (from, to, targetdepth, stopbefore, oldstate, commentstop, buffer)) |
1550 { | 1939 { |
1551 struct lisp_parse_state state; | 1940 struct lisp_parse_state state; |
1552 int target; | 1941 int target; |
1563 target = -100000; /* We won't reach this depth */ | 1952 target = -100000; /* We won't reach this depth */ |
1564 | 1953 |
1565 get_buffer_range_char (buf, from, to, &start, &end, 0); | 1954 get_buffer_range_char (buf, from, to, &start, &end, 0); |
1566 scan_sexps_forward (buf, &state, start, end, | 1955 scan_sexps_forward (buf, &state, start, end, |
1567 target, !NILP (stopbefore), oldstate, | 1956 target, !NILP (stopbefore), oldstate, |
1568 !NILP (commentstop)); | 1957 (NILP (commentstop) |
1569 | 1958 ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1))); |
1570 BUF_SET_PT (buf, state.location); | 1959 BUF_SET_PT (buf, state.location); |
1571 | 1960 |
1572 /* reverse order */ | 1961 /* reverse order */ |
1573 val = Qnil; | 1962 val = Qnil; |
1574 val = Fcons (state.comstyle ? Qt : Qnil, val); | 1963 val = Fcons (state.levelstarts, val); |
1964 val = Fcons ((state.incomment || (state.instring >= 0)) | |
1965 ? make_int (state.comstr_start) : Qnil, val); | |
1966 val = Fcons (state.comstyle ? (state.comstyle == ST_COMMENT_STYLE | |
1967 ? Qsyntax_table : Qt) : Qnil, val); | |
1575 val = Fcons (make_int (state.mindepth), val); | 1968 val = Fcons (make_int (state.mindepth), val); |
1576 val = Fcons (state.quoted ? Qt : Qnil, val); | 1969 val = Fcons (state.quoted ? Qt : Qnil, val); |
1577 val = Fcons (state.incomment ? Qt : Qnil, val); | 1970 val = Fcons (state.incomment ? Qt : Qnil, val); |
1578 val = Fcons (state.instring < 0 ? Qnil : make_int (state.instring), val); | 1971 val = Fcons (state.instring < 0 |
1972 ? Qnil | |
1973 : (state.instring == ST_STRING_STYLE | |
1974 ? Qt : make_int (state.instring)), val); | |
1579 val = Fcons (state.thislevelstart < 0 ? Qnil : make_int (state.thislevelstart), val); | 1975 val = Fcons (state.thislevelstart < 0 ? Qnil : make_int (state.thislevelstart), val); |
1580 val = Fcons (state.prevlevelstart < 0 ? Qnil : make_int (state.prevlevelstart), val); | 1976 val = Fcons (state.prevlevelstart < 0 ? Qnil : make_int (state.prevlevelstart), val); |
1581 val = Fcons (make_int (state.depth), val); | 1977 val = Fcons (make_int (state.depth), val); |
1582 | 1978 |
1583 return val; | 1979 return val; |
1670 | 2066 |
1671 void | 2067 void |
1672 syms_of_syntax (void) | 2068 syms_of_syntax (void) |
1673 { | 2069 { |
1674 defsymbol (&Qsyntax_table_p, "syntax-table-p"); | 2070 defsymbol (&Qsyntax_table_p, "syntax-table-p"); |
2071 defsymbol (&Qsyntax_table, "syntax-table"); | |
1675 | 2072 |
1676 DEFSUBR (Fsyntax_table_p); | 2073 DEFSUBR (Fsyntax_table_p); |
1677 DEFSUBR (Fsyntax_table); | 2074 DEFSUBR (Fsyntax_table); |
1678 DEFSUBR (Fstandard_syntax_table); | 2075 DEFSUBR (Fstandard_syntax_table); |
1679 DEFSUBR (Fcopy_syntax_table); | 2076 DEFSUBR (Fcopy_syntax_table); |
1699 DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments /* | 2096 DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments /* |
1700 Non-nil means `forward-sexp', etc., should treat comments as whitespace. | 2097 Non-nil means `forward-sexp', etc., should treat comments as whitespace. |
1701 */ ); | 2098 */ ); |
1702 parse_sexp_ignore_comments = 0; | 2099 parse_sexp_ignore_comments = 0; |
1703 | 2100 |
2101 DEFVAR_BOOL ("lookup-syntax-properties", &lookup_syntax_properties /* | |
2102 Non-nil means `forward-sexp', etc., grant `syntax-table' property. | |
2103 The value of this property should be either a syntax table, or a cons | |
2104 of the form (SYNTAXCODE . MATCHCHAR), SYNTAXCODE being the numeric | |
2105 syntax code, MATCHCHAR being nil or the character to match (which is | |
2106 relevant only for open/close type. | |
2107 */ ); | |
2108 lookup_syntax_properties = 1; | |
2109 | |
1704 DEFVAR_BOOL ("words-include-escapes", &words_include_escapes /* | 2110 DEFVAR_BOOL ("words-include-escapes", &words_include_escapes /* |
1705 Non-nil means `forward-word', etc., should treat escape chars part of words. | 2111 Non-nil means `forward-word', etc., should treat escape chars part of words. |
1706 */ ); | 2112 */ ); |
1707 words_include_escapes = 0; | 2113 words_include_escapes = 0; |
1708 | 2114 |