aboutsummaryrefslogtreecommitdiffstats
path: root/src/syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax.c')
-rw-r--r--src/syntax.c155
1 files changed, 137 insertions, 18 deletions
diff --git a/src/syntax.c b/src/syntax.c
index 4b26d04cd30..62612620f03 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
26#include "buffer.h" 26#include "buffer.h"
27#include "charset.h" 27#include "charset.h"
28#include "keymap.h" 28#include "keymap.h"
29#include "regex.h"
29 30
30/* Make syntax table lookup grant data in gl_state. */ 31/* Make syntax table lookup grant data in gl_state. */
31#define SYNTAX_ENTRY_VIA_PROPERTY 32#define SYNTAX_ENTRY_VIA_PROPERTY
@@ -97,11 +98,12 @@ static int find_start_modiff;
97static int find_defun_start P_ ((int, int)); 98static int find_defun_start P_ ((int, int));
98static int back_comment P_ ((int, int, int, int, int, int *, int *)); 99static int back_comment P_ ((int, int, int, int, int, int *, int *));
99static int char_quoted P_ ((int, int)); 100static int char_quoted P_ ((int, int));
100static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object)); 101static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int));
101static Lisp_Object scan_lists P_ ((int, int, int, int)); 102static Lisp_Object scan_lists P_ ((int, int, int, int));
102static void scan_sexps_forward P_ ((struct lisp_parse_state *, 103static void scan_sexps_forward P_ ((struct lisp_parse_state *,
103 int, int, int, int, 104 int, int, int, int,
104 int, Lisp_Object, int)); 105 int, Lisp_Object, int));
106static int in_classes P_ ((int, Lisp_Object));
105 107
106 108
107struct gl_state_s gl_state; /* Global state of syntax parser. */ 109struct gl_state_s gl_state; /* Global state of syntax parser. */
@@ -292,8 +294,11 @@ char_quoted (charpos, bytepos)
292 294
293 while (bytepos >= beg) 295 while (bytepos >= beg)
294 { 296 {
297 int c;
298
295 UPDATE_SYNTAX_TABLE_BACKWARD (charpos); 299 UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
296 code = SYNTAX (FETCH_CHAR (bytepos)); 300 c = FETCH_CHAR (bytepos);
301 code = SYNTAX (c);
297 if (! (code == Scharquote || code == Sescape)) 302 if (! (code == Scharquote || code == Sescape))
298 break; 303 break;
299 304
@@ -380,12 +385,16 @@ find_defun_start (pos, pos_byte)
380 gl_state.use_global = 0; 385 gl_state.use_global = 0;
381 while (PT > BEGV) 386 while (PT > BEGV)
382 { 387 {
388 int c;
389
383 /* Open-paren at start of line means we may have found our 390 /* Open-paren at start of line means we may have found our
384 defun-start. */ 391 defun-start. */
385 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen) 392 c = FETCH_CHAR (PT_BYTE);
393 if (SYNTAX (c) == Sopen)
386 { 394 {
387 SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */ 395 SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */
388 if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen) 396 c = FETCH_CHAR (PT_BYTE);
397 if (SYNTAX (c) == Sopen)
389 break; 398 break;
390 /* Now fallback to the default value. */ 399 /* Now fallback to the default value. */
391 gl_state.current_syntax_table = current_buffer->syntax_table; 400 gl_state.current_syntax_table = current_buffer->syntax_table;
@@ -1314,13 +1323,13 @@ except that `]' is never special and `\\' quotes `^', `-' or `\\'
1314 (but not as the end of a range; quoting is never needed there). 1323 (but not as the end of a range; quoting is never needed there).
1315Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter. 1324Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.
1316With arg "^a-zA-Z", skips nonletters stopping before first letter. 1325With arg "^a-zA-Z", skips nonletters stopping before first letter.
1317Returns the distance traveled, either zero or positive. 1326Char classes, e.g. `[:alpha:]', are supported.
1318Note that char classes, e.g. `[:alpha:]', are not currently supported; 1327
1319they will be treated as literals. */) 1328Returns the distance traveled, either zero or positive. */)
1320 (string, lim) 1329 (string, lim)
1321 Lisp_Object string, lim; 1330 Lisp_Object string, lim;
1322{ 1331{
1323 return skip_chars (1, 0, string, lim); 1332 return skip_chars (1, 0, string, lim, 1);
1324} 1333}
1325 1334
1326DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0, 1335DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
@@ -1330,7 +1339,7 @@ Returns the distance traveled, either zero or negative. */)
1330 (string, lim) 1339 (string, lim)
1331 Lisp_Object string, lim; 1340 Lisp_Object string, lim;
1332{ 1341{
1333 return skip_chars (0, 0, string, lim); 1342 return skip_chars (0, 0, string, lim, 1);
1334} 1343}
1335 1344
1336DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0, 1345DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
@@ -1342,7 +1351,7 @@ This function returns the distance traveled, either zero or positive. */)
1342 (syntax, lim) 1351 (syntax, lim)
1343 Lisp_Object syntax, lim; 1352 Lisp_Object syntax, lim;
1344{ 1353{
1345 return skip_chars (1, 1, syntax, lim); 1354 return skip_chars (1, 1, syntax, lim, 0);
1346} 1355}
1347 1356
1348DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0, 1357DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
@@ -1354,13 +1363,14 @@ This function returns the distance traveled, either zero or negative. */)
1354 (syntax, lim) 1363 (syntax, lim)
1355 Lisp_Object syntax, lim; 1364 Lisp_Object syntax, lim;
1356{ 1365{
1357 return skip_chars (0, 1, syntax, lim); 1366 return skip_chars (0, 1, syntax, lim, 0);
1358} 1367}
1359 1368
1360static Lisp_Object 1369static Lisp_Object
1361skip_chars (forwardp, syntaxp, string, lim) 1370skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes)
1362 int forwardp, syntaxp; 1371 int forwardp, syntaxp;
1363 Lisp_Object string, lim; 1372 Lisp_Object string, lim;
1373 int handle_iso_classes;
1364{ 1374{
1365 register unsigned int c; 1375 register unsigned int c;
1366 unsigned char fastmap[0400]; 1376 unsigned char fastmap[0400];
@@ -1376,12 +1386,14 @@ skip_chars (forwardp, syntaxp, string, lim)
1376 int size_byte; 1386 int size_byte;
1377 const unsigned char *str; 1387 const unsigned char *str;
1378 int len; 1388 int len;
1389 Lisp_Object iso_classes;
1379 1390
1380 CHECK_STRING (string); 1391 CHECK_STRING (string);
1381 char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2); 1392 char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);
1382 string_multibyte = STRING_MULTIBYTE (string); 1393 string_multibyte = STRING_MULTIBYTE (string);
1383 str = SDATA (string); 1394 str = SDATA (string);
1384 size_byte = SBYTES (string); 1395 size_byte = SBYTES (string);
1396 iso_classes = Qnil;
1385 1397
1386 /* Adjust the multibyteness of the string to that of the buffer. */ 1398 /* Adjust the multibyteness of the string to that of the buffer. */
1387 if (multibyte != string_multibyte) 1399 if (multibyte != string_multibyte)
@@ -1437,6 +1449,45 @@ skip_chars (forwardp, syntaxp, string, lim)
1437 fastmap[syntax_spec_code[c & 0377]] = 1; 1449 fastmap[syntax_spec_code[c & 0377]] = 1;
1438 else 1450 else
1439 { 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
1440 if (c == '\\') 1491 if (c == '\\')
1441 { 1492 {
1442 if (i_byte == size_byte) 1493 if (i_byte == size_byte)
@@ -1630,6 +1681,15 @@ skip_chars (forwardp, syntaxp, string, lim)
1630 stop = endp; 1681 stop = endp;
1631 } 1682 }
1632 c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes); 1683 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
1633 if (SINGLE_BYTE_CHAR_P (c)) 1693 if (SINGLE_BYTE_CHAR_P (c))
1634 { 1694 {
1635 if (!fastmap[c]) 1695 if (!fastmap[c])
@@ -1652,6 +1712,7 @@ skip_chars (forwardp, syntaxp, string, lim)
1652 if (!(negate ^ (i < n_char_ranges))) 1712 if (!(negate ^ (i < n_char_ranges)))
1653 break; 1713 break;
1654 } 1714 }
1715 fwd_ok:
1655 p += nbytes, pos++, pos_byte += nbytes; 1716 p += nbytes, pos++, pos_byte += nbytes;
1656 } 1717 }
1657 else 1718 else
@@ -1664,8 +1725,19 @@ skip_chars (forwardp, syntaxp, string, lim)
1664 p = GAP_END_ADDR; 1725 p = GAP_END_ADDR;
1665 stop = endp; 1726 stop = endp;
1666 } 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
1667 if (!fastmap[*p]) 1737 if (!fastmap[*p])
1668 break; 1738 break;
1739
1740 fwd_unibyte_ok:
1669 p++, pos++; 1741 p++, pos++;
1670 } 1742 }
1671 } 1743 }
@@ -1691,6 +1763,15 @@ skip_chars (forwardp, syntaxp, string, lim)
1691 p = prev_p - 1, c = *p, nbytes = 1; 1763 p = prev_p - 1, c = *p, nbytes = 1;
1692 else 1764 else
1693 c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH); 1765 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
1694 if (SINGLE_BYTE_CHAR_P (c)) 1775 if (SINGLE_BYTE_CHAR_P (c))
1695 { 1776 {
1696 if (!fastmap[c]) 1777 if (!fastmap[c])
@@ -1705,6 +1786,7 @@ skip_chars (forwardp, syntaxp, string, lim)
1705 if (!(negate ^ (i < n_char_ranges))) 1786 if (!(negate ^ (i < n_char_ranges)))
1706 break; 1787 break;
1707 } 1788 }
1789 back_ok:
1708 pos--, pos_byte -= nbytes; 1790 pos--, pos_byte -= nbytes;
1709 } 1791 }
1710 else 1792 else
@@ -1717,8 +1799,19 @@ skip_chars (forwardp, syntaxp, string, lim)
1717 p = GPT_ADDR; 1799 p = GPT_ADDR;
1718 stop = endp; 1800 stop = endp;
1719 } 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
1720 if (!fastmap[p[-1]]) 1811 if (!fastmap[p[-1]])
1721 break; 1812 break;
1813
1814 back_unibyte_ok:
1722 p--, pos--; 1815 p--, pos--;
1723 } 1816 }
1724 } 1817 }
@@ -1741,6 +1834,30 @@ skip_chars (forwardp, syntaxp, string, lim)
1741 return make_number (PT - start_point); 1834 return make_number (PT - start_point);
1742 } 1835 }
1743} 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
1842static int
1843in_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}
1744 1861
1745/* Jump over a comment, assuming we are at the beginning of one. 1862/* Jump over a comment, assuming we are at the beginning of one.
1746 FROM is the current position. 1863 FROM is the current position.
@@ -2124,7 +2241,7 @@ scan_lists (from, count, depth, sexpflag)
2124 INC_BOTH (from, from_byte); 2241 INC_BOTH (from, from_byte);
2125 UPDATE_SYNTAX_TABLE_FORWARD (from); 2242 UPDATE_SYNTAX_TABLE_FORWARD (from);
2126 if (from < stop && comstart_first 2243 if (from < stop && comstart_first
2127 && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte)) 2244 && (c = FETCH_CHAR (from_byte), SYNTAX_COMSTART_SECOND (c))
2128 && parse_sexp_ignore_comments) 2245 && parse_sexp_ignore_comments)
2129 { 2246 {
2130 /* we have encountered a comment start sequence and we 2247 /* we have encountered a comment start sequence and we
@@ -2449,7 +2566,7 @@ scan_lists (from, count, depth, sexpflag)
2449 Fcons (build_string ("Unbalanced parentheses"), 2566 Fcons (build_string ("Unbalanced parentheses"),
2450 Fcons (make_number (last_good), 2567 Fcons (make_number (last_good),
2451 Fcons (make_number (from), Qnil)))); 2568 Fcons (make_number (from), Qnil))));
2452 2569 abort ();
2453 /* NOTREACHED */ 2570 /* NOTREACHED */
2454} 2571}
2455 2572
@@ -2588,8 +2705,8 @@ scan_sexps_forward (stateptr, from, from_byte, end, targetdepth,
2588#define INC_FROM \ 2705#define INC_FROM \
2589do { prev_from = from; \ 2706do { prev_from = from; \
2590 prev_from_byte = from_byte; \ 2707 prev_from_byte = from_byte; \
2591 prev_from_syntax \ 2708 temp = FETCH_CHAR (prev_from_byte); \
2592 = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); \ 2709 prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
2593 INC_BOTH (from, from_byte); \ 2710 INC_BOTH (from, from_byte); \
2594 if (from < end) \ 2711 if (from < end) \
2595 UPDATE_SYNTAX_TABLE_FORWARD (from); \ 2712 UPDATE_SYNTAX_TABLE_FORWARD (from); \
@@ -2664,7 +2781,8 @@ do { prev_from = from; \
2664 curlevel->last = -1; 2781 curlevel->last = -1;
2665 2782
2666 SETUP_SYNTAX_TABLE (prev_from, 1); 2783 SETUP_SYNTAX_TABLE (prev_from, 1);
2667 prev_from_syntax = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); 2784 temp = FETCH_CHAR (prev_from_byte);
2785 prev_from_syntax = SYNTAX_WITH_FLAGS (temp);
2668 UPDATE_SYNTAX_TABLE_FORWARD (from); 2786 UPDATE_SYNTAX_TABLE_FORWARD (from);
2669 2787
2670 /* Enter the loop at a place appropriate for initial state. */ 2788 /* Enter the loop at a place appropriate for initial state. */
@@ -2743,7 +2861,8 @@ do { prev_from = from; \
2743 while (from < end) 2861 while (from < end)
2744 { 2862 {
2745 /* Some compilers can't handle this inside the switch. */ 2863 /* Some compilers can't handle this inside the switch. */
2746 temp = SYNTAX (FETCH_CHAR (from_byte)); 2864 temp = FETCH_CHAR (from_byte);
2865 temp = SYNTAX (temp);
2747 switch (temp) 2866 switch (temp)
2748 { 2867 {
2749 case Scharquote: 2868 case Scharquote: