/[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.4.4 by handa, Fri Apr 16 12:50:49 2004 UTC revision 1.166.4.5 by miles, Mon Jun 28 07:29:24 2004 UTC
# Line 26  Boston, MA 02111-1307, USA.  */ Line 26  Boston, MA 02111-1307, USA.  */
26  #include "buffer.h"  #include "buffer.h"
27  #include "character.h"  #include "character.h"
28  #include "keymap.h"  #include "keymap.h"
29    #include "regex.h"
30    
31  /* Make syntax table lookup grant data in gl_state.  */  /* Make syntax table lookup grant data in gl_state.  */
32  #define SYNTAX_ENTRY_VIA_PROPERTY  #define SYNTAX_ENTRY_VIA_PROPERTY
# Line 97  static int find_start_modiff; Line 98  static int find_start_modiff;
98  static int find_defun_start P_ ((int, int));  static int find_defun_start P_ ((int, int));
99  static int back_comment P_ ((int, int, int, int, int, int *, int *));  static int back_comment P_ ((int, int, int, int, int, int *, int *));
100  static int char_quoted P_ ((int, int));  static int char_quoted P_ ((int, int));
101  static Lisp_Object skip_chars P_ ((int, Lisp_Object, Lisp_Object));  static Lisp_Object skip_chars P_ ((int, Lisp_Object, Lisp_Object, int));
102  static Lisp_Object skip_syntaxes P_ ((int, Lisp_Object, Lisp_Object));  static Lisp_Object skip_syntaxes P_ ((int, Lisp_Object, Lisp_Object));
103  static Lisp_Object scan_lists P_ ((int, int, int, int));  static Lisp_Object scan_lists P_ ((int, int, int, int));
104  static void scan_sexps_forward P_ ((struct lisp_parse_state *,  static void scan_sexps_forward P_ ((struct lisp_parse_state *,
105                                      int, int, int, int,                                      int, int, int, int,
106                                      int, Lisp_Object, int));                                      int, Lisp_Object, int));
107    static int in_classes P_ ((int, Lisp_Object));
108    
109    
110  struct gl_state_s gl_state;             /* Global state of syntax parser.  */  struct gl_state_s gl_state;             /* Global state of syntax parser.  */
# Line 293  char_quoted (charpos, bytepos) Line 295  char_quoted (charpos, bytepos)
295    
296    while (bytepos >= beg)    while (bytepos >= beg)
297      {      {
298          int c;
299    
300        UPDATE_SYNTAX_TABLE_BACKWARD (charpos);        UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
301        code = SYNTAX (FETCH_CHAR_AS_MULTIBYTE (bytepos));        c = FETCH_CHAR_AS_MULTIBYTE (bytepos);
302          code = SYNTAX (c);
303        if (! (code == Scharquote || code == Sescape))        if (! (code == Scharquote || code == Sescape))
304          break;          break;
305    
# Line 381  find_defun_start (pos, pos_byte) Line 386  find_defun_start (pos, pos_byte)
386    gl_state.use_global = 0;    gl_state.use_global = 0;
387    while (PT > BEGV)    while (PT > BEGV)
388      {      {
389          int c;
390    
391        /* Open-paren at start of line means we may have found our        /* Open-paren at start of line means we may have found our
392           defun-start.  */           defun-start.  */
393        if (SYNTAX (FETCH_CHAR_AS_MULTIBYTE (PT_BYTE)) == Sopen)        c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
394          if (SYNTAX (c) == Sopen)
395          {          {
396            SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */            SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */
397            if (SYNTAX (FETCH_CHAR_AS_MULTIBYTE (PT_BYTE)) == Sopen)            c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
398              if (SYNTAX (c) == Sopen)
399              break;              break;
400            /* Now fallback to the default value.  */            /* Now fallback to the default value.  */
401            gl_state.current_syntax_table = current_buffer->syntax_table;            gl_state.current_syntax_table = current_buffer->syntax_table;
# Line 955  text property.  */) Line 964  text property.  */)
964  DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,  DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
965    "cSet syntax for character: \nsSet syntax for %s to: ",    "cSet syntax for character: \nsSet syntax for %s to: ",
966         doc: /* Set syntax for character CHAR according to string NEWENTRY.         doc: /* Set syntax for character CHAR according to string NEWENTRY.
967  The syntax is changed only for table SYNTAX_TABLE, which defaults to  The syntax is changed only for table SYNTAX-TABLE, which defaults to
968   the current buffer's syntax table.   the current buffer's syntax table.
969  CHAR may be a cons (MIN . MAX), in which case, syntaxes of all characters  CHAR may be a cons (MIN . MAX), in which case, syntaxes of all characters
970  in the range MIN and MAX are changed.  in the range MIN and MAX are changed.
# Line 1339  except that `]' is never special and `\\ Line 1348  except that `]' is never special and `\\
1348   (but not as the end of a range; quoting is never needed there).   (but not as the end of a range; quoting is never needed there).
1349  Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.  Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.
1350  With arg "^a-zA-Z", skips nonletters stopping before first letter.  With arg "^a-zA-Z", skips nonletters stopping before first letter.
1351  Returns the distance traveled, either zero or positive.  Char classes, e.g. `[:alpha:]', are supported.
1352  Note that char classes, e.g. `[:alpha:]', are not currently supported;  
1353  they will be treated as literals.  */)  Returns the distance traveled, either zero or positive.  */)
1354       (string, lim)       (string, lim)
1355       Lisp_Object string, lim;       Lisp_Object string, lim;
1356  {  {
1357    return skip_chars (1, string, lim);    return skip_chars (1, string, lim, 1);
1358  }  }
1359    
1360  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 1355  Returns the distance traveled, either ze Line 1364  Returns the distance traveled, either ze
1364       (string, lim)       (string, lim)
1365       Lisp_Object string, lim;       Lisp_Object string, lim;
1366  {  {
1367    return skip_chars (0, string, lim);    return skip_chars (0, string, lim, 1);
1368  }  }
1369    
1370  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 1383  This function returns the distance trave Line 1392  This function returns the distance trave
1392  }  }
1393    
1394  static Lisp_Object  static Lisp_Object
1395  skip_chars (forwardp, string, lim)  skip_chars (forwardp, string, lim, handle_iso_classes)
1396       int forwardp;       int forwardp;
1397       Lisp_Object string, lim;       Lisp_Object string, lim;
1398         int handle_iso_classes;
1399  {  {
1400    register unsigned int c;    register unsigned int c;
1401    unsigned char fastmap[0400];    unsigned char fastmap[0400];
# Line 1403  skip_chars (forwardp, string, lim) Line 1413  skip_chars (forwardp, string, lim)
1413    int size_byte;    int size_byte;
1414    const unsigned char *str;    const unsigned char *str;
1415    int len;    int len;
1416      Lisp_Object iso_classes;
1417    
1418    CHECK_STRING (string);    CHECK_STRING (string);
1419      iso_classes = Qnil;
1420    
1421    if (NILP (lim))    if (NILP (lim))
1422      XSETINT (lim, forwardp ? ZV : BEGV);      XSETINT (lim, forwardp ? ZV : BEGV);
# Line 1448  skip_chars (forwardp, string, lim) Line 1460  skip_chars (forwardp, string, lim)
1460          {          {
1461            c = str[i_byte++];            c = str[i_byte++];
1462    
1463              if (handle_iso_classes && c == '['
1464                  && i_byte < size_byte
1465                  && str[i_byte] == ':')
1466                {
1467                  const unsigned char *class_beg = str + i_byte + 1;
1468                  const unsigned char *class_end = class_beg;
1469                  const unsigned char *class_limit = str + size_byte - 2;
1470                  /* Leave room for the null.        */
1471                  unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1];
1472                  re_wctype_t cc;
1473    
1474                  if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH)
1475                    class_limit = class_beg + CHAR_CLASS_MAX_LENGTH;
1476    
1477                  while (class_end < class_limit
1478                         && *class_end >= 'a' && *class_end <= 'z')
1479                    class_end++;
1480    
1481                  if (class_end == class_beg
1482                      || *class_end != ':' || class_end[1] != ']')
1483                    goto not_a_class_name;
1484    
1485                  bcopy (class_beg, class_name, class_end - class_beg);
1486                  class_name[class_end - class_beg] = 0;
1487    
1488                  cc = re_wctype (class_name);
1489                  if (cc == 0)
1490                    error ("Invalid ISO C character class");
1491    
1492                  iso_classes = Fcons (make_number (cc), iso_classes);
1493    
1494                  i_byte = class_end + 2 - str;
1495                  continue;
1496                }
1497    
1498            not_a_class_name:
1499            if (c == '\\')            if (c == '\\')
1500              {              {
1501                if (i_byte == size_byte)                if (i_byte == size_byte)
# Line 1534  skip_chars (forwardp, string, lim) Line 1582  skip_chars (forwardp, string, lim)
1582            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);
1583            i_byte += len;            i_byte += len;
1584    
1585              if (handle_iso_classes && c == '['
1586                  && i_byte < size_byte
1587                  && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':')
1588                {
1589                  const unsigned char *class_beg = str + i_byte + 1;
1590                  const unsigned char *class_end = class_beg;
1591                  const unsigned char *class_limit = str + size_byte - 2;
1592                  /* Leave room for the null.        */
1593                  unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1];
1594                  re_wctype_t cc;
1595    
1596                  if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH)
1597                    class_limit = class_beg + CHAR_CLASS_MAX_LENGTH;
1598    
1599                  while (class_end < class_limit
1600                         && *class_end >= 'a' && *class_end <= 'z')
1601                    class_end++;
1602    
1603                  if (class_end == class_beg
1604                      || *class_end != ':' || class_end[1] != ']')
1605                    goto not_a_class_name_multibyte;
1606    
1607                  bcopy (class_beg, class_name, class_end - class_beg);
1608                  class_name[class_end - class_beg] = 0;
1609    
1610                  cc = re_wctype (class_name);
1611                  if (cc == 0)
1612                    error ("Invalid ISO C character class");
1613    
1614                  iso_classes = Fcons (make_number (cc), iso_classes);
1615    
1616                  i_byte = class_end + 2 - str;
1617                  continue;
1618                }
1619    
1620            not_a_class_name_multibyte:
1621            if (c == '\\')            if (c == '\\')
1622              {              {
1623                if (i_byte == size_byte)                if (i_byte == size_byte)
# Line 1643  skip_chars (forwardp, string, lim) Line 1727  skip_chars (forwardp, string, lim)
1727    
1728      if (forwardp)      if (forwardp)
1729        {        {
1730          endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));          endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
1731          stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;          stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;
1732        }        }
1733      else      else
1734        {        {
1735          endp = CHAR_POS_ADDR (XINT (lim));          endp = CHAR_POS_ADDR (XINT (lim));
1736          stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;          stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;
1737        }        }
1738    
1739      immediate_quit = 1;      immediate_quit = 1;
# Line 1667  skip_chars (forwardp, string, lim) Line 1751  skip_chars (forwardp, string, lim)
1751                    p = GAP_END_ADDR;                    p = GAP_END_ADDR;
1752                    stop = endp;                    stop = endp;
1753                  }                  }
1754                  c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
1755                  if (! NILP (iso_classes) && in_classes (c, iso_classes))
1756                    {
1757                      if (negate)
1758                        break;
1759                      else
1760                        goto fwd_ok;
1761                    }
1762    
1763                if (! fastmap[*p])                if (! fastmap[*p])
1764                  break;                  break;
               c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);  
1765                if (! ASCII_CHAR_P (c))                if (! ASCII_CHAR_P (c))
1766                  {                  {
1767                    /* As we are looking at a multibyte character, we                    /* As we are looking at a multibyte character, we
# Line 1686  skip_chars (forwardp, string, lim) Line 1778  skip_chars (forwardp, string, lim)
1778                    if (!(negate ^ (i < n_char_ranges)))                    if (!(negate ^ (i < n_char_ranges)))
1779                      break;                      break;
1780                  }                  }
1781                fwd_ok:
1782                p += nbytes, pos++, pos_byte += nbytes;                p += nbytes, pos++, pos_byte += nbytes;
1783              }              }
1784          else          else
# Line 1698  skip_chars (forwardp, string, lim) Line 1791  skip_chars (forwardp, string, lim)
1791                    p = GAP_END_ADDR;                    p = GAP_END_ADDR;
1792                    stop = endp;                    stop = endp;
1793                  }                  }
1794    
1795                  if (!NILP (iso_classes) && in_classes (*p, iso_classes))
1796                    {
1797                      if (negate)
1798                        break;
1799                      else
1800                        goto fwd_unibyte_ok;
1801                    }
1802    
1803                if (!fastmap[*p])                if (!fastmap[*p])
1804                  break;                  break;
1805                fwd_unibyte_ok:
1806                p++, pos++, pos_byte++;                p++, pos++, pos_byte++;
1807              }              }
1808        }        }
# Line 1719  skip_chars (forwardp, string, lim) Line 1822  skip_chars (forwardp, string, lim)
1822                  }                  }
1823                prev_p = p;                prev_p = p;
1824                while (--p >= stop && ! CHAR_HEAD_P (*p));                while (--p >= stop && ! CHAR_HEAD_P (*p));
1825                  c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
1826    
1827                  if (! NILP (iso_classes) && in_classes (c, iso_classes))
1828                    {
1829                      if (negate)
1830                        break;
1831                      else
1832                        goto back_ok;
1833                    }
1834    
1835                if (! fastmap[*p])                if (! fastmap[*p])
1836                  break;                  break;
               c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);  
1837                if (! ASCII_CHAR_P (c))                if (! ASCII_CHAR_P (c))
1838                  {                  {
1839                    /* See the comment in the previous similar code.  */                    /* See the comment in the previous similar code.  */
# Line 1731  skip_chars (forwardp, string, lim) Line 1843  skip_chars (forwardp, string, lim)
1843                    if (!(negate ^ (i < n_char_ranges)))                    if (!(negate ^ (i < n_char_ranges)))
1844                      break;                      break;
1845                  }                  }
1846                back_ok:
1847                pos--, pos_byte -= prev_p - p;                pos--, pos_byte -= prev_p - p;
1848              }              }
1849          else          else
# Line 1743  skip_chars (forwardp, string, lim) Line 1856  skip_chars (forwardp, string, lim)
1856                    p = GPT_ADDR;                    p = GPT_ADDR;
1857                    stop = endp;                    stop = endp;
1858                  }                  }
1859    
1860                  if (! NILP (iso_classes) && in_classes (p[-1], iso_classes))
1861                    {
1862                      if (negate)
1863                        break;
1864                      else
1865                        goto back_unibyte_ok;
1866                    }
1867    
1868                if (!fastmap[p[-1]])                if (!fastmap[p[-1]])
1869                  break;                  break;
1870                back_unibyte_ok:
1871                p--, pos--, pos_byte--;                p--, pos--, pos_byte--;
1872              }              }
1873        }        }
# Line 1927  skip_syntaxes (forwardp, string, lim) Line 2050  skip_syntaxes (forwardp, string, lim)
2050      return make_number (PT - start_point);      return make_number (PT - start_point);
2051    }    }
2052  }  }
2053    
2054    /* Return 1 if character C belongs to one of the ISO classes
2055       in the list ISO_CLASSES.  Each class is represented by an
2056       integer which is its type according to re_wctype.  */
2057    
2058    static int
2059    in_classes (c, iso_classes)
2060         int c;
2061         Lisp_Object iso_classes;
2062    {
2063      int fits_class = 0;
2064    
2065      while (! NILP (iso_classes))
2066        {
2067          Lisp_Object elt;
2068          elt = XCAR (iso_classes);
2069          iso_classes = XCDR (iso_classes);
2070    
2071          if (re_iswctype (c, XFASTINT (elt)))
2072            fits_class = 1;
2073        }
2074    
2075      return fits_class;
2076    }
2077    
2078  /* Jump over a comment, assuming we are at the beginning of one.  /* Jump over a comment, assuming we are at the beginning of one.
2079     FROM is the current position.     FROM is the current position.
# Line 2310  scan_lists (from, count, depth, sexpflag Line 2457  scan_lists (from, count, depth, sexpflag
2457            INC_BOTH (from, from_byte);            INC_BOTH (from, from_byte);
2458            UPDATE_SYNTAX_TABLE_FORWARD (from);            UPDATE_SYNTAX_TABLE_FORWARD (from);
2459            if (from < stop && comstart_first            if (from < stop && comstart_first
2460                && SYNTAX_COMSTART_SECOND (FETCH_CHAR_AS_MULTIBYTE (from_byte))                && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte),
2461                      SYNTAX_COMSTART_SECOND (c))
2462                && parse_sexp_ignore_comments)                && parse_sexp_ignore_comments)
2463              {              {
2464                /* we have encountered a comment start sequence and we                /* we have encountered a comment start sequence and we
# Line 2636  scan_lists (from, count, depth, sexpflag Line 2784  scan_lists (from, count, depth, sexpflag
2784             Fcons (build_string ("Unbalanced parentheses"),             Fcons (build_string ("Unbalanced parentheses"),
2785                    Fcons (make_number (last_good),                    Fcons (make_number (last_good),
2786                           Fcons (make_number (from), Qnil))));                           Fcons (make_number (from), Qnil))));
2787      abort ();
2788    /* NOTREACHED */    /* NOTREACHED */
2789  }  }
2790    
# Line 2776  scan_sexps_forward (stateptr, from, from Line 2924  scan_sexps_forward (stateptr, from, from
2924  #define INC_FROM                                \  #define INC_FROM                                \
2925  do { prev_from = from;                          \  do { prev_from = from;                          \
2926       prev_from_byte = from_byte;                \       prev_from_byte = from_byte;                \
2927       prev_from_syntax                           \       temp = FETCH_CHAR_AS_MULTIBYTE (prev_from_byte);   \
2928         = SYNTAX_WITH_FLAGS (FETCH_CHAR_AS_MULTIBYTE (prev_from_byte)); \       prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
2929       INC_BOTH (from, from_byte);                \       INC_BOTH (from, from_byte);                \
2930       if (from < end)                            \       if (from < end)                            \
2931         UPDATE_SYNTAX_TABLE_FORWARD (from);      \         UPDATE_SYNTAX_TABLE_FORWARD (from);      \
# Line 2852  do { prev_from = from;                         \ Line 3000  do { prev_from = from;                         \
3000    curlevel->last = -1;    curlevel->last = -1;
3001    
3002    SETUP_SYNTAX_TABLE (prev_from, 1);    SETUP_SYNTAX_TABLE (prev_from, 1);
3003    prev_from_syntax = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte));    temp = FETCH_CHAR (prev_from_byte);
3004      prev_from_syntax = SYNTAX_WITH_FLAGS (temp);
3005    UPDATE_SYNTAX_TABLE_FORWARD (from);    UPDATE_SYNTAX_TABLE_FORWARD (from);
3006    
3007    /* Enter the loop at a place appropriate for initial state.  */    /* Enter the loop at a place appropriate for initial state.  */
# Line 2931  do { prev_from = from;                         \ Line 3080  do { prev_from = from;                         \
3080            while (from < end)            while (from < end)
3081              {              {
3082                /* Some compilers can't handle this inside the switch.  */                /* Some compilers can't handle this inside the switch.  */
3083                temp = SYNTAX (FETCH_CHAR_AS_MULTIBYTE (from_byte));                temp = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3084                  temp = SYNTAX (temp);
3085                switch (temp)                switch (temp)
3086                  {                  {
3087                  case Scharquote:                  case Scharquote:

Legend:
Removed from v.1.166.4.4  
changed lines
  Added in v.1.166.4.5

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