]> code.delx.au - gnu-emacs/blobdiff - src/syntax.c
(init_syntax_once): Convert Fmake_vector argument to Lisp_Integer.
[gnu-emacs] / src / syntax.c
index 3cf575b71ebc6080fcb361647d42d68f2220a219..df89836d0999476ea5a836a81166ac4a2f78c368 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
-   Copyright (C) 1985, 1987, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1985, 87, 93, 94, 95, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -190,7 +190,7 @@ update_syntax_table (pos, count, init, object)
 
   gl_state.current_syntax_table = tmp_table;
   gl_state.old_prop = tmp_table;
-  if (Fsyntax_table_p (tmp_table) == Qt)
+  if (EQ (Fsyntax_table_p (tmp_table), Qt))
     {
       gl_state.use_global = 0;
     } 
@@ -341,8 +341,8 @@ find_defun_start (pos)
    the search was not successful).  */
 
 static int
-back_comment (from, stop)
-     int from, stop;
+back_comment (from, stop, comstyle)
+     int from, stop, comstyle;
 {
   /* Look back, counting the parity of string-quotes,
      and recording the comment-starters seen.
@@ -361,7 +361,7 @@ back_comment (from, stop)
   int comstart_parity = 0;
   int scanstart = from - 1;
   register enum syntaxcode code;
-  int c, comstyle = 0;
+  int c;
 
   /* At beginning of range to scan, we're outside of strings;
      that determines quote parity to the comment-end.  */
@@ -388,10 +388,16 @@ back_comment (from, stop)
                        
       /* If this char starts a 2-char comment start sequence,
         treat it like a 1-char comment starter.  */
-      if (from < scanstart && SYNTAX_COMSTART_FIRST (c)
-         && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from + 1))
-         && comstyle == SYNTAX_COMMENT_STYLE (FETCH_CHAR (from + 1)))
-       code = Scomment;
+      if (from < scanstart && SYNTAX_COMSTART_SECOND (c)
+         && SYNTAX_COMSTART_FIRST (FETCH_CHAR (from - 1))
+         && comstyle == SYNTAX_COMMENT_STYLE (c))
+       {
+         code = Scomment;
+         DEC_POS (from);
+         /* This is apparently the best we can do: */
+         UPDATE_SYNTAX_TABLE_BACKWARD (from);
+         c = FETCH_CHAR (from);
+       }
 
       /* Ignore escaped characters.  */
       if (char_quoted (from))
@@ -492,7 +498,7 @@ Currently, any char-table counts as a syntax table.")
      Lisp_Object object;
 {
   if (CHAR_TABLE_P (object)
-      && XCHAR_TABLE (object)->purpose == Qsyntax_table)
+      && EQ (XCHAR_TABLE (object)->purpose, Qsyntax_table))
     return Qt;
   return Qnil;
 }
@@ -502,7 +508,7 @@ check_syntax_table (obj)
      Lisp_Object obj;
 {
   if (!(CHAR_TABLE_P (obj)
-       && XCHAR_TABLE (obj)->purpose == Qsyntax_table))
+       && EQ (XCHAR_TABLE (obj)->purpose, Qsyntax_table)))
     wrong_type_argument (Qsyntax_table_p, obj);
 }   
 
@@ -659,7 +665,7 @@ DEFUN ("matching-paren", Fmatching_paren, Smatching_paren, 1, 1, 0,
   char_int = XINT (character);
   code = SYNTAX (char_int);
   if (code == Sopen || code == Sclose)
-    return make_number (SYNTAX_MATCH (char_int));
+    return SYNTAX_MATCH (char_int);
   return Qnil;
 }
 
@@ -729,11 +735,11 @@ DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
   p = XSTRING (newentry)->data;
   code = (enum syntaxcode) syntax_spec_code[*p++];
   if (((int) code & 0377) == 0377)
-    error ("invalid syntax description letter: %c", c);
+    error ("invalid syntax description letter: %c", p[-1]);
 
   if (code == Sinherit)
     {
-      SET_RAW_SYNTAX_ENTRY (syntax_table, c, Qnil);
+      SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), Qnil);
       return Qnil;
     }
 
