aboutsummaryrefslogtreecommitdiffstats
path: root/src/syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax.c')
-rw-r--r--src/syntax.c141
1 files changed, 104 insertions, 37 deletions
diff --git a/src/syntax.c b/src/syntax.c
index dc82210e79d..cacdf18c2a2 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -181,6 +181,7 @@ static void scan_sexps_forward (struct lisp_parse_state *,
181 ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT, 181 ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT,
182 bool, Lisp_Object, int); 182 bool, Lisp_Object, int);
183static bool in_classes (int, Lisp_Object); 183static bool in_classes (int, Lisp_Object);
184static void parse_sexp_propertize (ptrdiff_t charpos);
184 185
185/* This setter is used only in this file, so it can be private. */ 186/* This setter is used only in this file, so it can be private. */
186static void 187static void
@@ -246,8 +247,15 @@ SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
246 gl_state.object = Qnil; 247 gl_state.object = Qnil;
247 gl_state.offset = 0; 248 gl_state.offset = 0;
248 if (parse_sexp_lookup_properties) 249 if (parse_sexp_lookup_properties)
249 if (count > 0 || from > BEGV) 250 {
250 update_syntax_table (count > 0 ? from : from - 1, count, 1, Qnil); 251 if (count > 0)
252 update_syntax_table_forward (from, true, Qnil);
253 else if (from > BEGV)
254 {
255 update_syntax_table (from - 1, count, true, Qnil);
256 parse_sexp_propertize (from - 1);
257 }
258 }
251} 259}
252 260
253/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer. 261/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
@@ -313,7 +321,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
313{ 321{
314 Lisp_Object tmp_table; 322 Lisp_Object tmp_table;
315 int cnt = 0; 323 int cnt = 0;
316 bool invalidate = 1; 324 bool invalidate = true;
317 INTERVAL i; 325 INTERVAL i;
318 326
319 if (init) 327 if (init)
@@ -323,7 +331,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
323 gl_state.stop = gl_state.e_property; 331 gl_state.stop = gl_state.e_property;
324 i = interval_of (charpos, object); 332 i = interval_of (charpos, object);
325 gl_state.backward_i = gl_state.forward_i = i; 333 gl_state.backward_i = gl_state.forward_i = i;
326 invalidate = 0; 334 invalidate = false;
327 if (!i) 335 if (!i)
328 return; 336 return;
329 /* interval_of updates only ->position of the return value, so 337 /* interval_of updates only ->position of the return value, so
@@ -359,7 +367,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
359 i = update_interval (i, charpos); 367 i = update_interval (i, charpos);
360 if (INTERVAL_LAST_POS (i) != gl_state.b_property) 368 if (INTERVAL_LAST_POS (i) != gl_state.b_property)
361 { 369 {
362 invalidate = 0; 370 invalidate = false;
363 gl_state.forward_i = i; 371 gl_state.forward_i = i;
364 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; 372 gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset;
365 } 373 }
@@ -372,7 +380,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
372 i = update_interval (i, charpos); 380 i = update_interval (i, charpos);
373 if (i->position != gl_state.e_property) 381 if (i->position != gl_state.e_property)
374 { 382 {
375 invalidate = 0; 383 invalidate = false;
376 gl_state.backward_i = i; 384 gl_state.backward_i = i;
377 gl_state.b_property = i->position - gl_state.offset; 385 gl_state.b_property = i->position - gl_state.offset;
378 } 386 }
@@ -460,14 +468,69 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
460 } 468 }
461 eassert (i == NULL); /* This property goes to the end. */ 469 eassert (i == NULL); /* This property goes to the end. */
462 if (count > 0) 470 if (count > 0)
463 gl_state.e_property = gl_state.stop; 471 {
472 gl_state.e_property = gl_state.stop;
473 gl_state.forward_i = i;
474 }
464 else 475 else
465 gl_state.b_property = gl_state.start; 476 gl_state.b_property = gl_state.start;
466} 477}
478
479static void
480parse_sexp_propertize (ptrdiff_t charpos)
481{
482 EMACS_INT zv = ZV;
483 if (syntax_propertize__done <= charpos
484 && syntax_propertize__done < zv)
485 {
486 EMACS_INT modiffs = CHARS_MODIFF;
487 safe_call1 (Qinternal__syntax_propertize,
488 make_number (min (zv, 1 + charpos)));
489 if (modiffs != CHARS_MODIFF)
490 error ("parse-sexp-propertize-function modified the buffer!");
491 if (syntax_propertize__done <= charpos
492 && syntax_propertize__done < zv)
493 error ("parse-sexp-propertize-function did not move"
494 " syntax-propertize--done");
495 SETUP_SYNTAX_TABLE (charpos, 1);
496 }
497 else if (gl_state.e_property > syntax_propertize__done)
498 {
499 gl_state.e_property = syntax_propertize__done;
500 gl_state.e_property_truncated = true;
501 }
502 else if (gl_state.e_property_truncated
503 && gl_state.e_property < syntax_propertize__done)
504 { /* When moving backward, e_property might be set without resetting
505 e_property_truncated, so the e_property_truncated flag may
506 occasionally be left raised spuriously. This should be rare. */
507 gl_state.e_property_truncated = false;
508 update_syntax_table_forward (charpos, false, Qnil);
509 }
510}
511
512void
513update_syntax_table_forward (ptrdiff_t charpos, bool init,
514 Lisp_Object object)
515{
516 if (gl_state.e_property_truncated)
517 {
518 eassert (NILP (object));
519 eassert (charpos >= gl_state.e_property);
520 parse_sexp_propertize (charpos);
521 }
522 else
523 {
524 update_syntax_table (charpos, 1, init, object);
525 if (gl_state.e_property > syntax_propertize__done
526 && NILP (object))
527 parse_sexp_propertize (charpos);
528 }
529}
467 530
468/* Returns true if char at CHARPOS is quoted. 531/* Returns true if char at CHARPOS is quoted.
469 Global syntax-table data should be set up already to be good at CHARPOS 532 Global syntax-table data should be set up already to be good at CHARPOS
470 or after. On return global syntax data is good for lookup at CHARPOS. */ 533 or after. On return global syntax data is good for lookup at CHARPOS. */
471 534
472static bool 535static bool
473char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos) 536char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos)
@@ -628,7 +691,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
628 OFROM[I] is position of the earliest comment-starter seen 691 OFROM[I] is position of the earliest comment-starter seen
629 which is I+2X quotes from the comment-end. 692 which is I+2X quotes from the comment-end.
630 PARITY is current parity of quotes from the comment end. */ 693 PARITY is current parity of quotes from the comment end. */
631 int string_style = -1; /* Presumed outside of any string. */ 694 int string_style = -1; /* Presumed outside of any string. */
632 bool string_lossage = 0; 695 bool string_lossage = 0;
633 /* Not a real lossage: indicates that we have passed a matching comment 696 /* Not a real lossage: indicates that we have passed a matching comment
634 starter plus a non-matching comment-ender, meaning that any matching 697 starter plus a non-matching comment-ender, meaning that any matching
@@ -645,7 +708,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
645 ptrdiff_t defun_start = 0; 708 ptrdiff_t defun_start = 0;
646 ptrdiff_t defun_start_byte = 0; 709 ptrdiff_t defun_start_byte = 0;
647 enum syntaxcode code; 710 enum syntaxcode code;
648 ptrdiff_t nesting = 1; /* current comment nesting */ 711 ptrdiff_t nesting = 1; /* Current comment nesting. */
649 int c; 712 int c;
650 int syntax = 0; 713 int syntax = 0;
651 714
@@ -876,7 +939,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
876 is nested, so we need to try again from within the 939 is nested, so we need to try again from within the
877 surrounding comment. Example: { a (* " *) */ 940 surrounding comment. Example: { a (* " *) */
878 { 941 {
879 /* FIXME: We should advance by one or two chars. */ 942 /* FIXME: We should advance by one or two chars. */
880 defun_start = state.comstr_start + 2; 943 defun_start = state.comstr_start + 2;
881 defun_start_byte = CHAR_TO_BYTE (defun_start); 944 defun_start_byte = CHAR_TO_BYTE (defun_start);
882 } 945 }
@@ -1042,7 +1105,7 @@ DEFUN ("string-to-syntax", Fstring_to_syntax, Sstring_to_syntax, 1, 1, 0,
1042 doc: /* Convert a syntax descriptor STRING into a raw syntax descriptor. 1105 doc: /* Convert a syntax descriptor STRING into a raw syntax descriptor.
1043STRING should be a string of the form allowed as argument of 1106STRING should be a string of the form allowed as argument of
1044`modify-syntax-entry'. The return value is a raw syntax descriptor: a 1107`modify-syntax-entry'. The return value is a raw syntax descriptor: a
1045cons cell \(CODE . MATCHING-CHAR) which can be used, for example, as 1108cons cell (CODE . MATCHING-CHAR) which can be used, for example, as
1046the value of a `syntax-table' text property. */) 1109the value of a `syntax-table' text property. */)
1047 (Lisp_Object string) 1110 (Lisp_Object string)
1048{ 1111{
@@ -2288,13 +2351,13 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2288 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style 2351 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style
2289 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ? 2352 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ?
2290 (nesting > 0 && --nesting == 0) : nesting < 0)) 2353 (nesting > 0 && --nesting == 0) : nesting < 0))
2291 /* we have encountered a comment end of the same style 2354 /* We have encountered a comment end of the same style
2292 as the comment sequence which began this comment 2355 as the comment sequence which began this comment
2293 section */ 2356 section. */
2294 break; 2357 break;
2295 if (code == Scomment_fence 2358 if (code == Scomment_fence
2296 && style == ST_COMMENT_STYLE) 2359 && style == ST_COMMENT_STYLE)
2297 /* we have encountered a comment end of the same style 2360 /* We have encountered a comment end of the same style
2298 as the comment sequence which began this comment 2361 as the comment sequence which began this comment
2299 section. */ 2362 section. */
2300 break; 2363 break;
@@ -2302,8 +2365,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2302 && code == Scomment 2365 && code == Scomment
2303 && SYNTAX_FLAGS_COMMENT_NESTED (syntax) 2366 && SYNTAX_FLAGS_COMMENT_NESTED (syntax)
2304 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style) 2367 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style)
2305 /* we have encountered a nested comment of the same style 2368 /* We have encountered a nested comment of the same style
2306 as the comment sequence which began this comment section */ 2369 as the comment sequence which began this comment section. */
2307 nesting++; 2370 nesting++;
2308 INC_BOTH (from, from_byte); 2371 INC_BOTH (from, from_byte);
2309 UPDATE_SYNTAX_TABLE_FORWARD (from); 2372 UPDATE_SYNTAX_TABLE_FORWARD (from);
@@ -2319,9 +2382,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2319 ? nesting > 0 : nesting < 0)) 2382 ? nesting > 0 : nesting < 0))
2320 { 2383 {
2321 if (--nesting <= 0) 2384 if (--nesting <= 0)
2322 /* we have encountered a comment end of the same style 2385 /* We have encountered a comment end of the same style
2323 as the comment sequence which began this comment 2386 as the comment sequence which began this comment section. */
2324 section */
2325 break; 2387 break;
2326 else 2388 else
2327 { 2389 {
@@ -2338,9 +2400,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2338 && SYNTAX_FLAGS_COMSTART_SECOND (other_syntax)) 2400 && SYNTAX_FLAGS_COMSTART_SECOND (other_syntax))
2339 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) || 2401 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
2340 SYNTAX_FLAGS_COMMENT_NESTED (other_syntax))) 2402 SYNTAX_FLAGS_COMMENT_NESTED (other_syntax)))
2341 /* we have encountered a nested comment of the same style 2403 /* We have encountered a nested comment of the same style
2342 as the comment sequence which began this comment 2404 as the comment sequence which began this comment section. */
2343 section */
2344 { 2405 {
2345 INC_BOTH (from, from_byte); 2406 INC_BOTH (from, from_byte);
2346 UPDATE_SYNTAX_TABLE_FORWARD (from); 2407 UPDATE_SYNTAX_TABLE_FORWARD (from);
@@ -2584,9 +2645,9 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2584 bool quoted; 2645 bool quoted;
2585 bool mathexit = 0; 2646 bool mathexit = 0;
2586 enum syntaxcode code; 2647 enum syntaxcode code;
2587 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */ 2648 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */
2588 int comstyle = 0; /* style of comment encountered */ 2649 int comstyle = 0; /* Style of comment encountered. */
2589 bool comnested = 0; /* whether the comment is nestable or not */ 2650 bool comnested = 0; /* Whether the comment is nestable or not. */
2590 ptrdiff_t temp_pos; 2651 ptrdiff_t temp_pos;
2591 EMACS_INT last_good = from; 2652 EMACS_INT last_good = from;
2592 bool found; 2653 bool found;
@@ -2630,11 +2691,11 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2630 SYNTAX_FLAGS_COMSTART_SECOND (other_syntax)) 2691 SYNTAX_FLAGS_COMSTART_SECOND (other_syntax))
2631 && parse_sexp_ignore_comments) 2692 && parse_sexp_ignore_comments)
2632 { 2693 {
2633 /* we have encountered a comment start sequence and we 2694 /* We have encountered a comment start sequence and we
2634 are ignoring all text inside comments. We must record 2695 are ignoring all text inside comments. We must record
2635 the comment style this sequence begins so that later, 2696 the comment style this sequence begins so that later,
2636 only a comment end of the same style actually ends 2697 only a comment end of the same style actually ends
2637 the comment section */ 2698 the comment section. */
2638 code = Scomment; 2699 code = Scomment;
2639 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax); 2700 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
2640 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax); 2701 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
@@ -2652,7 +2713,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2652 if (from == stop) 2713 if (from == stop)
2653 goto lose; 2714 goto lose;
2654 INC_BOTH (from, from_byte); 2715 INC_BOTH (from, from_byte);
2655 /* treat following character as a word constituent */ 2716 /* Treat following character as a word constituent. */
2656 case Sword: 2717 case Sword:
2657 case Ssymbol: 2718 case Ssymbol:
2658 if (depth || !sexpflag) break; 2719 if (depth || !sexpflag) break;
@@ -2745,12 +2806,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2745 : c_code == Sstring_fence) 2806 : c_code == Sstring_fence)
2746 break; 2807 break;
2747 2808
2748 switch (c_code) 2809 if (c_code == Scharquote || c_code == Sescape)
2749 { 2810 INC_BOTH (from, from_byte);
2750 case Scharquote:
2751 case Sescape:
2752 INC_BOTH (from, from_byte);
2753 }
2754 INC_BOTH (from, from_byte); 2811 INC_BOTH (from, from_byte);
2755 } 2812 }
2756 INC_BOTH (from, from_byte); 2813 INC_BOTH (from, from_byte);
@@ -3365,11 +3422,16 @@ do { prev_from = from; \
3365 case Sstring_fence: 3422 case Sstring_fence:
3366 if (!nofence) goto string_end; 3423 if (!nofence) goto string_end;
3367 break; 3424 break;
3425
3368 case Scharquote: 3426 case Scharquote:
3369 case Sescape: 3427 case Sescape:
3370 INC_FROM; 3428 INC_FROM;
3371 startquotedinstring: 3429 startquotedinstring:
3372 if (from >= end) goto endquoted; 3430 if (from >= end) goto endquoted;
3431 break;
3432
3433 default:
3434 break;
3373 } 3435 }
3374 INC_FROM; 3436 INC_FROM;
3375 } 3437 }
@@ -3457,7 +3519,7 @@ Sixth arg COMMENTSTOP non-nil means stop at the start of a comment.
3457 target = XINT (targetdepth); 3519 target = XINT (targetdepth);
3458 } 3520 }
3459 else 3521 else
3460 target = TYPE_MINIMUM (EMACS_INT); /* We won't reach this depth */ 3522 target = TYPE_MINIMUM (EMACS_INT); /* We won't reach this depth. */
3461 3523
3462 validate_region (&from, &to); 3524 validate_region (&from, &to);
3463 scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)), 3525 scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)),
@@ -3588,7 +3650,7 @@ syms_of_syntax (void)
3588 staticpro (&gl_state.current_syntax_table); 3650 staticpro (&gl_state.current_syntax_table);
3589 staticpro (&gl_state.old_prop); 3651 staticpro (&gl_state.old_prop);
3590 3652
3591 /* Defined in regex.c */ 3653 /* Defined in regex.c. */
3592 staticpro (&re_match_object); 3654 staticpro (&re_match_object);
3593 3655
3594 DEFSYM (Qscan_error, "scan-error"); 3656 DEFSYM (Qscan_error, "scan-error");
@@ -3606,6 +3668,11 @@ Otherwise, that text property is simply ignored.
3606See the info node `(elisp)Syntax Properties' for a description of the 3668See the info node `(elisp)Syntax Properties' for a description of the
3607`syntax-table' property. */); 3669`syntax-table' property. */);
3608 3670
3671 DEFVAR_INT ("syntax-propertize--done", syntax_propertize__done,
3672 doc: /* Position up to which syntax-table properties have been set. */);
3673 syntax_propertize__done = -1;
3674 DEFSYM (Qinternal__syntax_propertize, "internal--syntax-propertize");
3675
3609 words_include_escapes = 0; 3676 words_include_escapes = 0;
3610 DEFVAR_BOOL ("words-include-escapes", words_include_escapes, 3677 DEFVAR_BOOL ("words-include-escapes", words_include_escapes,
3611 doc: /* Non-nil means `forward-word', etc., should treat escape chars part of words. */); 3678 doc: /* Non-nil means `forward-word', etc., should treat escape chars part of words. */);