Mercurial > hg > xemacs-beta
comparison src/font-lock.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 | abe6d1db359e |
children | 183866b06e0b |
comparison
equal
deleted
inserted
replaced
459:9d4fd877b885 | 460:223736d75acb |
---|---|
57 enum syntactic_context | 57 enum syntactic_context |
58 { | 58 { |
59 context_none, | 59 context_none, |
60 context_string, | 60 context_string, |
61 context_comment, | 61 context_comment, |
62 context_block_comment | 62 context_block_comment, |
63 context_generic_comment, | |
64 context_generic_string | |
63 }; | 65 }; |
64 | 66 |
65 enum block_comment_context | 67 enum block_comment_context |
66 { | 68 { |
67 ccontext_none, | 69 ccontext_none, |
331 context_cache.context = context_none; | 333 context_cache.context = context_none; |
332 context_cache.ccontext = ccontext_none; | 334 context_cache.ccontext = ccontext_none; |
333 context_cache.style = comment_style_none; | 335 context_cache.style = comment_style_none; |
334 context_cache.scontext = '\000'; | 336 context_cache.scontext = '\000'; |
335 context_cache.depth = 0; | 337 context_cache.depth = 0; |
338 /* #### shouldn't this be checking the character's syntax instead of | |
339 explicitly testing for backslash characters? */ | |
336 context_cache.backslash_p = ((pt > 1) && | 340 context_cache.backslash_p = ((pt > 1) && |
337 (BUF_FETCH_CHAR (buf, pt - 1) == '\\')); | 341 (BUF_FETCH_CHAR (buf, pt - 1) == '\\')); |
338 /* Note that the BOL context cache may not be at the beginning | 342 /* Note that the BOL context cache may not be at the beginning |
339 of the line, but that should be OK, nobody's checking. */ | 343 of the line, but that should be OK, nobody's checking. */ |
340 bol_context_cache = context_cache; | 344 bol_context_cache = context_cache; |
385 goto start_over; | 389 goto start_over; |
386 #endif | 390 #endif |
387 } | 391 } |
388 } | 392 } |
389 | 393 |
390 #define SYNTAX_START_STYLE(table, c1, c2) \ | 394 #define SYNTAX_START_STYLE(c1, c2) \ |
391 (SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \ | 395 (SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ? \ |
392 comment_style_a : \ | |
393 SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \ | |
394 comment_style_b : \ | |
395 comment_style_none) | |
396 | |
397 #define SYNTAX_END_STYLE(table, c1, c2) \ | |
398 (SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \ | |
399 comment_style_a : \ | 396 comment_style_a : \ |
400 SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \ | 397 SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ? \ |
401 comment_style_b : \ | 398 comment_style_b : \ |
402 comment_style_none) | 399 comment_style_none) |
403 | 400 |
404 #define SINGLE_SYNTAX_STYLE(table, c) \ | 401 #define SYNTAX_END_STYLE(c1, c2) \ |
405 (SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_A) ? \ | 402 (SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ? \ |
403 comment_style_a : \ | |
404 SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ? \ | |
405 comment_style_b : \ | |
406 comment_style_none) | |
407 | |
408 #define SINGLE_SYNTAX_STYLE(c) \ | |
409 (SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_A) ? \ | |
406 comment_style_a : \ | 410 comment_style_a : \ |
407 SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_B) ? \ | 411 SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_B) ? \ |
408 comment_style_b : \ | 412 comment_style_b : \ |
409 comment_style_none) | 413 comment_style_none) |
410 | 414 |
411 /* Set up context_cache for position PT in BUF. */ | 415 /* Set up context_cache for position PT in BUF. */ |
412 | 416 |
413 static void | 417 static void |
414 find_context (struct buffer *buf, Bufpos pt) | 418 find_context (struct buffer *buf, Bufpos pt) |
415 { | 419 { |
416 /* This function can GC */ | 420 /* This function can GC */ |
421 #ifndef emacs | |
417 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); | 422 Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table); |
418 Lisp_Object syntaxtab = buf->syntax_table; | 423 Lisp_Object syntaxtab = buf->syntax_table; |
424 #endif | |
419 Emchar prev_c, c; | 425 Emchar prev_c, c; |
426 int prev_syncode, syncode; | |
420 Bufpos target = pt; | 427 Bufpos target = pt; |
421 setup_context_cache (buf, pt); | 428 setup_context_cache (buf, pt); |
422 pt = context_cache.cur_point; | 429 pt = context_cache.cur_point; |
423 | 430 |
431 SETUP_SYNTAX_CACHE (pt - 1, 1); | |
424 if (pt > BUF_BEGV (buf)) | 432 if (pt > BUF_BEGV (buf)) |
425 c = BUF_FETCH_CHAR (buf, pt - 1); | 433 { |
434 c = BUF_FETCH_CHAR (buf, pt - 1); | |
435 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
436 } | |
426 else | 437 else |
427 c = '\n'; /* to get bol_context_cache at point-min */ | 438 { |
439 c = '\n'; /* to get bol_context_cache at point-min */ | |
440 syncode = Swhitespace; | |
441 } | |
428 | 442 |
429 for (; pt < target; pt++, context_cache.cur_point = pt) | 443 for (; pt < target; pt++, context_cache.cur_point = pt) |
430 { | 444 { |
431 if (context_cache.needs_its_head_reexamined) | 445 if (context_cache.needs_its_head_reexamined) |
432 { | 446 { |
457 context_cache.end_point = pt; | 471 context_cache.end_point = pt; |
458 bol_context_cache = context_cache; | 472 bol_context_cache = context_cache; |
459 } | 473 } |
460 } | 474 } |
461 | 475 |
476 UPDATE_SYNTAX_CACHE_FORWARD (pt); | |
462 prev_c = c; | 477 prev_c = c; |
478 prev_syncode = syncode; | |
463 c = BUF_FETCH_CHAR (buf, pt); | 479 c = BUF_FETCH_CHAR (buf, pt); |
480 syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c); | |
464 | 481 |
465 if (prev_c == '\n') | 482 if (prev_c == '\n') |
466 bol_context_cache = context_cache; | 483 bol_context_cache = context_cache; |
467 | 484 |
468 if (context_cache.backslash_p) | 485 if (context_cache.backslash_p) |
469 { | 486 { |
470 context_cache.backslash_p = 0; | 487 context_cache.backslash_p = 0; |
471 continue; | 488 continue; |
472 } | 489 } |
473 | 490 |
474 switch (SYNTAX (mirrortab, c)) | 491 switch (SYNTAX_FROM_CACHE (mirrortab, c)) |
475 { | 492 { |
476 case Sescape: | 493 case Sescape: |
477 context_cache.backslash_p = 1; | 494 context_cache.backslash_p = 1; |
478 break; | 495 break; |
479 | 496 |
490 case Scomment: | 507 case Scomment: |
491 if (context_cache.context == context_none) | 508 if (context_cache.context == context_none) |
492 { | 509 { |
493 context_cache.context = context_comment; | 510 context_cache.context = context_comment; |
494 context_cache.ccontext = ccontext_none; | 511 context_cache.ccontext = ccontext_none; |
495 context_cache.style = SINGLE_SYNTAX_STYLE (mirrortab, c); | 512 context_cache.style = SINGLE_SYNTAX_STYLE (syncode); |
496 if (context_cache.style == comment_style_none) abort (); | 513 if (context_cache.style == comment_style_none) abort (); |
497 } | 514 } |
498 break; | 515 break; |
499 | 516 |
500 case Sendcomment: | 517 case Sendcomment: |
501 if (context_cache.style != SINGLE_SYNTAX_STYLE (mirrortab, c)) | 518 if (context_cache.style != SINGLE_SYNTAX_STYLE (syncode)) |
502 ; | 519 ; |
503 else if (context_cache.context == context_comment) | 520 else if (context_cache.context == context_comment) |
504 { | 521 { |
505 context_cache.context = context_none; | 522 context_cache.context = context_none; |
506 context_cache.style = comment_style_none; | 523 context_cache.style = comment_style_none; |
523 context_cache.context = context_none; | 540 context_cache.context = context_none; |
524 context_cache.scontext = '\000'; | 541 context_cache.scontext = '\000'; |
525 } | 542 } |
526 else if (context_cache.context == context_none) | 543 else if (context_cache.context == context_none) |
527 { | 544 { |
528 Lisp_Object stringtermobj = syntax_match (syntaxtab, c); | 545 Lisp_Object stringtermobj = |
546 syntax_match (syntax_cache.current_syntax_table, c); | |
529 Emchar stringterm; | 547 Emchar stringterm; |
530 | 548 |
531 if (CHARP (stringtermobj)) | 549 if (CHARP (stringtermobj)) |
532 stringterm = XCHAR (stringtermobj); | 550 stringterm = XCHAR (stringtermobj); |
533 else | 551 else |
536 context_cache.scontext = stringterm; | 554 context_cache.scontext = stringterm; |
537 context_cache.ccontext = ccontext_none; | 555 context_cache.ccontext = ccontext_none; |
538 } | 556 } |
539 break; | 557 break; |
540 } | 558 } |
559 | |
560 case Scomment_fence: | |
561 { | |
562 if (context_cache.context == context_generic_comment) | |
563 { | |
564 context_cache.context = context_none; | |
565 } | |
566 else if (context_cache.context == context_none) | |
567 { | |
568 context_cache.context = context_generic_comment; | |
569 context_cache.ccontext = ccontext_none; | |
570 } | |
571 break; | |
572 } | |
573 | |
574 case Sstring_fence: | |
575 { | |
576 if (context_cache.context == context_generic_string) | |
577 { | |
578 context_cache.context = context_none; | |
579 } | |
580 else if (context_cache.context == context_none) | |
581 { | |
582 context_cache.context = context_generic_string; | |
583 context_cache.ccontext = ccontext_none; | |
584 } | |
585 break; | |
586 } | |
587 | |
541 default: | 588 default: |
542 ; | 589 ; |
543 } | 590 } |
544 | 591 |
545 /* That takes care of the characters with manifest syntax. | 592 /* That takes care of the characters with manifest syntax. |
546 Now we've got to hack multi-char sequences that start | 593 Now we've got to hack multi-char sequences that start |
547 and end block comments. | 594 and end block comments. |
548 */ | 595 */ |
549 if ((SYNTAX_COMMENT_BITS (mirrortab, c) & | 596 if ((SYNTAX_CODE_COMMENT_BITS (syncode) & |
550 SYNTAX_SECOND_CHAR_START) && | 597 SYNTAX_SECOND_CHAR_START) && |
551 context_cache.context == context_none && | 598 context_cache.context == context_none && |
552 context_cache.ccontext == ccontext_start1 && | 599 context_cache.ccontext == ccontext_start1 && |
553 SYNTAX_START_P (mirrortab, prev_c, c) /* the two chars match */ | 600 SYNTAX_CODES_START_P (prev_syncode, syncode) /* the two chars match */ |
554 ) | 601 ) |
555 { | 602 { |
556 context_cache.ccontext = ccontext_start2; | 603 context_cache.ccontext = ccontext_start2; |
557 context_cache.style = SYNTAX_START_STYLE (mirrortab, prev_c, c); | 604 context_cache.style = SYNTAX_START_STYLE (prev_syncode, syncode); |
558 if (context_cache.style == comment_style_none) abort (); | 605 if (context_cache.style == comment_style_none) abort (); |
559 } | 606 } |
560 else if ((SYNTAX_COMMENT_BITS (mirrortab, c) & | 607 else if ((SYNTAX_CODE_COMMENT_BITS (syncode) & |
561 SYNTAX_FIRST_CHAR_START) && | 608 SYNTAX_FIRST_CHAR_START) && |
562 context_cache.context == context_none && | 609 context_cache.context == context_none && |
563 (context_cache.ccontext == ccontext_none || | 610 (context_cache.ccontext == ccontext_none || |
564 context_cache.ccontext == ccontext_start1)) | 611 context_cache.ccontext == ccontext_start1)) |
565 { | 612 { |
566 context_cache.ccontext = ccontext_start1; | 613 context_cache.ccontext = ccontext_start1; |
567 context_cache.style = comment_style_none; /* should be this already*/ | 614 context_cache.style = comment_style_none; /* should be this already*/ |
568 } | 615 } |
569 else if ((SYNTAX_COMMENT_BITS (mirrortab, c) & | 616 else if ((SYNTAX_CODE_COMMENT_BITS (syncode) & |
570 SYNTAX_SECOND_CHAR_END) && | 617 SYNTAX_SECOND_CHAR_END) && |
571 context_cache.context == context_block_comment && | 618 context_cache.context == context_block_comment && |
572 context_cache.ccontext == ccontext_end1 && | 619 context_cache.ccontext == ccontext_end1 && |
573 SYNTAX_END_P (mirrortab, prev_c, c) && | 620 SYNTAX_CODES_END_P (prev_syncode, syncode) && |
574 /* the two chars match */ | 621 /* the two chars match */ |
575 context_cache.style == | 622 context_cache.style == |
576 SYNTAX_END_STYLE (mirrortab, prev_c, c) | 623 SYNTAX_END_STYLE (prev_syncode, syncode) |
577 ) | 624 ) |
578 { | 625 { |
579 context_cache.context = context_none; | 626 context_cache.context = context_none; |
580 context_cache.ccontext = ccontext_none; | 627 context_cache.ccontext = ccontext_none; |
581 context_cache.style = comment_style_none; | 628 context_cache.style = comment_style_none; |
582 } | 629 } |
583 else if ((SYNTAX_COMMENT_BITS (mirrortab, c) & | 630 else if ((SYNTAX_CODE_COMMENT_BITS (syncode) & |
584 SYNTAX_FIRST_CHAR_END) && | 631 SYNTAX_FIRST_CHAR_END) && |
585 context_cache.context == context_block_comment && | 632 context_cache.context == context_block_comment && |
586 (context_cache.style == | 633 context_cache.style == SINGLE_SYNTAX_STYLE (syncode) && |
587 SYNTAX_END_STYLE (mirrortab, c, | |
588 BUF_FETCH_CHAR (buf, pt+1))) && | |
589 (context_cache.ccontext == ccontext_start2 || | 634 (context_cache.ccontext == ccontext_start2 || |
590 context_cache.ccontext == ccontext_end1)) | 635 context_cache.ccontext == ccontext_end1)) |
591 /* #### is it right to check for end1 here?? */ | 636 /* #### is it right to check for end1 here?? |
637 yes, because this might be a repetition of the first char | |
638 of a comment-end sequence. ie, '/xxx foo xxx/' or | |
639 '/xxx foo x/', where 'x' = '*' -- mct */ | |
592 { | 640 { |
593 if (context_cache.style == comment_style_none) abort (); | 641 if (context_cache.style == comment_style_none) abort (); |
594 context_cache.ccontext = ccontext_end1; | 642 context_cache.ccontext = ccontext_end1; |
595 } | 643 } |
596 | 644 |
625 static Lisp_Object | 673 static Lisp_Object |
626 context_to_symbol (enum syntactic_context context) | 674 context_to_symbol (enum syntactic_context context) |
627 { | 675 { |
628 switch (context) | 676 switch (context) |
629 { | 677 { |
630 case context_none: return Qnil; | 678 case context_none: return Qnil; |
631 case context_string: return Qstring; | 679 case context_string: return Qstring; |
632 case context_comment: return Qcomment; | 680 case context_comment: return Qcomment; |
633 case context_block_comment: return Qblock_comment; | 681 case context_block_comment: return Qblock_comment; |
682 case context_generic_comment: return Qblock_comment; | |
683 case context_generic_string: return Qstring; | |
634 default: abort (); return Qnil; /* suppress compiler warning */ | 684 default: abort (); return Qnil; /* suppress compiler warning */ |
635 } | 685 } |
636 } | 686 } |
637 | 687 |
638 DEFUN ("buffer-syntactic-context", Fbuffer_syntactic_context, 0, 1, 0, /* | 688 DEFUN ("buffer-syntactic-context", Fbuffer_syntactic_context, 0, 1, 0, /* |
719 the comment. | 769 the comment. |
720 */ | 770 */ |
721 if (this_context == context_block_comment && | 771 if (this_context == context_block_comment && |
722 context_cache.ccontext == ccontext_start2) | 772 context_cache.ccontext == ccontext_start2) |
723 estart -= 2; | 773 estart -= 2; |
724 else if (this_context == context_comment) | 774 else if (this_context == context_comment |
775 || this_context == context_generic_comment | |
776 ) | |
725 estart -= 1; | 777 estart -= 1; |
726 | 778 |
727 edepth = context_cache.depth; | 779 edepth = context_cache.depth; |
728 while (context_cache.context == this_context && pt < e) | 780 while (context_cache.context == this_context && pt < e) |
729 { | 781 { |
735 | 787 |
736 /* Minor kludge: consider the character which terminated the comment | 788 /* Minor kludge: consider the character which terminated the comment |
737 a part of the comment. | 789 a part of the comment. |
738 */ | 790 */ |
739 if ((this_context == context_block_comment || | 791 if ((this_context == context_block_comment || |
740 this_context == context_comment) | 792 this_context == context_comment |
793 || this_context == context_generic_comment | |
794 ) | |
741 && pt < e) | 795 && pt < e) |
742 eend++; | 796 eend++; |
743 | 797 |
744 if (estart == eend) | 798 if (estart == eend) |
745 continue; | 799 continue; |