@@ -785,7 +791,7 @@ DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
     /* Since we can't use a shared object, let's make a new one.  */
     newentry = Fcons (make_number (val), match);
     
-  SET_RAW_SYNTAX_ENTRY (syntax_table, c, newentry);
+  SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), newentry);
 
   return Qnil;
 }
@@ -830,7 +836,7 @@ describe_syntax (value)
       return;
     }
 
-  code = (enum syntaxcode) (first & 0377);
+  code = (enum syntaxcode) (XINT (first) & 0377);
   start1 = (XINT (first) >> 16) & 1;
   start2 = (XINT (first) >> 17) & 1;
   end1 = (XINT (first) >> 18) & 1;
@@ -933,12 +939,13 @@ describe_syntax_1 (vector)
 {
   struct buffer *old = current_buffer;
   set_buffer_internal (XBUFFER (Vstandard_output));
-  describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil);
+  describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil, (int *) 0, 0);
   while (! NILP (XCHAR_TABLE (vector)->parent))
     {
       vector = XCHAR_TABLE (vector)->parent;
       insert_string ("\nThe parent syntax table is:");
-      describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil);
+      describe_vector (vector, Qnil, describe_syntax, 0, Qnil, Qnil,
+                      (int *) 0, 0);
     }
        
   call0 (intern ("help-mode"));
@@ -1133,9 +1140,21 @@ skip_chars (forwardp, syntaxp, string, lim)
 {
   register unsigned char *p, *pend;
   register unsigned int c;
+  register int ch;
   unsigned char fastmap[0400];
+  /* If SYNTAXP is 0, STRING may contain multi-byte form of characters
+     of which codes don't fit in FASTMAP.  In that case, we set the
+     first byte of multibyte form (i.e. base leading-code) in FASTMAP
+     and set the actual ranges of characters in CHAR_RANGES.  In the
+     form "X-Y" of STRING, both X and Y must belong to the same
+     character set because a range striding across character sets is
+     meaningless.  */
+  int *char_ranges
+    = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2);
+  int n_char_ranges = 0;
   int negate = 0;
   register int i;
+  int multibyte = !NILP (current_buffer->enable_multibyte_characters);
 
   CHECK_STRING (string, 0);
 
@@ -1168,7 +1187,17 @@ skip_chars (forwardp, syntaxp, string, lim)
 
   while (p != pend)
     {
-      c = *p++;
+      c = *p;
+      if (multibyte)
+       {
+         ch = STRING_CHAR (p, pend - p);
+         p += BYTES_BY_CHAR_HEAD (*p);
+       }
+      else
+       {
+         ch = c;
+         p++;
+       }
       if (syntaxp)
        fastmap[syntax_spec_code[c]] = 1;
       else
@@ -1180,25 +1209,51 @@ skip_chars (forwardp, syntaxp, string, lim)
            }
          if (p != pend && *p == '-')
            {
+             unsigned int ch2;
+
              p++;
              if (p == pend) break;
-             while (c <= *p)
+             if (SINGLE_BYTE_CHAR_P (ch))
+               while (c <= *p)
+                 {
+                   fastmap[c] = 1;
+                   c++;
+                 }
+             else
                {
-                 fastmap[c] = 1;
-                 c++;
+                 fastmap[c] = 1; /* C is the base leading-code.  */
+                 ch2 = STRING_CHAR (p, pend - p);
+                 if (ch <= ch2)
+                   char_ranges[n_char_ranges++] = ch,
+                   char_ranges[n_char_ranges++] = ch2;
                }
-             p++;
+             p += multibyte ? BYTES_BY_CHAR_HEAD (*p) : 1;
            }
          else
-           fastmap[c] = 1;
+           {
+             fastmap[c] = 1;
+             if (!SINGLE_BYTE_CHAR_P (ch))
+               {
+                 char_ranges[n_char_ranges++] = ch;
+                 char_ranges[n_char_ranges++] = ch;
+               }
+           }
        }
     }
 
