/[emacs]/emacs/src/syntax.c
ViewVC logotype

Diff of /emacs/src/syntax.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.166 by rms, Sat May 17 12:50:24 2003 UTC revision 1.166.4.1 by handa, Mon Sep 8 12:48:12 2003 UTC
# Line 24  Boston, MA 02111-1307, USA.  */ Line 24  Boston, MA 02111-1307, USA.  */
24  #include "lisp.h"  #include "lisp.h"
25  #include "commands.h"  #include "commands.h"
26  #include "buffer.h"  #include "buffer.h"
27  #include "charset.h"  #include "character.h"
28  #include "keymap.h"  #include "keymap.h"
29    
30  /* Make syntax table lookup grant data in gl_state.  */  /* Make syntax table lookup grant data in gl_state.  */
# Line 97  static int find_start_modiff; Line 97  static int find_start_modiff;
97  static int find_defun_start P_ ((int, int));  static int find_defun_start P_ ((int, int));
98  static int back_comment P_ ((int, int, int, int, int, int *, int *));  static int back_comment P_ ((int, int, int, int, int, int *, int *));
99  static int char_quoted P_ ((int, int));  static int char_quoted P_ ((int, int));
100  static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object));  static Lisp_Object skip_chars P_ ((int, Lisp_Object, Lisp_Object));
101    static Lisp_Object skip_syntaxes P_ ((int, Lisp_Object, Lisp_Object));
102  static Lisp_Object scan_lists P_ ((int, int, int, int));  static Lisp_Object scan_lists P_ ((int, int, int, int));
103  static void scan_sexps_forward P_ ((struct lisp_parse_state *,  static void scan_sexps_forward P_ ((struct lisp_parse_state *,
104                                      int, int, int, int,                                      int, int, int, int,
# Line 293  char_quoted (charpos, bytepos) Line 294  char_quoted (charpos, bytepos)
294    while (bytepos >= beg)    while (bytepos >= beg)
295      {      {
296        UPDATE_SYNTAX_TABLE_BACKWARD (charpos);        UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
297        code = SYNTAX (FETCH_CHAR (bytepos));        code = SYNTAX (FETCH_CHAR_AS_MULTIBYTE (bytepos));
298        if (! (code == Scharquote || code == Sescape))        if (! (code == Scharquote || code == Sescape))
299          break;          break;
300    
# Line 382  find_defun_start (pos, pos_byte) Line 383  find_defun_start (pos, pos_byte)
383      {      {
384        /* Open-paren at start of line means we may have found our        /* Open-paren at start of line means we may have found our
385           defun-start.  */           defun-start.  */
386        if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)        if (SYNTAX (FETCH_CHAR_AS_MULTIBYTE (PT_BYTE)) == Sopen)
387          {          {
388            SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */            SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */
389            if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)            if (SYNTAX (FETCH_CHAR_AS_MULTIBYTE (PT_BYTE)) == Sopen)
390              break;              break;
391            /* Now fallback to the default value.  */            /* Now fallback to the default value.  */
392            gl_state.current_syntax_table = current_buffer->syntax_table;            gl_state.current_syntax_table = current_buffer->syntax_table;
# Line 505  back_comment (from, from_byte, stop, com Line 506  back_comment (from, from_byte, stop, com
506        UPDATE_SYNTAX_TABLE_BACKWARD (from);        UPDATE_SYNTAX_TABLE_BACKWARD (from);
507    
508        prev_syntax = syntax;        prev_syntax = syntax;
509        c = FETCH_CHAR (from_byte);        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
510        syntax = SYNTAX_WITH_FLAGS (c);        syntax = SYNTAX_WITH_FLAGS (c);
511        code = SYNTAX (c);        code = SYNTAX (c);
512    
# Line 534  back_comment (from, from_byte, stop, com Line 535  back_comment (from, from_byte, stop, com
535            int next = from, next_byte = from_byte, next_c, next_syntax;            int next = from, next_byte = from_byte, next_c, next_syntax;
536            DEC_BOTH (next, next_byte);            DEC_BOTH (next, next_byte);
537            UPDATE_SYNTAX_TABLE_BACKWARD (next);            UPDATE_SYNTAX_TABLE_BACKWARD (next);
538            next_c = FETCH_CHAR (next_byte);            next_c = FETCH_CHAR_AS_MULTIBYTE (next_byte);
539            next_syntax = SYNTAX_WITH_FLAGS (next_c);            next_syntax = SYNTAX_WITH_FLAGS (next_c);
540            if (((com2start || comnested)            if (((com2start || comnested)
541                 && SYNTAX_FLAGS_COMEND_SECOND (syntax)                 && SYNTAX_FLAGS_COMEND_SECOND (syntax)
# Line 838  char syntax_code_spec[16] = Line 839  char syntax_code_spec[16] =
839  static Lisp_Object Vsyntax_code_object;  static Lisp_Object Vsyntax_code_object;
840    
841    
 /* Look up the value for CHARACTER in syntax table TABLE's parent  
    and its parents.  SYNTAX_ENTRY calls this, when TABLE itself has nil  
    for CHARACTER.  It's actually used only when not compiled with GCC.  */  
   
 Lisp_Object  
 syntax_parent_lookup (table, character)  
      Lisp_Object table;  
      int character;  
 {  
   Lisp_Object value;  
   
   while (1)  
     {  
       table = XCHAR_TABLE (table)->parent;  
       if (NILP (table))  
         return Qnil;  
   
       value = XCHAR_TABLE (table)->contents[character];  
       if (!NILP (value))  
         return value;  
     }  
 }  
   
842  DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,  DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
843         doc: /* Return the syntax code of CHARACTER, described by a character.         doc: /* Return the syntax code of CHARACTER, described by a character.
844  For example, if CHARACTER is a word constituent,  For example, if CHARACTER is a word constituent,
# Line 979  DEFUN ("modify-syntax-entry", Fmodify_sy Line 957  DEFUN ("modify-syntax-entry", Fmodify_sy
957         doc: /* Set syntax for character CHAR according to string NEWENTRY.         doc: /* Set syntax for character CHAR according to string NEWENTRY.
958  The syntax is changed only for table SYNTAX_TABLE, which defaults to  The syntax is changed only for table SYNTAX_TABLE, which defaults to
959   the current buffer's syntax table.   the current buffer's syntax table.
960    CHAR may be a cons (MIN . MAX), in which case, syntaxes of all characters
961    in the range MIN and MAX are changed.
962  The first character of NEWENTRY should be one of the following:  The first character of NEWENTRY should be one of the following:
963    Space or -  whitespace syntax.    w   word constituent.    Space or -  whitespace syntax.    w   word constituent.
964    _           symbol constituent.   .   punctuation.    _           symbol constituent.   .   punctuation.
# Line 1015  usage: (modify-syntax-entry CHAR NEWENTR Line 995  usage: (modify-syntax-entry CHAR NEWENTR
995       (c, newentry, syntax_table)       (c, newentry, syntax_table)
996       Lisp_Object c, newentry, syntax_table;       Lisp_Object c, newentry, syntax_table;
997  {  {
998    CHECK_NUMBER (c);    if (CONSP (c))
999        {
1000          CHECK_CHARACTER_CAR (c);
1001          CHECK_CHARACTER_CDR (c);
1002        }
1003      else
1004        CHECK_CHARACTER (c);
1005    
1006    if (NILP (syntax_table))    if (NILP (syntax_table))
1007      syntax_table = current_buffer->syntax_table;      syntax_table = current_buffer->syntax_table;
1008    else    else
1009      check_syntax_table (syntax_table);      check_syntax_table (syntax_table);
1010    
1011    SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), Fstring_to_syntax (newentry));    newentry = Fstring_to_syntax (newentry);
1012      if (CONSP (c))
1013        SET_RAW_SYNTAX_ENTRY_RANGE (syntax_table, c, newentry);
1014      else
1015        SET_RAW_SYNTAX_ENTRY (syntax_table, XINT (c), newentry);
1016    return Qnil;    return Qnil;
1017  }  }
1018    
# Line 1176  DEFUN ("internal-describe-syntax-value", Line 1166  DEFUN ("internal-describe-syntax-value",
1166    
1167  int parse_sexp_ignore_comments;  int parse_sexp_ignore_comments;
1168    
1169    /* Char-table of functions that find the next or previous word
1170       boundary.  */
1171    Lisp_Object Vfind_word_boundary_function_table;
1172    
1173  /* Return the position across COUNT words from FROM.  /* Return the position across COUNT words from FROM.
1174     If that many words cannot be found before the end of the buffer, return 0.     If that many words cannot be found before the end of the buffer, return 0.
1175     COUNT negative means scan backward and stop at word beginning.  */     COUNT negative means scan backward and stop at word beginning.  */
# Line 1189  scan_words (from, count) Line 1183  scan_words (from, count)
1183    register int from_byte = CHAR_TO_BYTE (from);    register int from_byte = CHAR_TO_BYTE (from);
1184    register enum syntaxcode code;    register enum syntaxcode code;
1185    int ch0, ch1;    int ch0, ch1;
1186      Lisp_Object func, script, pos;
1187    
1188    immediate_quit = 1;    immediate_quit = 1;
1189    QUIT;    QUIT;
# Line 1205  scan_words (from, count) Line 1200  scan_words (from, count)
1200                return 0;                return 0;
1201              }              }
1202            UPDATE_SYNTAX_TABLE_FORWARD (from);            UPDATE_SYNTAX_TABLE_FORWARD (from);
1203            ch0 = FETCH_CHAR (from_byte);            ch0 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1204            code = SYNTAX (ch0);            code = SYNTAX (ch0);
1205            INC_BOTH (from, from_byte);            INC_BOTH (from, from_byte);
1206            if (words_include_escapes            if (words_include_escapes
# Line 1216  scan_words (from, count) Line 1211  scan_words (from, count)
1211          }          }
1212        /* Now CH0 is a character which begins a word and FROM is the        /* Now CH0 is a character which begins a word and FROM is the
1213           position of the next character.  */           position of the next character.  */
1214        while (1)        func = CHAR_TABLE_REF (Vfind_word_boundary_function_table, ch0);
1215          if (! NILP (Ffboundp (func)))
1216          {          {
1217            if (from == end) break;            pos = call2 (func, make_number (from - 1), make_number (end));
1218            UPDATE_SYNTAX_TABLE_FORWARD (from);            if (INTEGERP (pos) && XINT (pos) > from)
1219            ch1 = FETCH_CHAR (from_byte);              {
1220            code = SYNTAX (ch1);                from = XINT (pos);
1221            if (!(words_include_escapes                from_byte = CHAR_TO_BYTE (from);
1222                  && (code == Sescape || code == Scharquote)))              }
1223              if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))          }
1224                break;        else
1225            INC_BOTH (from, from_byte);          {
1226            ch0 = ch1;            script = CHAR_TABLE_REF (Vchar_script_table, ch0);
1227              while (1)
1228                {
1229                  if (from == end) break;
1230                  UPDATE_SYNTAX_TABLE_FORWARD (from);
1231                  ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1232                  code = SYNTAX (ch1);
1233                  if ((code != Sword
1234                       && (! words_include_escapes
1235                           || (code != Sescape && code != Scharquote)))
1236                      || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch1), script))
1237                    break;
1238                  INC_BOTH (from, from_byte);
1239                  ch0 = ch1;
1240                }
1241          }          }
1242        count--;        count--;
1243      }      }
# Line 1242  scan_words (from, count) Line 1252  scan_words (from, count)
1252              }              }
1253            DEC_BOTH (from, from_byte);            DEC_BOTH (from, from_byte);
1254            UPDATE_SYNTAX_TABLE_BACKWARD (from);            UPDATE_SYNTAX_TABLE_BACKWARD (from);
1255            ch1 = FETCH_CHAR (from_byte);            ch1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1256            code = SYNTAX (ch1);            code = SYNTAX (ch1);
1257            if (words_include_escapes            if (words_include_escapes
1258                && (code == Sescape || code == Scharquote))                && (code == Sescape || code == Scharquote))
# Line 1252  scan_words (from, count) Line 1262  scan_words (from, count)
1262          }          }
1263        /* Now CH1 is a character which ends a word and FROM is the        /* Now CH1 is a character which ends a word and FROM is the
1264           position of it.  */           position of it.  */
1265        while (1)        func = CHAR_TABLE_REF (Vfind_word_boundary_function_table, ch1);
1266          if (! NILP (Ffboundp (func)))
1267            {
1268              pos = call2 (func, make_number (from), make_number (beg));
1269              if (INTEGERP (pos) && XINT (pos) < from)
1270                {
1271                  from = XINT (pos);
1272                  from_byte = CHAR_TO_BYTE (from);
1273                }
1274            }
1275          else
1276          {          {
1277            int temp_byte;            script = CHAR_TABLE_REF (Vchar_script_table, ch1);
1278              while (1)
1279                {
1280                  int temp_byte;
1281    
1282            if (from == beg)                if (from == beg)
1283              break;                  break;
1284            temp_byte = dec_bytepos (from_byte);                temp_byte = dec_bytepos (from_byte);
1285            UPDATE_SYNTAX_TABLE_BACKWARD (from);                UPDATE_SYNTAX_TABLE_BACKWARD (from);
1286            ch0 = FETCH_CHAR (temp_byte);                ch0 = FETCH_CHAR_AS_MULTIBYTE (temp_byte);
1287            code = SYNTAX (ch0);                code = SYNTAX (ch0);
1288            if (!(words_include_escapes                if ((code != Sword
1289                  && (code == Sescape || code == Scharquote)))                     && (! words_include_escapes
1290              if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))                         || (code != Sescape && code != Scharquote)))
1291                break;                    || ! EQ (CHAR_TABLE_REF (Vchar_script_table, ch0), script))
1292            DEC_BOTH (from, from_byte);                  break;
1293            ch1 = ch0;                DEC_BOTH (from, from_byte);
1294                  ch1 = ch0;
1295                }
1296          }          }
1297        count++;        count++;
1298      }      }
# Line 1316  they will be treated as literals.  */) Line 1341  they will be treated as literals.  */)
1341       (string, lim)       (string, lim)
1342       Lisp_Object string, lim;       Lisp_Object string, lim;
1343  {  {
1344    return skip_chars (1, 0, string, lim);    return skip_chars (1, string, lim);
1345  }  }
1346    
1347  DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,  DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
# Line 1326  Returns the distance traveled, either ze Line 1351  Returns the distance traveled, either ze
1351       (string, lim)       (string, lim)
1352       Lisp_Object string, lim;       Lisp_Object string, lim;
1353  {  {
1354    return skip_chars (0, 0, string, lim);    return skip_chars (0, string, lim);
1355  }  }
1356    
1357  DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,  DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
# Line 1338  This function returns the distance trave Line 1363  This function returns the distance trave
1363       (syntax, lim)       (syntax, lim)
1364       Lisp_Object syntax, lim;       Lisp_Object syntax, lim;
1365  {  {
1366    return skip_chars (1, 1, syntax, lim);    return skip_syntaxes (1, syntax, lim);
1367  }  }
1368    
1369  DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,  DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
# Line 1350  This function returns the distance trave Line 1375  This function returns the distance trave
1375       (syntax, lim)       (syntax, lim)
1376       Lisp_Object syntax, lim;       Lisp_Object syntax, lim;
1377  {  {
1378    return skip_chars (0, 1, syntax, lim);    return skip_syntaxes (0, syntax, lim);
1379  }  }
1380    
1381  static Lisp_Object  static Lisp_Object
1382  skip_chars (forwardp, syntaxp, string, lim)  skip_chars (forwardp, string, lim)
1383       int forwardp, syntaxp;       int forwardp;
1384       Lisp_Object string, lim;       Lisp_Object string, lim;
1385  {  {
1386    register unsigned int c;    register unsigned int c;
1387    unsigned char fastmap[0400];    unsigned char fastmap[0400];
1388    /* If SYNTAXP is 0, STRING may contain multi-byte form of characters    /* Store the ranges of non-ASCII characters.  */
      of which codes don't fit in FASTMAP.  In that case, set the  
      ranges of characters in CHAR_RANGES.  */  
1389    int *char_ranges;    int *char_ranges;
1390    int n_char_ranges = 0;    int n_char_ranges = 0;
1391    int negate = 0;    int negate = 0;
1392    register int i, i_byte;    register int i, i_byte;
1393    int multibyte = !NILP (current_buffer->enable_multibyte_characters);    /* Set to 1 if the current buffer is multibyte and the region
1394         contains non-ASCII chars.  */
1395      int multibyte;
1396      /* Set to 1 if STRING is multibyte and it contains non-ASCII
1397         chars.  */
1398    int string_multibyte;    int string_multibyte;
1399    int size_byte;    int size_byte;
1400    const unsigned char *str;    const unsigned char *str;
1401    int len;    int len;
1402    
1403    CHECK_STRING (string);    CHECK_STRING (string);
   char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);  
   string_multibyte = STRING_MULTIBYTE (string);  
   str = SDATA (string);  
   size_byte = SBYTES (string);  
   
   /* Adjust the multibyteness of the string to that of the buffer.  */  
   if (multibyte != string_multibyte)  
     {  
       int nbytes;  
   
       if (multibyte)  
         nbytes = count_size_as_multibyte (SDATA (string),  
                                           SCHARS (string));  
       else  
         nbytes = SCHARS (string);  
       if (nbytes != size_byte)  
         {  
           unsigned char *tmp = (unsigned char *) alloca (nbytes);  
           copy_text (SDATA (string), tmp, size_byte,  
                      string_multibyte, multibyte);  
           size_byte = nbytes;  
           str = tmp;  
         }  
     }  
1404    
1405    if (NILP (lim))    if (NILP (lim))
1406      XSETINT (lim, forwardp ? ZV : BEGV);      XSETINT (lim, forwardp ? ZV : BEGV);
# Line 1410  skip_chars (forwardp, syntaxp, string, l Line 1413  skip_chars (forwardp, syntaxp, string, l
1413    if (XINT (lim) < BEGV)    if (XINT (lim) < BEGV)
1414      XSETFASTINT (lim, BEGV);      XSETFASTINT (lim, BEGV);
1415    
1416      multibyte = (!NILP (current_buffer->enable_multibyte_characters)
1417                   && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
1418      string_multibyte = SBYTES (string) > SCHARS (string);
1419    
1420    bzero (fastmap, sizeof fastmap);    bzero (fastmap, sizeof fastmap);
1421      if (multibyte)
1422        char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);
1423    
1424    i_byte = 0;    str = SDATA (string);
1425      size_byte = SBYTES (string);
1426    
1427      i_byte = 0;
1428    if (i_byte < size_byte    if (i_byte < size_byte
1429        && SREF (string, 0) == '^')        && SREF (string, 0) == '^')
1430      {      {
# Line 1421  skip_chars (forwardp, syntaxp, string, l Line 1432  skip_chars (forwardp, syntaxp, string, l
1432      }      }
1433    
1434    /* Find the characters specified and set their elements of fastmap.    /* Find the characters specified and set their elements of fastmap.
1435       If syntaxp, each character counts as itself.       Handle backslashes and ranges specially.
      Otherwise, handle backslashes and ranges specially.  */  
1436    
1437    while (i_byte < size_byte)       If STRING contains non-ASCII characters, setup char_ranges for
1438         them and use fastmap only for their leading codes.  */
1439    
1440      if (! string_multibyte)
1441      {      {
1442        c = STRING_CHAR_AND_LENGTH (str + i_byte, size_byte - i_byte, len);        int string_has_eight_bit = 0;
       i_byte += len;  
1443    
1444        if (syntaxp)        /* At first setup fastmap.  */
1445          fastmap[syntax_spec_code[c & 0377]] = 1;        while (i_byte < size_byte)
1446        else          {
1447              c = str[i_byte++];
1448    
1449              if (c == '\\')
1450                {
1451                  if (i_byte == size_byte)
1452                    break;
1453    
1454                  c = str[i_byte++];
1455                }
1456              if (i_byte < size_byte
1457                  && str[i_byte] == '-')
1458                {
1459                  unsigned int c2;
1460    
1461                  /* Skip over the dash.  */
1462                  i_byte++;
1463    
1464                  if (i_byte == size_byte)
1465                    break;
1466    
1467                  /* Get the end of the range.  */
1468                  c2 = str[i_byte++];
1469                  if (c2 == '\\'
1470                      && i_byte < size_byte)
1471                    c2 = str[i_byte++];
1472    
1473                  if (c <= c2)
1474                    {
1475                      while (c <= c2)
1476                        fastmap[c++] = 1;
1477                      if (! ASCII_CHAR_P (c2))
1478                        string_has_eight_bit = 1;
1479                    }
1480                }
1481              else
1482                {
1483                  fastmap[c] = 1;
1484                  if (! ASCII_CHAR_P (c))
1485                    string_has_eight_bit = 1;
1486                }
1487            }
1488    
1489          /* If the current range is multibyte and STRING contains
1490             eight-bit chars, arrange fastmap and setup char_ranges for
1491             the corresponding multibyte chars.  */
1492          if (multibyte && string_has_eight_bit)
1493            {
1494              unsigned char fastmap2[0400];
1495              int range_start_byte, range_start_char;
1496    
1497              bcopy (fastmap2 + 0200, fastmap + 0200, 0200);
1498              bzero (fastmap + 0200, 0200);
1499              /* We are sure that this loop stops.  */
1500              for (i = 0200; ! fastmap2[i]; i++);
1501              c = unibyte_char_to_multibyte (i);
1502              fastmap[CHAR_LEADING_CODE (c)] = 1;
1503              range_start_byte = i;
1504              range_start_char = c;
1505              for (i = 129; i < 0400; i++)
1506                {
1507                  c = unibyte_char_to_multibyte (i);
1508                  fastmap[CHAR_LEADING_CODE (c)] = 1;
1509                  if (i - range_start_byte != c - range_start_char)
1510                    {
1511                      char_ranges[n_char_ranges++] = range_start_char;
1512                      char_ranges[n_char_ranges++] = ((i - 1 - range_start_byte)
1513                                                      + range_start_char);
1514                      range_start_byte = i;
1515                      range_start_char = c;
1516                    }
1517                }
1518              char_ranges[n_char_ranges++] = range_start_char;
1519              char_ranges[n_char_ranges++] = ((i - 1 - range_start_byte)
1520                                              + range_start_char);
1521            }
1522        }
1523      else
1524        {
1525          while (i_byte < size_byte)
1526          {          {
1527              unsigned char leading_code;
1528    
1529              leading_code = str[i_byte];
1530              c = STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
1531              i_byte += len;
1532    
1533            if (c == '\\')            if (c == '\\')
1534              {              {
1535                if (i_byte == size_byte)                if (i_byte == size_byte)
1536                  break;                  break;
1537    
1538                  leading_code = str[i_byte];
1539                c = STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len);                c = STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len);
1540                i_byte += len;                i_byte += len;
1541              }              }
# Line 1445  skip_chars (forwardp, syntaxp, string, l Line 1543  skip_chars (forwardp, syntaxp, string, l
1543                && str[i_byte] == '-')                && str[i_byte] == '-')
1544              {              {
1545                unsigned int c2;                unsigned int c2;
1546                  unsigned char leading_code2;
1547    
1548                /* Skip over the dash.  */                /* Skip over the dash.  */
1549                i_byte++;                i_byte++;
# Line 1453  skip_chars (forwardp, syntaxp, string, l Line 1552  skip_chars (forwardp, syntaxp, string, l
1552                  break;                  break;
1553    
1554                /* Get the end of the range.  */                /* Get the end of the range.  */
1555                c2 =STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len);                leading_code2 = str[i_byte];
1556                  c2 =STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
1557                i_byte += len;                i_byte += len;
1558    
1559                if (SINGLE_BYTE_CHAR_P (c))                if (c2 == '\\'
1560                      && i_byte < size_byte)
1561                  {                  {
1562                    if (! SINGLE_BYTE_CHAR_P (c2))                    leading_code2 = str[i_byte];
1563                      {                    c2 =STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
1564                        /* Handle a range starting with a character of                    i_byte += len;
1565                           less than 256, and ending with a character of                  }
                          not less than 256.  Split that into two  
                          ranges, the low one ending at 0377, and the  
                          high one starting at the smallest character  
                          in the charset of C2 and ending at C2.  */  
                       int charset = CHAR_CHARSET (c2);  
                       int c1 = MAKE_CHAR (charset, 0, 0);  
1566    
1567                        char_ranges[n_char_ranges++] = c1;                if (ASCII_CHAR_P (c))
1568                        char_ranges[n_char_ranges++] = c2;                  {
1569                        c2 = 0377;                    while (c <= c2 && c < 0x80)
1570                      }                      fastmap[c++] = 1;
1571                    while (c <= c2)                    leading_code = CHAR_LEADING_CODE (c);
                     {  
                       fastmap[c] = 1;  
                       c++;  
                     }  
1572                  }                  }
1573                else if (c <= c2) /* Both C and C2 are multibyte char.  */                if (! ASCII_CHAR_P (c))
1574                  {                  {
1575                    char_ranges[n_char_ranges++] = c;                    while (leading_code <= leading_code2)
1576                    char_ranges[n_char_ranges++] = c2;                      fastmap[leading_code++] = 1;
1577                      if (c <= c2)
1578                        {
1579                          char_ranges[n_char_ranges++] = c;
1580                          char_ranges[n_char_ranges++] = c2;
1581                        }
1582                  }                  }
1583              }              }
1584            else            else
1585              {              {
1586                if (SINGLE_BYTE_CHAR_P (c))                if (ASCII_CHAR_P (c))
1587                  fastmap[c] = 1;                  fastmap[c] = 1;
1588                else                else
1589                  {                  {
1590                      fastmap[leading_code] = 1;
1591                    char_ranges[n_char_ranges++] = c;                    char_ranges[n_char_ranges++] = c;
1592                    char_ranges[n_char_ranges++] = c;                    char_ranges[n_char_ranges++] = c;
1593                  }                  }
1594              }              }
1595          }          }
1596    
1597          /* If the current range is unibyte and STRING contains non-ASCII
1598             chars, arrange fastmap for the corresponding unibyte
1599             chars.  */
1600    
1601          if (! multibyte && n_char_ranges > 0)
1602            {
1603              bzero (fastmap + 0200, 0200);
1604              for (i = 0; i < n_char_ranges; i += 2)
1605                {
1606                  int c1 = char_ranges[i];
1607                  int c2 = char_ranges[i + 1];
1608    
1609                  for (; c1 <= c2; c1++)
1610                    fastmap[CHAR_TO_BYTE8 (c1)] = 1;
1611                }
1612            }
1613      }      }
1614    
1615    /* If ^ was the first character, complement the fastmap.  */    /* If ^ was the first character, complement the fastmap.  */
1616    if (negate)    if (negate)
1617      for (i = 0; i < sizeof fastmap; i++)      {
1618        fastmap[i] ^= 1;        if (! multibyte)
1619            for (i = 0; i < sizeof fastmap; i++)
1620              fastmap[i] ^= 1;
1621          else
1622            {
1623              for (i = 0; i < 0200; i++)
1624                fastmap[i] ^= 1;
1625              /* All non-ASCII chars possibly match.  */
1626              for (; i < sizeof fastmap; i++)
1627                fastmap[i] = 1;
1628            }
1629        }
1630    
1631    {    {
1632      int start_point = PT;      int start_point = PT;
# Line 1511  skip_chars (forwardp, syntaxp, string, l Line 1636  skip_chars (forwardp, syntaxp, string, l
1636    
1637      if (forwardp)      if (forwardp)
1638        {        {
1639          endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));          endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
1640          stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;          stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;
1641        }        }
1642      else      else
1643        {        {
1644          endp = CHAR_POS_ADDR (XINT (lim));          endp = CHAR_POS_ADDR (XINT (lim));
1645          stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;          stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;
1646        }        }
1647    
1648      immediate_quit = 1;      immediate_quit = 1;
1649      if (syntaxp)      if (forwardp)
1650        {        {
1651          SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);          if (multibyte)
1652          if (forwardp)            while (1)
1653            {              {
1654              if (multibyte)                int nbytes;
               while (1)  
                 {  
                   int nbytes;  
1655    
1656                    if (p >= stop)                if (p >= stop)
                     {  
                       if (p >= endp)  
                         break;  
                       p = GAP_END_ADDR;  
                       stop = endp;  
                     }  
                   c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);  
                   if (! fastmap[(int) SYNTAX (c)])  
                     break;  
                   p += nbytes, pos++, pos_byte += nbytes;  
                   UPDATE_SYNTAX_TABLE_FORWARD (pos);  
                 }  
             else  
               while (1)  
1657                  {                  {
1658                    if (p >= stop)                    if (p >= endp)
                     {  
                       if (p >= endp)  
                         break;  
                       p = GAP_END_ADDR;  
                       stop = endp;  
                     }  
                   if (! fastmap[(int) SYNTAX (*p)])  
1659                      break;                      break;
1660                    p++, pos++;                    p = GAP_END_ADDR;
1661                    UPDATE_SYNTAX_TABLE_FORWARD (pos);                    stop = endp;
1662                  }                  }
1663            }                if (! fastmap[*p])
1664          else                  break;
1665            {                c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
1666              if (multibyte)                if (! ASCII_CHAR_P (c))
               while (1)  
1667                  {                  {
1668                    unsigned char *prev_p;                    /* As we are looking at a multibyte character, we
1669                    int nbytes;                       must look up the character in the table
1670                         CHAR_RANGES.  If there's no data in the table,
1671                    if (p <= stop)                       that character is not what we want to skip.  */
1672                      {  
1673                        if (p <= endp)                    /* The following code do the right thing even if
1674                          break;                       n_char_ranges is zero (i.e. no data in
1675                        p = GPT_ADDR;                       CHAR_RANGES).  */
1676                        stop = endp;                    for (i = 0; i < n_char_ranges; i += 2)
1677                      }                      if (c >= char_ranges[i] && c <= char_ranges[i + 1])
                   prev_p = p;  
                   while (--p >= stop && ! CHAR_HEAD_P (*p));  
                   PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes);  
                   if (prev_p - p > nbytes)  
                     p = prev_p - 1, c = *p, nbytes = 1;  
                   else  
                     c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);  
                   pos--, pos_byte -= nbytes;  
                   UPDATE_SYNTAX_TABLE_BACKWARD (pos);  
                   if (! fastmap[(int) SYNTAX (c)])  
                     {  
                       pos++;  
                       pos_byte += nbytes;  
1678                        break;                        break;
1679                      }                    if (!(negate ^ (i < n_char_ranges)))
1680                        break;
1681                  }                  }
1682              else                p += nbytes, pos++, pos_byte += nbytes;
1683                while (1)              }
1684            else
1685              while (1)
1686                {
1687                  if (p >= stop)
1688                  {                  {
1689                    if (p <= stop)                    if (p >= endp)
                     {  
                       if (p <= endp)  
                         break;  
                       p = GPT_ADDR;  
                       stop = endp;  
                     }  
                   if (! fastmap[(int) SYNTAX (p[-1])])  
1690                      break;                      break;
1691                    p--, pos--;                    p = GAP_END_ADDR;
1692                    UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);                    stop = endp;
1693                  }                  }
1694            }                if (!fastmap[*p])
1695                    break;
1696                  p++, pos++, pos_byte++;
1697                }
1698        }        }
1699      else      else
1700        {        {
1701          if (forwardp)          if (multibyte)
1702            {            while (1)
1703              if (multibyte)              {
1704                while (1)                unsigned char *prev_p;
                 {  
                   int nbytes;  
1705    
1706                    if (p >= stop)                if (p <= stop)
                     {  
                       if (p >= endp)  
                         break;  
                       p = GAP_END_ADDR;  
                       stop = endp;  
                     }  
                   c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);  
                   if (SINGLE_BYTE_CHAR_P (c))  
                     {  
                       if (!fastmap[c])  
                         break;  
                     }  
                   else  
                     {  
                       /* If we are looking at a multibyte character,  
                          we must look up the character in the table  
                          CHAR_RANGES.  If there's no data in the  
                          table, that character is not what we want to  
                          skip.  */  
   
                       /* The following code do the right thing even if  
                          n_char_ranges is zero (i.e. no data in  
                          CHAR_RANGES).  */  
                       for (i = 0; i < n_char_ranges; i += 2)  
                         if (c >= char_ranges[i] && c <= char_ranges[i + 1])  
                           break;  
                       if (!(negate ^ (i < n_char_ranges)))  
                         break;  
                     }  
                   p += nbytes, pos++, pos_byte += nbytes;  
                 }  
             else  
               while (1)  
1707                  {                  {
1708                    if (p >= stop)                    if (p <= endp)
                     {  
                       if (p >= endp)  
                         break;  
                       p = GAP_END_ADDR;  
                       stop = endp;  
                     }  
                   if (!fastmap[*p])  
1709                      break;                      break;
1710                    p++, pos++;                    p = GPT_ADDR;
1711                      stop = endp;
1712                  }                  }
1713            }                prev_p = p;
1714          else                while (--p >= stop && ! CHAR_HEAD_P (*p));
1715            {                if (! fastmap[*p])
1716              if (multibyte)                  break;
1717                while (1)                c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
1718                  if (! ASCII_CHAR_P (c))
1719                  {                  {
1720                    unsigned char *prev_p;                    /* See the comment in the previous similar code.  */
1721                    int nbytes;                    for (i = 0; i < n_char_ranges; i += 2)
1722                        if (c >= char_ranges[i] && c <= char_ranges[i + 1])
1723                    if (p <= stop)                        break;
1724                      {                    if (!(negate ^ (i < n_char_ranges)))
1725                        if (p <= endp)                      break;
                         break;  
                       p = GPT_ADDR;  
                       stop = endp;  
                     }  
                   prev_p = p;  
                   while (--p >= stop && ! CHAR_HEAD_P (*p));  
                   PARSE_MULTIBYTE_SEQ (p, MAX_MULTIBYTE_LENGTH, nbytes);  
                   if (prev_p - p > nbytes)  
                     p = prev_p - 1, c = *p, nbytes = 1;  
                   else  
                     c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);  
                   if (SINGLE_BYTE_CHAR_P (c))  
                     {  
                       if (!fastmap[c])  
                         break;  
                     }  
                   else  
                     {  
                       /* See the comment in the previous similar code.  */  
                       for (i = 0; i < n_char_ranges; i += 2)  
                         if (c >= char_ranges[i] && c <= char_ranges[i + 1])  
                           break;  
                       if (!(negate ^ (i < n_char_ranges)))  
                         break;  
                     }  
                   pos--, pos_byte -= nbytes;  
1726                  }                  }
1727              else                pos--, pos_byte -= prev_p - p;
1728                while (1)              }
1729            else
1730              while (1)
1731                {
1732                  if (p <= stop)
1733                  {                  {
1734                    if (p <= stop)                    if (p <= endp)
                     {  
                       if (p <= endp)  
                         break;  
                       p = GPT_ADDR;  
                       stop = endp;  
                     }  
                   if (!fastmap[p[-1]])  
1735                      break;                      break;
1736                    p--, pos--;                    p = GPT_ADDR;
1737                      stop = endp;
1738                  }                  }
1739            }                if (!fastmap[p[-1]])
1740                    break;
1741                  p--, pos--, pos_byte--;
1742                }
1743          }
1744    
1745        SET_PT_BOTH (pos, pos_byte);
1746        immediate_quit = 0;
1747    
1748        return make_number (PT - start_point);
1749      }
1750    }
1751    
1752    
1753    static Lisp_Object
1754    skip_syntaxes (forwardp, string, lim)
1755         int forwardp;
1756         Lisp_Object string, lim;
1757    {
1758      register unsigned int c;
1759      unsigned char fastmap[0400];
1760      int negate = 0;
1761      register int i, i_byte;
1762      int multibyte;
1763      int size_byte;
1764      unsigned char *str;
1765    
1766      CHECK_STRING (string);
1767    
1768      if (NILP (lim))
1769        XSETINT (lim, forwardp ? ZV : BEGV);
1770      else
1771        CHECK_NUMBER_COERCE_MARKER (lim);
1772    
1773      /* In any case, don't allow scan outside bounds of buffer.  */
1774      if (XINT (lim) > ZV)
1775        XSETFASTINT (lim, ZV);
1776      if (XINT (lim) < BEGV)
1777        XSETFASTINT (lim, BEGV);
1778    
1779      if (forwardp ? (PT >= XFASTINT (lim)) : (PT <= XFASTINT (lim)))
1780        return Qnil;
1781    
1782      multibyte = (!NILP (current_buffer->enable_multibyte_characters)
1783                   && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
1784    
1785      bzero (fastmap, sizeof fastmap);
1786    
1787      if (SBYTES (string) > SCHARS (string))
1788        /* As this is very rare case (syntax spec is ASCII only), don't
1789           consider efficiency.  */
1790        string = string_make_unibyte (string);
1791    
1792      str = SDATA (string);
1793      size_byte = SBYTES (string);
1794    
1795      i_byte = 0;
1796      if (i_byte < size_byte
1797          && SREF (string, 0) == '^')
1798        {
1799          negate = 1; i_byte++;
1800        }
1801    
1802      /* Find the syntaxes specified and set their elements of fastmap.  */
1803    
1804      while (i_byte < size_byte)
1805        {
1806          c = str[i_byte++];
1807          fastmap[syntax_spec_code[c]] = 1;
1808        }
1809    
1810      /* If ^ was the first character, complement the fastmap.  */
1811      if (negate)
1812        for (i = 0; i < sizeof fastmap; i++)
1813          fastmap[i] ^= 1;
1814    
1815      {
1816        int start_point = PT;
1817        int pos = PT;
1818        int pos_byte = PT_BYTE;
1819        unsigned char *p = PT_ADDR, *endp, *stop;
1820    
1821        if (forwardp)
1822          {
1823            endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
1824            stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;
1825          }
1826        else
1827          {
1828            endp = CHAR_POS_ADDR (XINT (lim));
1829            stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;
1830        }        }
1831    
1832  #if 0 /* Not needed now that a position in mid-character      immediate_quit = 1;
1833           cannot be specified in Lisp.  */      SETUP_SYNTAX_TABLE (pos, forwardp ? 1 : -1);
1834      if (multibyte      if (forwardp)
1835          /* INC_POS or DEC_POS might have moved POS over LIM.  */        {
1836          && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))          if (multibyte)
1837        pos = XINT (lim);            {
1838  #endif              while (1)
1839                  {
1840                    int nbytes;
1841    
1842                    if (p >= stop)
1843                      {
1844                        if (p >= endp)
1845                          break;
1846                        p = GAP_END_ADDR;
1847                        stop = endp;
1848                      }
1849                    c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
1850                    if (! fastmap[(int) SYNTAX (c)])
1851                      break;
1852                    p += nbytes, pos++, pos_byte += nbytes;
1853                    UPDATE_SYNTAX_TABLE_FORWARD (pos);
1854                  }
1855              }
1856            else
1857              {
1858                while (1)
1859                  {
1860                    if (p >= stop)
1861                      {
1862                        if (p >= endp)
1863                          break;
1864                        p = GAP_END_ADDR;
1865                        stop = endp;
1866                      }
1867                    if (! fastmap[(int) SYNTAX (*p)])
1868                      break;
1869                    p++, pos++, pos_byte++;
1870                    UPDATE_SYNTAX_TABLE_FORWARD (pos);
1871                  }
1872              }
1873          }
1874        else
1875          {
1876            if (multibyte)
1877              {
1878                while (1)
1879                  {
1880                    unsigned char *prev_p;
1881    
1882      if (! multibyte)                  if (p <= stop)
1883        pos_byte = pos;                    {
1884                        if (p <= endp)
1885                          break;
1886                        p = GPT_ADDR;
1887                        stop = endp;
1888                      }
1889                    prev_p = p;
1890                    while (--p >= stop && ! CHAR_HEAD_P (*p));
1891                    c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
1892                    if (! fastmap[(int) SYNTAX (c)])
1893                      break;
1894                    pos--, pos_byte -= prev_p - p;
1895                    UPDATE_SYNTAX_TABLE_BACKWARD (pos);
1896                  }
1897              }
1898            else
1899              {
1900                while (1)
1901                  {
1902                    if (p <= stop)
1903                      {
1904                        if (p <= endp)
1905                          break;
1906                        p = GPT_ADDR;
1907                        stop = endp;
1908                      }
1909                    if (! fastmap[(int) SYNTAX (p[-1])])
1910                      break;
1911                    p--, pos--, pos_byte--;
1912                    UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
1913                  }
1914              }
1915          }
1916    
1917      SET_PT_BOTH (pos, pos_byte);      SET_PT_BOTH (pos, pos_byte);
1918      immediate_quit = 0;      immediate_quit = 0;
# Line 1788  forw_comment (from, from_byte, stop, nes Line 1972  forw_comment (from, from_byte, stop, nes
1972            *bytepos_ptr = from_byte;            *bytepos_ptr = from_byte;
1973            return 0;            return 0;
1974          }          }
1975        c = FETCH_CHAR (from_byte);        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
1976        syntax = SYNTAX_WITH_FLAGS (c);        syntax = SYNTAX_WITH_FLAGS (c);
1977        code = syntax & 0xff;        code = syntax & 0xff;
1978        if (code == Sendcomment        if (code == Sendcomment
# Line 1818  forw_comment (from, from_byte, stop, nes Line 2002  forw_comment (from, from_byte, stop, nes
2002      forw_incomment:      forw_incomment:
2003        if (from < stop && SYNTAX_FLAGS_COMEND_FIRST (syntax)        if (from < stop && SYNTAX_FLAGS_COMEND_FIRST (syntax)
2004            && SYNTAX_FLAGS_COMMENT_STYLE (syntax) == style            && SYNTAX_FLAGS_COMMENT_STYLE (syntax) == style
2005            && (c1 = FETCH_CHAR (from_byte),            && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2006                SYNTAX_COMEND_SECOND (c1))                SYNTAX_COMEND_SECOND (c1))
2007            && ((SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||            && ((SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
2008                 SYNTAX_COMMENT_NESTED (c1)) ? nesting > 0 : nesting < 0))                 SYNTAX_COMMENT_NESTED (c1)) ? nesting > 0 : nesting < 0))
# Line 1837  forw_comment (from, from_byte, stop, nes Line 2021  forw_comment (from, from_byte, stop, nes
2021        if (nesting > 0        if (nesting > 0
2022            && from < stop            && from < stop
2023            && SYNTAX_FLAGS_COMSTART_FIRST (syntax)            && SYNTAX_FLAGS_COMSTART_FIRST (syntax)
2024            && (c1 = FETCH_CHAR (from_byte),            && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2025                SYNTAX_COMMENT_STYLE (c1) == style                SYNTAX_COMMENT_STYLE (c1) == style
2026                && SYNTAX_COMSTART_SECOND (c1))                && SYNTAX_COMSTART_SECOND (c1))
2027            && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||            && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
# Line 1901  between them, return t; otherwise return Line 2085  between them, return t; otherwise return
2085                immediate_quit = 0;                immediate_quit = 0;
2086                return Qnil;                return Qnil;
2087              }              }
2088            c = FETCH_CHAR (from_byte);            c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2089            code = SYNTAX (c);            code = SYNTAX (c);
2090            comstart_first = SYNTAX_COMSTART_FIRST (c);            comstart_first = SYNTAX_COMSTART_FIRST (c);
2091            comnested = SYNTAX_COMMENT_NESTED (c);            comnested = SYNTAX_COMMENT_NESTED (c);
# Line 1909  between them, return t; otherwise return Line 2093  between them, return t; otherwise return
2093            INC_BOTH (from, from_byte);            INC_BOTH (from, from_byte);
2094            UPDATE_SYNTAX_TABLE_FORWARD (from);            UPDATE_SYNTAX_TABLE_FORWARD (from);
2095            if (from < stop && comstart_first            if (from < stop && comstart_first
2096                && (c1 = FETCH_CHAR (from_byte),                && (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2097                    SYNTAX_COMSTART_SECOND (c1)))                    SYNTAX_COMSTART_SECOND (c1)))
2098              {              {
2099                /* We have encountered a comment start sequence and we                /* We have encountered a comment start sequence and we
# Line 1967  between them, return t; otherwise return Line 2151  between them, return t; otherwise return
2151            DEC_BOTH (from, from_byte);            DEC_BOTH (from, from_byte);
2152            /* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from).  */            /* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from).  */
2153            quoted = char_quoted (from, from_byte);            quoted = char_quoted (from, from_byte);
2154            c = FETCH_CHAR (from_byte);            c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2155            code = SYNTAX (c);            code = SYNTAX (c);
2156            comstyle = 0;            comstyle = 0;
2157            comnested = SYNTAX_COMMENT_NESTED (c);            comnested = SYNTAX_COMMENT_NESTED (c);
# Line 1984  between them, return t; otherwise return Line 2168  between them, return t; otherwise return
2168                code = Sendcomment;                code = Sendcomment;
2169                /* Calling char_quoted, above, set up global syntax position                /* Calling char_quoted, above, set up global syntax position
2170                   at the new value of FROM.  */                   at the new value of FROM.  */
2171                c1 = FETCH_CHAR (from_byte);                c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2172                comstyle = SYNTAX_COMMENT_STYLE (c1);                comstyle = SYNTAX_COMMENT_STYLE (c1);
2173                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
2174              }              }
# Line 2000  between them, return t; otherwise return Line 2184  between them, return t; otherwise return
2184                    if (from == stop)                    if (from == stop)
2185                      break;                      break;
2186                    UPDATE_SYNTAX_TABLE_BACKWARD (from);                    UPDATE_SYNTAX_TABLE_BACKWARD (from);
2187                    c = FETCH_CHAR (from_byte);                    c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2188                    if (SYNTAX (c) == Scomment_fence                    if (SYNTAX (c) == Scomment_fence
2189                        && !char_quoted (from, from_byte))                        && !char_quoted (from, from_byte))
2190                      {                      {
# Line 2061  between them, return t; otherwise return Line 2245  between them, return t; otherwise return
2245    return Qt;    return Qt;
2246  }  }
2247    
2248  /* Return syntax code of character C if C is a single byte character  /* Return syntax code of character C if C is an ASCII character
2249     or `multibyte_symbol_p' is zero.  Otherwise, return Ssymbol.  */     or `multibyte_symbol_p' is zero.  Otherwise, return Ssymbol.  */
2250    
2251  #define SYNTAX_WITH_MULTIBYTE_CHECK(c)                  \  #define SYNTAX_WITH_MULTIBYTE_CHECK(c)          \
2252    ((SINGLE_BYTE_CHAR_P (c) || !multibyte_symbol_p)      \    ((ASCII_CHAR_P (c) || !multibyte_symbol_p)    \
2253     ? SYNTAX (c) : Ssymbol)     ? SYNTAX (c) : Ssymbol)
2254    
2255  static Lisp_Object  static Lisp_Object
# Line 2108  scan_lists (from, count, depth, sexpflag Line 2292  scan_lists (from, count, depth, sexpflag
2292          {          {
2293            int comstart_first, prefix;            int comstart_first, prefix;
2294            UPDATE_SYNTAX_TABLE_FORWARD (from);            UPDATE_SYNTAX_TABLE_FORWARD (from);
2295            c = FETCH_CHAR (from_byte);            c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2296            code = SYNTAX_WITH_MULTIBYTE_CHECK (c);            code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
2297            comstart_first = SYNTAX_COMSTART_FIRST (c);            comstart_first = SYNTAX_COMSTART_FIRST (c);
2298            comnested = SYNTAX_COMMENT_NESTED (c);            comnested = SYNTAX_COMMENT_NESTED (c);
# Line 2119  scan_lists (from, count, depth, sexpflag Line 2303  scan_lists (from, count, depth, sexpflag
2303            INC_BOTH (from, from_byte);            INC_BOTH (from, from_byte);
2304            UPDATE_SYNTAX_TABLE_FORWARD (from);            UPDATE_SYNTAX_TABLE_FORWARD (from);
2305            if (from < stop && comstart_first            if (from < stop && comstart_first
2306                && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte))                && SYNTAX_COMSTART_SECOND (FETCH_CHAR_AS_MULTIBYTE (from_byte))
2307                && parse_sexp_ignore_comments)                && parse_sexp_ignore_comments)
2308              {              {
2309                /* we have encountered a comment start sequence and we                /* we have encountered a comment start sequence and we
# Line 2128  scan_lists (from, count, depth, sexpflag Line 2312  scan_lists (from, count, depth, sexpflag
2312                   only a comment end of the same style actually ends                   only a comment end of the same style actually ends
2313                   the comment section */                   the comment section */
2314                code = Scomment;                code = Scomment;
2315                c1 = FETCH_CHAR (from_byte);                c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2316                comstyle = SYNTAX_COMMENT_STYLE (c1);                comstyle = SYNTAX_COMMENT_STYLE (c1);
2317                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
2318                INC_BOTH (from, from_byte);                INC_BOTH (from, from_byte);
# Line 2154  scan_lists (from, count, depth, sexpflag Line 2338  scan_lists (from, count, depth, sexpflag
2338                    UPDATE_SYNTAX_TABLE_FORWARD (from);                    UPDATE_SYNTAX_TABLE_FORWARD (from);
2339    
2340                    /* Some compilers can't handle this inside the switch.  */                    /* Some compilers can't handle this inside the switch.  */
2341                    c = FETCH_CHAR (from_byte);                    c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2342                    temp = SYNTAX_WITH_MULTIBYTE_CHECK (c);                    temp = SYNTAX_WITH_MULTIBYTE_CHECK (c);
2343                    switch (temp)                    switch (temp)
2344                      {                      {
# Line 2197  scan_lists (from, count, depth, sexpflag Line 2381  scan_lists (from, count, depth, sexpflag
2381              case Smath:              case Smath:
2382                if (!sexpflag)                if (!sexpflag)
2383                  break;                  break;
2384                if (from != stop && c == FETCH_CHAR (from_byte))                if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (from_byte))
2385                  {                  {
2386                    INC_BOTH (from, from_byte);                    INC_BOTH (from, from_byte);
2387                  }                  }
# Line 2225  scan_lists (from, count, depth, sexpflag Line 2409  scan_lists (from, count, depth, sexpflag
2409              case Sstring:              case Sstring:
2410              case Sstring_fence:              case Sstring_fence:
2411                temp_pos = dec_bytepos (from_byte);                temp_pos = dec_bytepos (from_byte);
2412                stringterm = FETCH_CHAR (temp_pos);                stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2413                while (1)                while (1)
2414                  {                  {
2415                    if (from >= stop) goto lose;                    if (from >= stop) goto lose;
2416                    UPDATE_SYNTAX_TABLE_FORWARD (from);                    UPDATE_SYNTAX_TABLE_FORWARD (from);
2417                    c = FETCH_CHAR (from_byte);                    c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2418                    if (code == Sstring                    if (code == Sstring
2419                        ? (c == stringterm                        ? (c == stringterm
2420                           && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)                           && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
# Line 2273  scan_lists (from, count, depth, sexpflag Line 2457  scan_lists (from, count, depth, sexpflag
2457          {          {
2458            DEC_BOTH (from, from_byte);            DEC_BOTH (from, from_byte);
2459            UPDATE_SYNTAX_TABLE_BACKWARD (from);            UPDATE_SYNTAX_TABLE_BACKWARD (from);
2460            c = FETCH_CHAR (from_byte);            c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2461            code = SYNTAX_WITH_MULTIBYTE_CHECK (c);            code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
2462            if (depth == min_depth)            if (depth == min_depth)
2463              last_good = from;              last_good = from;
# Line 2291  scan_lists (from, count, depth, sexpflag Line 2475  scan_lists (from, count, depth, sexpflag
2475                DEC_BOTH (from, from_byte);                DEC_BOTH (from, from_byte);
2476                UPDATE_SYNTAX_TABLE_BACKWARD (from);                UPDATE_SYNTAX_TABLE_BACKWARD (from);
2477                code = Sendcomment;                code = Sendcomment;
2478                c1 = FETCH_CHAR (from_byte);                c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2479                comstyle = SYNTAX_COMMENT_STYLE (c1);                comstyle = SYNTAX_COMMENT_STYLE (c1);
2480                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);                comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
2481              }              }
# Line 2324  scan_lists (from, count, depth, sexpflag Line 2508  scan_lists (from, count, depth, sexpflag
2508                    else                    else
2509                      temp_pos--;                      temp_pos--;
2510                    UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);                    UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2511                    c1 = FETCH_CHAR (temp_pos);                    c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2512                    temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);                    temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
2513                    /* Don't allow comment-end to be quoted.  */                    /* Don't allow comment-end to be quoted.  */
2514                    if (temp_code == Sendcomment)                    if (temp_code == Sendcomment)
# Line 2336  scan_lists (from, count, depth, sexpflag Line 2520  scan_lists (from, count, depth, sexpflag
2520                        temp_pos = dec_bytepos (temp_pos);                        temp_pos = dec_bytepos (temp_pos);
2521                        UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);                        UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2522                      }                      }
2523                    c1 = FETCH_CHAR (temp_pos);                    c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2524                    temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);                    temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
2525                    if (! (quoted || temp_code == Sword                    if (! (quoted || temp_code == Sword
2526                           || temp_code == Ssymbol                           || temp_code == Ssymbol
# Line 2351  scan_lists (from, count, depth, sexpflag Line 2535  scan_lists (from, count, depth, sexpflag
2535                  break;                  break;
2536                temp_pos = dec_bytepos (from_byte);                temp_pos = dec_bytepos (from_byte);
2537                UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);                UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2538                if (from != stop && c == FETCH_CHAR (temp_pos))                if (from != stop && c == FETCH_CHAR_AS_MULTIBYTE (temp_pos))
2539                  DEC_BOTH (from, from_byte);                  DEC_BOTH (from, from_byte);
2540                if (mathexit)                if (mathexit)
2541                  {                  {
# Line 2397  scan_lists (from, count, depth, sexpflag Line 2581  scan_lists (from, count, depth, sexpflag
2581                    if (from == stop) goto lose;                    if (from == stop) goto lose;
2582                    UPDATE_SYNTAX_TABLE_BACKWARD (from);                    UPDATE_SYNTAX_TABLE_BACKWARD (from);
2583                    if (!char_quoted (from, from_byte)                    if (!char_quoted (from, from_byte)
2584                        && (c = FETCH_CHAR (from_byte),                        && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2585                            SYNTAX_WITH_MULTIBYTE_CHECK (c) == code))                            SYNTAX_WITH_MULTIBYTE_CHECK (c) == code))
2586                      break;                      break;
2587                  }                  }
# Line 2405  scan_lists (from, count, depth, sexpflag Line 2589  scan_lists (from, count, depth, sexpflag
2589                break;                break;
2590    
2591              case Sstring:              case Sstring:
2592                stringterm = FETCH_CHAR (from_byte);                stringterm = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2593                while (1)                while (1)
2594                  {                  {
2595                    if (from == stop) goto lose;                    if (from == stop) goto lose;
# Line 2416  scan_lists (from, count, depth, sexpflag Line 2600  scan_lists (from, count, depth, sexpflag
2600                      temp_pos--;                      temp_pos--;
2601                    UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);                    UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2602                    if (!char_quoted (from - 1, temp_pos)                    if (!char_quoted (from - 1, temp_pos)
2603                        && stringterm == (c = FETCH_CHAR (temp_pos))                        && stringterm == (c = FETCH_CHAR_AS_MULTIBYTE (temp_pos))
2604                        && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)                        && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
2605                      break;                      break;
2606                    DEC_BOTH (from, from_byte);                    DEC_BOTH (from, from_byte);
# Line 2524  This includes chars with "quote" or "pre Line 2708  This includes chars with "quote" or "pre
2708    
2709    while (!char_quoted (pos, pos_byte)    while (!char_quoted (pos, pos_byte)
2710           /* Previous statement updates syntax table.  */           /* Previous statement updates syntax table.  */
2711           && ((c = FETCH_CHAR (pos_byte), SYNTAX (c) == Squote)           && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote)
2712               || SYNTAX_PREFIX (c)))               || SYNTAX_PREFIX (c)))
2713      {      {
2714        opoint = pos;        opoint = pos;
# Line 2552  scan_sexps_forward (stateptr, from, from Line 2736  scan_sexps_forward (stateptr, from, from
2736                      stopbefore, oldstate, commentstop)                      stopbefore, oldstate, commentstop)
2737       struct lisp_parse_state *stateptr;       struct lisp_parse_state *stateptr;
2738       register int from;       register int from;
2739       int end, targetdepth, stopbefore, from_byte;       int from_byte;
2740         int end, targetdepth, stopbefore;
2741       Lisp_Object oldstate;       Lisp_Object oldstate;
2742       int commentstop;       int commentstop;
2743  {  {
# Line 2590  scan_sexps_forward (stateptr, from, from Line 2775  scan_sexps_forward (stateptr, from, from
2775  do { prev_from = from;                          \  do { prev_from = from;                          \
2776       prev_from_byte = from_byte;                \       prev_from_byte = from_byte;                \
2777       prev_from_syntax                           \       prev_from_syntax                           \
2778         = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); \         = SYNTAX_WITH_FLAGS (FETCH_CHAR_AS_MULTIBYTE (prev_from_byte)); \
2779       INC_BOTH (from, from_byte);                \       INC_BOTH (from, from_byte);                \
2780       if (from < end)                            \       if (from < end)                            \
2781         UPDATE_SYNTAX_TABLE_FORWARD (from);      \         UPDATE_SYNTAX_TABLE_FORWARD (from);      \
# Line 2706  do { prev_from = from;                         \ Line 2891  do { prev_from = from;                         \
2891          }          }
2892       else if (from < end)       else if (from < end)
2893          if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax))          if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax))
2894            if (c1 = FETCH_CHAR (from_byte),            if (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2895                SYNTAX_COMSTART_SECOND (c1))                SYNTAX_COMSTART_SECOND (c1))
2896              /* Duplicate code to avoid a complex if-expression              /* Duplicate code to avoid a complex if-expression
2897                 which causes trouble for the SGI compiler.  */                 which causes trouble for the SGI compiler.  */
# Line 2744  do { prev_from = from;                         \ Line 2929  do { prev_from = from;                         \
2929            while (from < end)            while (from < end)
2930              {              {
2931                /* Some compilers can't handle this inside the switch.  */                /* Some compilers can't handle this inside the switch.  */
2932                temp = SYNTAX (FETCH_CHAR (from_byte));                temp = SYNTAX (FETCH_CHAR_AS_MULTIBYTE (from_byte));
2933                switch (temp)                switch (temp)
2934                  {                  {
2935                  case Scharquote:                  case Scharquote:
# Line 2817  do { prev_from = from;                         \ Line 3002  do { prev_from = from;                         \
3002            if (stopbefore) goto stop;  /* this arg means stop at sexp start */            if (stopbefore) goto stop;  /* this arg means stop at sexp start */
3003            curlevel->last = prev_from;            curlevel->last = prev_from;
3004            state.instring = (code == Sstring            state.instring = (code == Sstring
3005                              ? (FETCH_CHAR (prev_from_byte))                              ? (FETCH_CHAR_AS_MULTIBYTE (prev_from_byte))
3006                              : ST_STRING_STYLE);                              : ST_STRING_STYLE);
3007            if (boundary_stop) goto done;            if (boundary_stop) goto done;
3008          startinstring:          startinstring:
# Line 2829  do { prev_from = from;                         \ Line 3014  do { prev_from = from;                         \
3014                  int c;                  int c;
3015    
3016                  if (from >= end) goto done;                  if (from >= end) goto done;
3017                  c = FETCH_CHAR (from_byte);                  c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3018                  /* Some compilers can't handle this inside the switch.  */                  /* Some compilers can't handle this inside the switch.  */
3019                  temp = SYNTAX (c);                  temp = SYNTAX (c);
3020    
# Line 3041  init_syntax_once () Line 3226  init_syntax_once ()
3226    
3227    /* All multibyte characters have syntax `word' by default.  */    /* All multibyte characters have syntax `word' by default.  */
3228    temp = XVECTOR (Vsyntax_code_object)->contents[(int) Sword];    temp = XVECTOR (Vsyntax_code_object)->contents[(int) Sword];
3229    for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)    char_table_set_range (Vstandard_syntax_table, 0x80, MAX_CHAR, temp);
     XCHAR_TABLE (Vstandard_syntax_table)->contents[i] = temp;  
