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 |
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. */ |
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 |
|
|
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; |
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. |
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, |
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, |
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]; |
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); |
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) |
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) |
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; |
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 |
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 |
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 |
} |
} |
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. */ |
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 |
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 |
} |
} |
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. |
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 |
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 |
|
|
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); \ |
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. */ |
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: |