-  /* If ^ was the first character, complement the fastmap.  */
+  /* If ^ was the first character, complement the fastmap.  In
+     addition, as all multibyte characters have possibility of
+     matching, set all entries for base leading codes, which is
+     harmless even if SYNTAXP is 1.  */
 
   if (negate)
     for (i = 0; i < sizeof fastmap; i++)
-      fastmap[i] ^= 1;
+      {
+       if (!multibyte || !BASE_LEADING_CODE_P (i))
+         fastmap[i] ^= 1;
+       else
+         fastmap[i] = 1;
+      }
 
   {
     int start_point = PT;
@@ -1210,20 +1265,53 @@ skip_chars (forwardp, syntaxp, string, lim)
         SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
        if (forwardp)
          {
-           while (pos < XINT (lim)
-                  && fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+           if (multibyte)
              {
-               pos++;
-               UPDATE_SYNTAX_TABLE_FORWARD (pos);
+               while (pos < XINT (lim)
+                      && fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+                 {
+                   INC_POS (pos);
+                   UPDATE_SYNTAX_TABLE_FORWARD (pos);
+                 }
+             }
+           else
+             {
+               while (pos < XINT (lim)
+                      && fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
+                 {
+                   pos++;
+                   UPDATE_SYNTAX_TABLE_FORWARD (pos);
+                 }
              }
          }
        else
          {
-           while (pos > XINT (lim)
-                  && fastmap[(int) SYNTAX (FETCH_CHAR (pos - 1))])
+           if (multibyte)
              {
-               pos--;
-               UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
+               while (pos > XINT (lim))
+                 {
+                   int savepos = pos;
+                   DEC_POS (pos);
+                   UPDATE_SYNTAX_TABLE_BACKWARD (pos);
+                   if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
+                     {
+                       pos = savepos;
+                       break;
+                     }
+                 }
+             }
+           else
+             {
+               while (pos > XINT (lim))
+                 {
+                   pos--;
+                   UPDATE_SYNTAX_TABLE_BACKWARD (pos);
+                   if (!fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
+                     {
+                       pos++;
+                       break;
+                     }
+                 }
              }
          }
       }
@@ -1231,15 +1319,83 @@ skip_chars (forwardp, syntaxp, string, lim)
       {
        if (forwardp)
          {
-           while (pos < XINT (lim) && fastmap[FETCH_CHAR (pos)])
-             pos++;
+           if (multibyte)
+             while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos))])
+               {
+                 if (!BASE_LEADING_CODE_P (c))
+                   pos++;
+                 else if (n_char_ranges)
+                   {
+                     /* We much check CHAR_RANGES for a multibyte
+                        character.  */
+                     ch = FETCH_MULTIBYTE_CHAR (pos);
+                     for (i = 0; i < n_char_ranges; i += 2)
+                       if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1]))
+                         break;
+                     if (!(negate ^ (i < n_char_ranges)))
+                       break;
+
+                     INC_POS (pos);
+                   }
+                 else
+                   {
+                     if (!negate) break;
+                     INC_POS (pos);
+                   }
+               }
+           else
+             while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)])
+               pos++;
          }
        else
          {
-           while (pos > XINT (lim) && fastmap[FETCH_CHAR (pos - 1)])
-             pos--;
+           if (multibyte)
+             while (pos > XINT (lim))
+               {
+                 int savepos = pos;
+                 DEC_POS (pos);
+                 if (fastmap[(c = FETCH_BYTE (pos))])
+                   {
+                     if (!BASE_LEADING_CODE_P (c))
+                       ;
+                     else if (n_char_ranges)
+                       {
+                         /* We much check CHAR_RANGES for a multibyte
+                            character.  */
+                         ch = FETCH_MULTIBYTE_CHAR (pos);
+                         for (i = 0; i < n_char_ranges; i += 2)
+                           if (ch >= char_ranges[i] && ch <= char_ranges[i + 1])
+                             break;
+                         if (!(negate ^ (i < n_char_ranges)))
+                           {
+                             pos = savepos;
+                             break;
+                           }
+                       }
+                     else
+                       if (!negate)
+                         {
+                           pos = savepos;
+                           break;
+                         }
+                   }
+                 else
+                   {
+                     pos = savepos;
+                     break;
+                   }
+               }
+           else
+             while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)])
+               pos--;
          }
       }
