26 |
#include "buffer.h" |
#include "buffer.h" |
27 |
#include "charset.h" |
#include "charset.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, int, Lisp_Object, Lisp_Object)); |
static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int)); |
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, |
105 |
int, Lisp_Object, int)); |
int, Lisp_Object, int)); |
106 |
|
static int in_classes P_ ((int, Lisp_Object)); |
107 |
|
|
108 |
|
|
109 |
struct gl_state_s gl_state; /* Global state of syntax parser. */ |
struct gl_state_s gl_state; /* Global state of syntax parser. */ |
1323 |
(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). |
1324 |
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. |
1325 |
With arg "^a-zA-Z", skips nonletters stopping before first letter. |
With arg "^a-zA-Z", skips nonletters stopping before first letter. |
1326 |
Returns the distance traveled, either zero or positive. |
Char classes, e.g. `[:alpha:]', are supported. |
1327 |
Note that char classes, e.g. `[:alpha:]', are not currently supported; |
|
1328 |
they will be treated as literals. */) |
Returns the distance traveled, either zero or positive. */) |
1329 |
(string, lim) |
(string, lim) |
1330 |
Lisp_Object string, lim; |
Lisp_Object string, lim; |
1331 |
{ |
{ |
1332 |
return skip_chars (1, 0, string, lim); |
return skip_chars (1, 0, string, lim, 1); |
1333 |
} |
} |
1334 |
|
|
1335 |
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, |
1339 |
(string, lim) |
(string, lim) |
1340 |
Lisp_Object string, lim; |
Lisp_Object string, lim; |
1341 |
{ |
{ |
1342 |
return skip_chars (0, 0, string, lim); |
return skip_chars (0, 0, string, lim, 1); |
1343 |
} |
} |
1344 |
|
|
1345 |
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, |
1351 |
(syntax, lim) |
(syntax, lim) |
1352 |
Lisp_Object syntax, lim; |
Lisp_Object syntax, lim; |
1353 |
{ |
{ |
1354 |
return skip_chars (1, 1, syntax, lim); |
return skip_chars (1, 1, syntax, lim, 0); |
1355 |
} |
} |
1356 |
|
|
1357 |
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, |
1363 |
(syntax, lim) |
(syntax, lim) |
1364 |
Lisp_Object syntax, lim; |
Lisp_Object syntax, lim; |
1365 |
{ |
{ |
1366 |
return skip_chars (0, 1, syntax, lim); |
return skip_chars (0, 1, syntax, lim, 0); |
1367 |
} |
} |
1368 |
|
|
1369 |
static Lisp_Object |
static Lisp_Object |
1370 |
skip_chars (forwardp, syntaxp, string, lim) |
skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes) |
1371 |
int forwardp, syntaxp; |
int forwardp, syntaxp; |
1372 |
Lisp_Object string, lim; |
Lisp_Object string, lim; |
1373 |
|
int handle_iso_classes; |
1374 |
{ |
{ |
1375 |
register unsigned int c; |
register unsigned int c; |
1376 |
unsigned char fastmap[0400]; |
unsigned char fastmap[0400]; |
1386 |
int size_byte; |
int size_byte; |
1387 |
const unsigned char *str; |
const unsigned char *str; |
1388 |
int len; |
int len; |
1389 |
|
Lisp_Object iso_classes; |
1390 |
|
|
1391 |
CHECK_STRING (string); |
CHECK_STRING (string); |
1392 |
char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2); |
char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2); |
1393 |
string_multibyte = STRING_MULTIBYTE (string); |
string_multibyte = STRING_MULTIBYTE (string); |
1394 |
str = SDATA (string); |
str = SDATA (string); |
1395 |
size_byte = SBYTES (string); |
size_byte = SBYTES (string); |
1396 |
|
iso_classes = Qnil; |
1397 |
|
|
1398 |
/* Adjust the multibyteness of the string to that of the buffer. */ |
/* Adjust the multibyteness of the string to that of the buffer. */ |
1399 |
if (multibyte != string_multibyte) |
if (multibyte != string_multibyte) |
1449 |
fastmap[syntax_spec_code[c & 0377]] = 1; |
fastmap[syntax_spec_code[c & 0377]] = 1; |
1450 |
else |
else |
1451 |
{ |
{ |
1452 |
|
if (handle_iso_classes && c == '[' |
1453 |
|
&& i_byte < size_byte |
1454 |
|
&& STRING_CHAR (str + i_byte, size_byte - i_byte) == ':') |
1455 |
|
{ |
1456 |
|
const unsigned char *class_beg = str + i_byte + 1; |
1457 |
|
const unsigned char *class_end = class_beg; |
1458 |
|
const unsigned char *class_limit = str + size_byte; |
1459 |
|
/* Leave room for the null. */ |
1460 |
|
unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1]; |
1461 |
|
re_wctype_t cc; |
1462 |
|
|
1463 |
|
if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH) |
1464 |
|
class_limit = class_beg + CHAR_CLASS_MAX_LENGTH; |
1465 |
|
|
1466 |
|
while (class_end != class_limit |
1467 |
|
&& ! (*class_end >= 0200 |
1468 |
|
|| *class_end <= 040 |
1469 |
|
|| (*class_end == ':' |
1470 |
|
&& class_end[1] == ']'))) |
1471 |
|
class_end++; |
1472 |
|
|
1473 |
|
if (class_end == class_limit |
1474 |
|
|| *class_end >= 0200 |
1475 |
|
|| *class_end <= 040) |
1476 |
|
error ("Invalid ISO C character class"); |
1477 |
|
|
1478 |
|
bcopy (class_beg, class_name, class_end - class_beg); |
1479 |
|
class_name[class_end - class_beg] = 0; |
1480 |
|
|
1481 |
|
cc = re_wctype (class_name); |
1482 |
|
if (cc == 0) |
1483 |
|
error ("Invalid ISO C character class"); |
1484 |
|
|
1485 |
|
iso_classes = Fcons (make_number (cc), iso_classes); |
1486 |
|
|
1487 |
|
i_byte = class_end + 2 - str; |
1488 |
|
continue; |
1489 |
|
} |
1490 |
|
|
1491 |
if (c == '\\') |
if (c == '\\') |
1492 |
{ |
{ |
1493 |
if (i_byte == size_byte) |
if (i_byte == size_byte) |
1681 |
stop = endp; |
stop = endp; |
1682 |
} |
} |
1683 |
c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes); |
c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes); |
1684 |
|
|
1685 |
|
if (! NILP (iso_classes) && in_classes (c, iso_classes)) |
1686 |
|
{ |
1687 |
|
if (negate) |
1688 |
|
break; |
1689 |
|
else |
1690 |
|
goto fwd_ok; |
1691 |
|
} |
1692 |
|
|
1693 |
if (SINGLE_BYTE_CHAR_P (c)) |
if (SINGLE_BYTE_CHAR_P (c)) |
1694 |
{ |
{ |
1695 |
if (!fastmap[c]) |
if (!fastmap[c]) |
1712 |
if (!(negate ^ (i < n_char_ranges))) |
if (!(negate ^ (i < n_char_ranges))) |
1713 |
break; |
break; |
1714 |
} |
} |
1715 |
|
fwd_ok: |
1716 |
p += nbytes, pos++, pos_byte += nbytes; |
p += nbytes, pos++, pos_byte += nbytes; |
1717 |
} |
} |
1718 |
else |
else |
1725 |
p = GAP_END_ADDR; |
p = GAP_END_ADDR; |
1726 |
stop = endp; |
stop = endp; |
1727 |
} |
} |
1728 |
|
|
1729 |
|
if (!NILP (iso_classes) && in_classes (*p, iso_classes)) |
1730 |
|
{ |
1731 |
|
if (negate) |
1732 |
|
break; |
1733 |
|
else |
1734 |
|
goto fwd_ok; |
1735 |
|
} |
1736 |
|
|
1737 |
if (!fastmap[*p]) |
if (!fastmap[*p]) |
1738 |
break; |
break; |
1739 |
|
|
1740 |
|
fwd_unibyte_ok: |
1741 |
p++, pos++; |
p++, pos++; |
1742 |
} |
} |
1743 |
} |
} |
1763 |
p = prev_p - 1, c = *p, nbytes = 1; |
p = prev_p - 1, c = *p, nbytes = 1; |
1764 |
else |
else |
1765 |
c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); |
c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); |
1766 |
|
|
1767 |
|
if (! NILP (iso_classes) && in_classes (c, iso_classes)) |
1768 |
|
{ |
1769 |
|
if (negate) |
1770 |
|
break; |
1771 |
|
else |
1772 |
|
goto back_ok; |
1773 |
|
} |
1774 |
|
|
1775 |
if (SINGLE_BYTE_CHAR_P (c)) |
if (SINGLE_BYTE_CHAR_P (c)) |
1776 |
{ |
{ |
1777 |
if (!fastmap[c]) |
if (!fastmap[c]) |
1786 |
if (!(negate ^ (i < n_char_ranges))) |
if (!(negate ^ (i < n_char_ranges))) |
1787 |
break; |
break; |
1788 |
} |
} |
1789 |
|
back_ok: |
1790 |
pos--, pos_byte -= nbytes; |
pos--, pos_byte -= nbytes; |
1791 |
} |
} |
1792 |
else |
else |
1799 |
p = GPT_ADDR; |
p = GPT_ADDR; |
1800 |
stop = endp; |
stop = endp; |
1801 |
} |
} |
1802 |
|
|
1803 |
|
if (! NILP (iso_classes) && in_classes (p[-1], iso_classes)) |
1804 |
|
{ |
1805 |
|
if (negate) |
1806 |
|
break; |
1807 |
|
else |
1808 |
|
goto fwd_ok; |
1809 |
|
} |
1810 |
|
|
1811 |
if (!fastmap[p[-1]]) |
if (!fastmap[p[-1]]) |
1812 |
break; |
break; |
1813 |
|
|
1814 |
|
back_unibyte_ok: |
1815 |
p--, pos--; |
p--, pos--; |
1816 |
} |
} |
1817 |
} |
} |
1834 |
return make_number (PT - start_point); |
return make_number (PT - start_point); |
1835 |
} |
} |
1836 |
} |
} |
1837 |
|
|
1838 |
|
/* Return 1 if character C belongs to one of the ISO classes |
1839 |
|
in the list ISO_CLASSES. Each class is represented by an |
1840 |
|
integer which is its type according to re_wctype. */ |
1841 |
|
|
1842 |
|
static int |
1843 |
|
in_classes (c, iso_classes) |
1844 |
|
int c; |
1845 |
|
Lisp_Object iso_classes; |
1846 |
|
{ |
1847 |
|
int fits_class = 0; |
1848 |
|
|
1849 |
|
while (! NILP (iso_classes)) |
1850 |
|
{ |
1851 |
|
Lisp_Object elt; |
1852 |
|
elt = XCAR (iso_classes); |
1853 |
|
iso_classes = XCDR (iso_classes); |
1854 |
|
|
1855 |
|
if (re_iswctype (c, XFASTINT (elt))) |
1856 |
|
fits_class = 1; |
1857 |
|
} |
1858 |
|
|
1859 |
|
return fits_class; |
1860 |
|
} |
1861 |
|
|
1862 |
/* Jump over a comment, assuming we are at the beginning of one. |
/* Jump over a comment, assuming we are at the beginning of one. |
1863 |
FROM is the current position. |
FROM is the current position. |