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