+
+    if (multibyte
+       /* INC_POS or DEC_POS might have moved POS over LIM.  */
+       && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))
+      pos = XINT (lim);
+
     SET_PT (pos);
     immediate_quit = 0;
 
@@ -1382,6 +1538,17 @@ between them, return t; otherwise return nil.")
              comstyle = SYNTAX_COMMENT_STYLE (c1);
              from = temp_pos;
            }
+         if (from > stop && SYNTAX_COMSTART_SECOND (c)
+             && (c1 = FETCH_CHAR (temp_pos),
+                 SYNTAX_COMSTART_FIRST (c1))
+             && !char_quoted (temp_pos))
+           {
+             /* We must record the comment style encountered so that
+                later, we can match only the proper comment begin
+                sequence of the same style.  */
+             code = Scomment;
+             from = temp_pos;
+           }
 
          if (code == Scomment_fence)
            {
@@ -1435,7 +1602,7 @@ between them, return t; otherwise return nil.")
                  break;
                }
 #endif /* 0 */
-             found = back_comment (from, stop);
+             found = back_comment (from, stop, comstyle);
              if (found != -1) from = found;
 #if 0
              /* Look back, counting the parity of string-quotes,
@@ -1882,7 +2049,7 @@ scan_lists (from, count, depth, sexpflag)
                  break;
                }
 #endif /* 0 */
-             found = back_comment (from, stop);
+             found = back_comment (from, stop, comstyle);
              if (found != -1) from = found;
 #if 0
              /* Look back, counting the parity of string-quotes,
@@ -2247,12 +2414,10 @@ scan_sexps_forward (stateptr, from, end, targetdepth,
       UPDATE_SYNTAX_TABLE_FORWARD (from);
       code = SYNTAX (FETCH_CHAR (from));
       INC_FROM;
+
       if (code == Scomment)
        state.comstr_start = prev_from;
-      
-      else if (code == Scomment_fence 
-              || (from < end && SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from))
-                  && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from))))
+      else if (code == Scomment_fence)
        {
          /* Record the comment style we have entered so that only
             the comment-end sequence of the same style actually
@@ -2264,6 +2429,22 @@ scan_sexps_forward (stateptr, from, end, targetdepth,
          if (code != Scomment_fence) INC_FROM;
          code = Scomment;
        }
+     else if (from < end)
+       if (SYNTAX_COMSTART_FIRST (FETCH_CHAR (prev_from)))
+         if (SYNTAX_COMSTART_SECOND (FETCH_CHAR (from)))
+           /* Duplicate code to avoid a very complex if-expression
+              which causes trouble for the SGI compiler.  */
+           {
+             /* Record the comment style we have entered so that only
+                the comment-end sequence of the same style actually
+                terminates the comment section.  */
+             state.comstyle = ( code == Scomment_fence 
+                                ? ST_COMMENT_STYLE 
+                                : SYNTAX_COMMENT_STYLE (FETCH_CHAR (from)));
+             state.comstr_start = prev_from;
+             if (code != Scomment_fence) INC_FROM;
+             code = Scomment;
+           }
 
       if (SYNTAX_PREFIX (FETCH_CHAR (prev_from)))
        continue;
@@ -2534,7 +2715,7 @@ init_syntax_once ()
   Qchar_table_extra_slots = intern ("char-table-extra-slots");
 
   /* Create objects which can be shared among syntax tables.  */
-  Vsyntax_code_object = Fmake_vector (13, Qnil);
+  Vsyntax_code_object = Fmake_vector (make_number (13), Qnil);
   for (i = 0; i < XVECTOR (Vsyntax_code_object)->size; i++)
     XVECTOR (Vsyntax_code_object)->contents[i]
       = Fcons (make_number (i), Qnil);