(U+6215): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / src / font-lock.c
index cefa0d5..ddeeda9 100644 (file)
@@ -1,6 +1,7 @@
 /* Routines to compute the current syntactic context, for font-lock mode.
    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
    Copyright (C) 1995 Sun Microsystems, Inc.
+   Copyright (C) 2001 MORIOKA Tomohiko
 
 This file is part of XEmacs.
 
@@ -59,7 +60,9 @@ enum syntactic_context
   context_none,
   context_string,
   context_comment,
-  context_block_comment
+  context_block_comment,
+  context_generic_comment,
+  context_generic_string
 };
 
 enum block_comment_context
@@ -333,6 +336,8 @@ setup_context_cache (struct buffer *buf, Bufpos pt)
       context_cache.style = comment_style_none;
       context_cache.scontext = '\000';
       context_cache.depth = 0;
+      /* #### shouldn't this be checking the character's syntax instead of
+         explicitly testing for backslash characters? */
       context_cache.backslash_p = ((pt > 1) &&
                                   (BUF_FETCH_CHAR (buf, pt - 1) == '\\'));
       /* Note that the BOL context cache may not be at the beginning
@@ -368,8 +373,8 @@ setup_context_cache (struct buffer *buf, Bufpos pt)
       /* OK, fine. */
       return;
 #if 0
-    /* This appears to cause huge slowdowns in files like
-       emacsfns.h, which have no top-level forms.
+    /* This appears to cause huge slowdowns in files which have no
+       top-level forms.
 
        In any case, it's not really necessary that we know for
        sure the top-level form we're in; if we're in a form
@@ -387,26 +392,30 @@ setup_context_cache (struct buffer *buf, Bufpos pt)
   }
 }
 
-#define SYNTAX_START_STYLE(table, c1, c2)                               \
-  (SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
-   comment_style_a :                                                    \
-   SYNTAX_STYLES_MATCH_START_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
-   comment_style_b :                                                    \
-   comment_style_none)
-
-#define SYNTAX_END_STYLE(table, c1, c2)                                        \
-  (SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_A) ? \
+/* GCC 2.95.4 seems to need the casts */
+#define SYNTAX_START_STYLE(c1, c2)                                     \
+  ((enum comment_style)                                                 \
+   (SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ?      \
    comment_style_a :                                                   \
-   SYNTAX_STYLES_MATCH_END_P (table, c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
+   SYNTAX_CODES_MATCH_START_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ?       \
    comment_style_b :                                                   \
-   comment_style_none)
-
-#define SINGLE_SYNTAX_STYLE(table, c)                                  \
-      (SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_A) ?        \
-       comment_style_a :                                               \
-       SYNTAX_STYLES_MATCH_1CHAR_P (table, c, SYNTAX_COMMENT_STYLE_B) ?        \
-       comment_style_b :                                               \
-       comment_style_none)
+   comment_style_none))
+
+#define SYNTAX_END_STYLE(c1, c2)                               \
+  ((enum comment_style)                                         \
+   (SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_A) ?        \
+   comment_style_a :                                           \
+   SYNTAX_CODES_MATCH_END_P (c1, c2, SYNTAX_COMMENT_STYLE_B) ? \
+   comment_style_b :                                           \
+   comment_style_none))
+
+#define SINGLE_SYNTAX_STYLE(c)                                 \
+  ((enum comment_style)                                         \
+   (SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_A) ?  \
+   comment_style_a :                                           \
+   SYNTAX_CODE_MATCHES_1CHAR_P (c, SYNTAX_COMMENT_STYLE_B) ?   \
+   comment_style_b :                                           \
+   comment_style_none))
 
 /* Set up context_cache for position PT in BUF. */
 
@@ -414,18 +423,32 @@ static void
 find_context (struct buffer *buf, Bufpos pt)
 {
   /* This function can GC */
-  struct Lisp_Char_Table *mirrortab =
-    XCHAR_TABLE (buf->mirror_syntax_table);
+#ifndef emacs
+#ifdef UTF2000
+  Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->syntax_table);
+#else
+  Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
   Lisp_Object syntaxtab = buf->syntax_table;
+#endif
   Emchar prev_c, c;
+  int prev_syncode, syncode;
   Bufpos target = pt;
   setup_context_cache (buf, pt);
   pt = context_cache.cur_point;
 
+  SCS_STATISTICS_SET_FUNCTION (scs_find_context);
+  SETUP_SYNTAX_CACHE (pt - 1, 1);
   if (pt > BUF_BEGV (buf))