3230  }  }
3231    
3232  void  void
# Line 3082  See the info node `(elisp)Syntax Propert Line 3266  See the info node `(elisp)Syntax Propert
3266                 doc: /* *Non-nil means an open paren in column 0 denotes the start of a defun.  */);                 doc: /* *Non-nil means an open paren in column 0 denotes the start of a defun.  */);
3267    open_paren_in_column_0_is_defun_start = 1;    open_paren_in_column_0_is_defun_start = 1;
3268    
3269    
3270      DEFVAR_LISP ("find-word-boundary-function-table",
3271                   &Vfind_word_boundary_function_table,
3272                   doc: /*
3273    Char table of functions to search for the word boundary.
3274    Each function is called with two arguments; POS and LIMIT.
3275    POS and LIMIT are character positions in the current buffer.
3276    
3277    If POS is less than LIMIT, POS is at the first character of a word,
3278    and the return value of a function is a position after the last
3279    character of that word.
3280    
3281    If POS is not less than LIMIT, POS is at the last character of a word,
3282    and the return value of a function is a position at the first
3283    character of that word.
3284    
3285    In both cases, LIMIT bounds the search. */);
3286      Vfind_word_boundary_function_table = Fmake_char_table (Qnil, Qnil);
3287    
3288    defsubr (&Ssyntax_table_p);    defsubr (&Ssyntax_table_p);
3289    defsubr (&Ssyntax_table);    defsubr (&Ssyntax_table);
3290    defsubr (&Sstandard_syntax_table);    defsubr (&Sstandard_syntax_table);

Legend:
Removed from v.1.166  
changed lines
  Added in v.1.166.4.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26