-    c = BUF_FETCH_CHAR (buf, pt - 1);
+    {
+      c = BUF_FETCH_CHAR (buf, pt - 1);
+      syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c);
+    }
   else
-    c = '\n'; /* to get bol_context_cache at point-min */
+    {
+      c = '\n'; /* to get bol_context_cache at point-min */
+      syncode = Swhitespace;
+    }
 
   for (; pt < target; pt++, context_cache.cur_point = pt)
     {
@@ -460,8 +483,11 @@ find_context (struct buffer *buf, Bufpos pt)
            }
        }
 
+      UPDATE_SYNTAX_CACHE_FORWARD (pt);
       prev_c = c;
+      prev_syncode = syncode;
       c = BUF_FETCH_CHAR (buf, pt);
+      syncode = SYNTAX_CODE_FROM_CACHE (mirrortab, c);
 
       if (prev_c == '\n')
        bol_context_cache = context_cache;
@@ -472,7 +498,7 @@ find_context (struct buffer *buf, Bufpos pt)
          continue;
        }
 
-      switch (SYNTAX (mirrortab, c))
+      switch (SYNTAX_FROM_CACHE (mirrortab, c))
        {
        case Sescape:
          context_cache.backslash_p = 1;
@@ -493,13 +519,13 @@ find_context (struct buffer *buf, Bufpos pt)
            {
              context_cache.context = context_comment;
              context_cache.ccontext = ccontext_none;
-             context_cache.style = SINGLE_SYNTAX_STYLE (mirrortab, c);
-             if (context_cache.style == comment_style_none) abort ();
+             context_cache.style = SINGLE_SYNTAX_STYLE (syncode);
+             if (context_cache.style == comment_style_none) ABORT ();
            }
          break;
 
        case Sendcomment:
-         if (context_cache.style != SINGLE_SYNTAX_STYLE (mirrortab, c))
+         if (context_cache.style != SINGLE_SYNTAX_STYLE (syncode))
            ;
          else if (context_cache.context == context_comment)
            {
@@ -526,7 +552,8 @@ find_context (struct buffer *buf, Bufpos pt)
              }
             else if (context_cache.context == context_none)
              {
-               Lisp_Object stringtermobj = syntax_match (syntaxtab, c);
+               Lisp_Object stringtermobj =
+                 syntax_match (syntax_cache.current_syntax_table, c);
                Emchar stringterm;
 
                if (CHARP (stringtermobj))
@@ -539,6 +566,35 @@ find_context (struct buffer *buf, Bufpos pt)
              }
             break;
           }
+
+       case Scomment_fence:
+         {
+           if (context_cache.context == context_generic_comment)
+             {
+               context_cache.context = context_none;
+             }
+           else if (context_cache.context == context_none)
+             {
+               context_cache.context = context_generic_comment;
+               context_cache.ccontext = ccontext_none;
+             }
+           break;
+         }
+
+       case Sstring_fence:
+         {
+           if (context_cache.context == context_generic_string)
+             {
+               context_cache.context = context_none;
+             }
+           else if (context_cache.context == context_none)
+             {
+               context_cache.context = context_generic_string;
+               context_cache.ccontext = ccontext_none;
+             }
+           break;
+         }
+
        default:
          ;
        }
@@ -547,18 +603,18 @@ find_context (struct buffer *buf, Bufpos pt)
         Now we've got to hack multi-char sequences that start
         and end block comments.
        */
-      if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+      if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
           SYNTAX_SECOND_CHAR_START) &&
          context_cache.context == context_none &&
          context_cache.ccontext == ccontext_start1 &&
-         SYNTAX_START_P (mirrortab, prev_c, c) /* the two chars match */
+         SYNTAX_CODES_START_P (prev_syncode, syncode) /* the two chars match */
          )
        {
          context_cache.ccontext = ccontext_start2;
-         context_cache.style = SYNTAX_START_STYLE (mirrortab, prev_c, c);
-         if (context_cache.style == comment_style_none) abort ();
+         context_cache.style = SYNTAX_START_STYLE (prev_syncode, syncode);
+         if (context_cache.style == comment_style_none) ABORT ();
        }
-      else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+      else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
                SYNTAX_FIRST_CHAR_START) &&
               context_cache.context == context_none &&
               (context_cache.ccontext == ccontext_none ||
@@ -567,42 +623,48 @@ find_context (struct buffer *buf, Bufpos pt)
          context_cache.ccontext = ccontext_start1;
          context_cache.style = comment_style_none; /* should be this already*/
        }
-      else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+      else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
                SYNTAX_SECOND_CHAR_END) &&
               context_cache.context == context_block_comment &&
               context_cache.ccontext == ccontext_end1 &&
-              SYNTAX_END_P (mirrortab, prev_c, c) &&
+              SYNTAX_CODES_END_P (prev_syncode, syncode) &&
               /* the two chars match */
               context_cache.style ==
-              SYNTAX_END_STYLE (mirrortab, prev_c, c)
+              SYNTAX_END_STYLE (prev_syncode, syncode)
               )
        {
          context_cache.context = context_none;
          context_cache.ccontext = ccontext_none;
          context_cache.style = comment_style_none;
        }
-      else if ((SYNTAX_COMMENT_BITS (mirrortab, c) &
+      else if ((SYNTAX_CODE_COMMENT_BITS (syncode) &
                SYNTAX_FIRST_CHAR_END) &&
               context_cache.context == context_block_comment &&
+#if 0
+              /* #### pre-Matt code had: */
               (context_cache.style ==
-               SYNTAX_END_STYLE (mirrortab, c,
-                                 BUF_FETCH_CHAR (buf, pt+1))) &&
+               SYNTAX_END_STYLE (c, BUF_FETCH_CHAR (buf, pt+1))) &&
+              /* why do these differ here?! */
+#endif
+              context_cache.style == SINGLE_SYNTAX_STYLE (syncode) &&
               (context_cache.ccontext == ccontext_start2 ||
                context_cache.ccontext == ccontext_end1))
-       /* #### is it right to check for end1 here?? */
+       /* check end1, to detect a repetition of the first char of a
+          comment-end sequence. ie, '/xxx foo xxx/' or '/xxx foo x/',
+          where 'x' = '*' -- mct */
        {
-         if (context_cache.style == comment_style_none) abort ();
+         if (context_cache.style == comment_style_none) ABORT ();
          context_cache.ccontext = ccontext_end1;
        }
 
       else if (context_cache.ccontext == ccontext_start1)
        {
-         if (context_cache.context != context_none) abort ();
+         if (context_cache.context != context_none) ABORT ();
          context_cache.ccontext = ccontext_none;
        }
       else if (context_cache.ccontext == ccontext_end1)
        {
-         if (context_cache.context != context_block_comment) abort ();
+         if (context_cache.context != context_block_comment) ABORT ();
          context_cache.context = context_none;
          context_cache.ccontext = ccontext_start2;
        }
@@ -611,7 +673,7 @@ find_context (struct buffer *buf, Bufpos pt)
          context_cache.context == context_none)
        {
          context_cache.context = context_block_comment;
-         if (context_cache.style == comment_style_none) abort ();
+         if (context_cache.style == comment_style_none) ABORT ();
        }
       else if (context_cache.ccontext == ccontext_none &&
               context_cache.context == context_block_comment)
@@ -628,11 +690,13 @@ context_to_symbol (enum syntactic_context context)
 {
   switch (context)
     {
-    case context_none:         return Qnil;
-    case context_string:       return Qstring;
-    case context_comment:      return Qcomment;
-    case context_block_comment:        return Qblock_comment;
-    default: abort (); return Qnil; /* suppress compiler warning */
+    case context_none:                 return Qnil;
+    case context_string:               return Qstring;
+    case context_comment:              return Qcomment;
+    case context_block_comment:                return Qblock_comment;
+    case context_generic_comment:      return Qblock_comment;
+    case context_generic_string:       return Qstring;
+    default: ABORT (); return Qnil; /* suppress compiler warning */
     }
 }
 
@@ -722,7 +786,9 @@ WARNING: this may alter match-data.
       if (this_context == context_block_comment &&
          context_cache.ccontext == ccontext_start2)
        estart -= 2;
-      else if (this_context == context_comment)
+      else if (this_context == context_comment
+              || this_context == context_generic_comment
+              )
        estart -= 1;
 
       edepth = context_cache.depth;
@@ -738,7 +804,9 @@ WARNING: this may alter match-data.
         a part of the comment.
        */
       if ((this_context == context_block_comment ||
-          this_context == context_comment)
+          this_context == context_comment
+          || this_context == context_generic_comment
+          )
          && pt < e)
        eend++;
 
@@ -769,8 +837,14 @@ syms_of_font_lock (void)
 }
 
 void
-vars_of_font_lock (void)
+reinit_vars_of_font_lock (void)
 {
   xzero (context_cache);
   xzero (bol_context_cache);
 }
+
+void
+vars_of_font_lock (void)
+{
+  reinit_vars_of_font_lock ();
+}