diff options
| author | Francesco Potortì | 1993-11-08 18:52:56 +0000 |
|---|---|---|
| committer | Francesco Potortì | 1993-11-08 18:52:56 +0000 |
| commit | b12756c81ec1f6bc81b64d5d04470b9c187c29b9 (patch) | |
| tree | a84020b6e76ed05bad7143b196775e1f478fbd75 /lib-src | |
| parent | bb6066c863f0c21701c06d12cbc8159447e2f217 (diff) | |
| download | emacs-b12756c81ec1f6bc81b64d5d04470b9c187c29b9.tar.gz emacs-b12756c81ec1f6bc81b64d5d04470b9c187c29b9.zip | |
Mon Nov 8 19:56:20 MET 1993 Tom Hageman (tom@basil.icce.rug.nl)
* etags.c: (C_entries): Keep track of ()-parenthesis level so that
functions returning a pointer to a function, a la `signal', can be
parsed. This also required new state `fstartlist' to `FUNCST'.
(SAVE_TOKEN, RESTORE_TOKEN, TOKEN_SAVED_P): 1-deep token save stack.
(C_entries, CNL): use it to isolate preprocessor directive processing
from the other state engines.
(begtk): add '~', for C++ class destructors.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 173 |
1 files changed, 139 insertions, 34 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 305780082a8..bb1eb26f9d9 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -25,7 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 25 | * Gnu Emacs TAGS format and modifications by RMS? | 25 | * Gnu Emacs TAGS format and modifications by RMS? |
| 26 | * Sam Kendall added C++. | 26 | * Sam Kendall added C++. |
| 27 | * | 27 | * |
| 28 | * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 9.7 | 28 | * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 9.8 |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | #ifdef HAVE_CONFIG_H | 31 | #ifdef HAVE_CONFIG_H |
| @@ -353,7 +353,7 @@ char *curfile, /* current input file name */ | |||
| 353 | *white = " \f\t\n", /* white chars */ | 353 | *white = " \f\t\n", /* white chars */ |
| 354 | *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ | 354 | *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ |
| 355 | /* token starting chars */ | 355 | /* token starting chars */ |
| 356 | *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$", | 356 | *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", |
| 357 | /* valid in-token chars */ | 357 | /* valid in-token chars */ |
| 358 | *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; | 358 | *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; |
| 359 | 359 | ||
| @@ -1331,6 +1331,7 @@ typedef enum | |||
| 1331 | { | 1331 | { |
| 1332 | fnone, /* nothing seen */ | 1332 | fnone, /* nothing seen */ |
| 1333 | ftagseen, /* function-like tag seen */ | 1333 | ftagseen, /* function-like tag seen */ |
| 1334 | fstartlist, /* just after open parenthesis */ | ||
| 1334 | finlist, /* in parameter list */ | 1335 | finlist, /* in parameter list */ |
| 1335 | flistseen, /* after parameter list */ | 1336 | flistseen, /* after parameter list */ |
| 1336 | fignore, /* before open brace */ | 1337 | fignore, /* before open brace */ |
| @@ -1410,6 +1411,15 @@ logical yacc_rules; | |||
| 1410 | #define othlinepos (lbs[1-curndx].linepos) | 1411 | #define othlinepos (lbs[1-curndx].linepos) |
| 1411 | #define newlinepos (lbs[newndx].linepos) | 1412 | #define newlinepos (lbs[newndx].linepos) |
| 1412 | 1413 | ||
| 1414 | /* Save and restore token state. This is used when preprocessor defines | ||
| 1415 | are handled, to avoid disturbing active function/typedef/struct states. */ | ||
| 1416 | #define TOKEN_SAVED_P (savetok.lineno > 0) | ||
| 1417 | #define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \ | ||
| 1418 | savetok.len = toklen, strcpy(savenameb, nameb)) | ||
| 1419 | #define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \ | ||
| 1420 | toklen = tok.len, strcpy(nameb, savenameb), \ | ||
| 1421 | savetok.lineno = 0) | ||
| 1422 | |||
| 1413 | #define CNL_SAVE_DEFINEDEF \ | 1423 | #define CNL_SAVE_DEFINEDEF \ |
| 1414 | do { \ | 1424 | do { \ |
| 1415 | SET_FILEPOS (curlinepos, inf, charno); \ | 1425 | SET_FILEPOS (curlinepos, inf, charno); \ |
| @@ -1423,6 +1433,8 @@ do { \ | |||
| 1423 | #define CNL \ | 1433 | #define CNL \ |
| 1424 | do { \ | 1434 | do { \ |
| 1425 | CNL_SAVE_DEFINEDEF; \ | 1435 | CNL_SAVE_DEFINEDEF; \ |
| 1436 | if (TOKEN_SAVED_P) \ | ||
| 1437 | RESTORE_TOKEN; \ | ||
| 1426 | definedef = dnone; \ | 1438 | definedef = dnone; \ |
| 1427 | } while (FALSE) | 1439 | } while (FALSE) |
| 1428 | 1440 | ||
| @@ -1443,9 +1455,14 @@ C_entries (c_ext) | |||
| 1443 | register int tokoff; /* offset in line of start of latest token */ | 1455 | register int tokoff; /* offset in line of start of latest token */ |
| 1444 | register int toklen; /* length of latest token */ | 1456 | register int toklen; /* length of latest token */ |
| 1445 | int cblev; /* current curly brace level */ | 1457 | int cblev; /* current curly brace level */ |
| 1458 | int parlev; /* current parenthesis level */ | ||
| 1446 | logical incomm, inquote, inchar, quotednl, midtoken; | 1459 | logical incomm, inquote, inchar, quotednl, midtoken; |
| 1447 | logical cplpl; | 1460 | logical cplpl; |
| 1461 | TOKEN savetok; /* saved token during preprocessor handling */ | ||
| 1462 | logical saveisfunc; | ||
| 1463 | char savenameb[BUFSIZ]; /* ouch! */ | ||
| 1448 | 1464 | ||
| 1465 | savetok.lineno = 0; | ||
| 1449 | curndx = newndx = 0; | 1466 | curndx = newndx = 0; |
| 1450 | lineno = 0; | 1467 | lineno = 0; |
| 1451 | charno = 0; | 1468 | charno = 0; |
| @@ -1456,6 +1473,7 @@ C_entries (c_ext) | |||
| 1456 | next_token_is_func = yacc_rules = FALSE; | 1473 | next_token_is_func = yacc_rules = FALSE; |
| 1457 | midtoken = inquote = inchar = incomm = quotednl = FALSE; | 1474 | midtoken = inquote = inchar = incomm = quotednl = FALSE; |
| 1458 | cblev = 0; | 1475 | cblev = 0; |
| 1476 | parlev = 0; | ||
| 1459 | cplpl = c_ext & C_PLPL; | 1477 | cplpl = c_ext & C_PLPL; |
| 1460 | 1478 | ||
| 1461 | C_create_stabs (); | 1479 | C_create_stabs (); |
| @@ -1522,9 +1540,13 @@ C_entries (c_ext) | |||
| 1522 | { | 1540 | { |
| 1523 | case '"': | 1541 | case '"': |
| 1524 | inquote = TRUE; | 1542 | inquote = TRUE; |
| 1543 | if (funcdef != finlist && funcdef != fignore) | ||
| 1544 | funcdef = fnone; | ||
| 1525 | continue; | 1545 | continue; |
| 1526 | case '\'': | 1546 | case '\'': |
| 1527 | inchar = TRUE; | 1547 | inchar = TRUE; |
| 1548 | if (funcdef != finlist && funcdef != fignore) | ||
| 1549 | funcdef = fnone; | ||
| 1528 | continue; | 1550 | continue; |
| 1529 | case '/': | 1551 | case '/': |
| 1530 | if (*lp == '*') | 1552 | if (*lp == '*') |
| @@ -1538,7 +1560,8 @@ C_entries (c_ext) | |||
| 1538 | c = 0; | 1560 | c = 0; |
| 1539 | break; | 1561 | break; |
| 1540 | } | 1562 | } |
| 1541 | continue; | 1563 | else |
| 1564 | break; | ||
| 1542 | case '%': | 1565 | case '%': |
| 1543 | if ((c_ext & YACC) && *lp == '%') | 1566 | if ((c_ext & YACC) && *lp == '%') |
| 1544 | { | 1567 | { |
| @@ -1552,6 +1575,8 @@ C_entries (c_ext) | |||
| 1552 | yacc_rules = !yacc_rules; | 1575 | yacc_rules = !yacc_rules; |
| 1553 | continue; | 1576 | continue; |
| 1554 | } | 1577 | } |
| 1578 | else | ||
| 1579 | break; | ||
| 1555 | case '#': | 1580 | case '#': |
| 1556 | if (lp == newlb.buffer + 1 && definedef == dnone) | 1581 | if (lp == newlb.buffer + 1 && definedef == dnone) |
| 1557 | definedef = dsharpseen; | 1582 | definedef = dsharpseen; |
| @@ -1563,13 +1588,14 @@ C_entries (c_ext) | |||
| 1563 | if (((cblev == 0 && structdef != scolonseen) | 1588 | if (((cblev == 0 && structdef != scolonseen) |
| 1564 | || (cblev == 1 && cplpl && structdef == sinbody)) | 1589 | || (cblev == 1 && cplpl && structdef == sinbody)) |
| 1565 | && definedef != dignorerest | 1590 | && definedef != dignorerest |
| 1566 | && funcdef != finlist) | 1591 | && (funcdef != finlist |
| 1592 | || (definedef != dnone && definedef != dignorerest))) | ||
| 1567 | { | 1593 | { |
| 1568 | if (midtoken) | 1594 | if (midtoken) |
| 1569 | { | 1595 | { |
| 1570 | if (endtoken (c)) | 1596 | if (endtoken (c)) |
| 1571 | { | 1597 | { |
| 1572 | if (cplpl && c == ':' && *lp == ':' && intoken (*(lp + 1))) | 1598 | if (cplpl && c == ':' && *lp == ':' && begtoken(*(lp + 1))) |
| 1573 | { | 1599 | { |
| 1574 | /* | 1600 | /* |
| 1575 | * This handles :: in the middle, but not at beginning | 1601 | * This handles :: in the middle, but not at beginning |
| @@ -1610,9 +1636,10 @@ C_entries (c_ext) | |||
| 1610 | || typdef == tend) | 1636 | || typdef == tend) |
| 1611 | tok.named = TRUE; | 1637 | tok.named = TRUE; |
| 1612 | 1638 | ||
| 1613 | if (funcdef == ftagseen | 1639 | if (definedef == dnone |
| 1614 | || structdef == stagseen | 1640 | && (funcdef == ftagseen |
| 1615 | || typdef == tend) | 1641 | || structdef == stagseen |
| 1642 | || typdef == tend)) | ||
| 1616 | { | 1643 | { |
| 1617 | if (newndx == curndx) | 1644 | if (newndx == curndx) |
| 1618 | curndx = 1 - curndx; /* switch line buffers */ | 1645 | curndx = 1 - curndx; /* switch line buffers */ |
| @@ -1631,18 +1658,40 @@ C_entries (c_ext) | |||
| 1631 | } /* if (midtoken) */ | 1658 | } /* if (midtoken) */ |
| 1632 | else if (begtoken (c)) | 1659 | else if (begtoken (c)) |
| 1633 | { | 1660 | { |
| 1634 | switch (funcdef) | 1661 | switch (definedef) |
| 1635 | { | 1662 | { |
| 1636 | case flistseen: | 1663 | case dnone: |
| 1637 | MAKE_TAG_FROM_OTH_LB (TRUE); | 1664 | switch (funcdef) |
| 1638 | funcdef = fignore; | 1665 | { |
| 1639 | break; | 1666 | case fstartlist: |
| 1640 | case ftagseen: | 1667 | funcdef = finlist; |
| 1641 | funcdef = fnone; | 1668 | continue; |
| 1669 | case flistseen: | ||
| 1670 | MAKE_TAG_FROM_OTH_LB (TRUE); | ||
| 1671 | funcdef = fignore; | ||
| 1672 | break; | ||
| 1673 | case ftagseen: | ||
| 1674 | funcdef = fnone; | ||
| 1675 | break; | ||
| 1676 | } | ||
| 1677 | if (structdef == stagseen) | ||
| 1678 | structdef = snone; | ||
| 1642 | break; | 1679 | break; |
| 1680 | case dsharpseen: | ||
| 1681 | /* Take a quick peek ahead for define directive, | ||
| 1682 | so we can avoid saving the token when not absolutely | ||
| 1683 | necessary. [This is a speed hack.] */ | ||
| 1684 | if (c == 'd' && strneq(lp, "efine", 5) | ||
| 1685 | && iswhite(*(lp + 5))) | ||
| 1686 | { | ||
| 1687 | SAVE_TOKEN; | ||
| 1688 | definedef = ddefineseen; | ||
| 1689 | lp += 6; | ||
| 1690 | } | ||
| 1691 | else | ||
| 1692 | definedef = dignorerest; | ||
| 1693 | continue; | ||
| 1643 | } | 1694 | } |
| 1644 | if (structdef == stagseen) | ||
| 1645 | structdef = snone; | ||
| 1646 | if (!yacc_rules || lp == newlb.buffer + 1) | 1695 | if (!yacc_rules || lp == newlb.buffer + 1) |
| 1647 | { | 1696 | { |
| 1648 | tokoff = lp - 1 - newlb.buffer; | 1697 | tokoff = lp - 1 - newlb.buffer; |
| @@ -1655,19 +1704,32 @@ C_entries (c_ext) | |||
| 1655 | 1704 | ||
| 1656 | 1705 | ||
| 1657 | /* Detect end of line, colon, comma, semicolon and various braces | 1706 | /* Detect end of line, colon, comma, semicolon and various braces |
| 1658 | after having handled the last token on the line.*/ | 1707 | after having handled a token.*/ |
| 1659 | switch (c) | 1708 | switch (c) |
| 1660 | { | 1709 | { |
| 1661 | case ':': | 1710 | case ':': |
| 1711 | if (definedef != dnone) | ||
| 1712 | break; | ||
| 1662 | if (structdef == stagseen) | 1713 | if (structdef == stagseen) |
| 1663 | structdef = scolonseen; | 1714 | structdef = scolonseen; |
| 1664 | else if (yacc_rules && funcdef == ftagseen) | 1715 | else |
| 1665 | { | 1716 | switch (funcdef) |
| 1666 | MAKE_TAG_FROM_OTH_LB (FALSE); | 1717 | { |
| 1667 | funcdef = fignore; | 1718 | case ftagseen: |
| 1668 | } | 1719 | if (yacc_rules) |
| 1720 | { | ||
| 1721 | MAKE_TAG_FROM_OTH_LB (FALSE); | ||
| 1722 | funcdef = fignore; | ||
| 1723 | } | ||
| 1724 | break; | ||
| 1725 | case fstartlist: | ||
| 1726 | funcdef = fnone; | ||
| 1727 | break; | ||
| 1728 | } | ||
| 1669 | break; | 1729 | break; |
| 1670 | case ';': | 1730 | case ';': |
| 1731 | if (definedef != dnone) | ||
| 1732 | break; | ||
| 1671 | if (cblev == 0 && typdef == tend) | 1733 | if (cblev == 0 && typdef == tend) |
| 1672 | { | 1734 | { |
| 1673 | typdef = tnone; | 1735 | typdef = tnone; |
| @@ -1679,28 +1741,46 @@ C_entries (c_ext) | |||
| 1679 | case ',': | 1741 | case ',': |
| 1680 | /* FALLTHRU */ | 1742 | /* FALLTHRU */ |
| 1681 | case '[': | 1743 | case '[': |
| 1744 | if (definedef != dnone) | ||
| 1745 | break; | ||
| 1682 | if (funcdef != finlist && funcdef != fignore) | 1746 | if (funcdef != finlist && funcdef != fignore) |
| 1683 | funcdef = fnone; | 1747 | funcdef = fnone; |
| 1684 | if (structdef == stagseen) | 1748 | if (structdef == stagseen) |
| 1685 | structdef = snone; | 1749 | structdef = snone; |
| 1686 | break; | 1750 | break; |
| 1687 | case '(': | 1751 | case '(': |
| 1752 | if (definedef != dnone) | ||
| 1753 | break; | ||
| 1688 | switch (funcdef) | 1754 | switch (funcdef) |
| 1689 | { | 1755 | { |
| 1690 | case ftagseen: | 1756 | case ftagseen: |
| 1691 | funcdef = finlist; | 1757 | funcdef = fstartlist; |
| 1692 | break; | 1758 | break; |
| 1693 | case finlist: | ||
| 1694 | case flistseen: | 1759 | case flistseen: |
| 1695 | funcdef = fnone; | 1760 | funcdef = finlist; |
| 1696 | break; | 1761 | break; |
| 1697 | } | 1762 | } |
| 1763 | parlev++; | ||
| 1698 | break; | 1764 | break; |
| 1699 | case ')': | 1765 | case ')': |
| 1700 | if (funcdef == finlist) | 1766 | if (definedef != dnone) |
| 1701 | funcdef = flistseen; | 1767 | break; |
| 1768 | if (--parlev == 0) | ||
| 1769 | { | ||
| 1770 | switch (funcdef) | ||
| 1771 | { | ||
| 1772 | case fstartlist: | ||
| 1773 | case finlist: | ||
| 1774 | funcdef = flistseen; | ||
| 1775 | break; | ||
| 1776 | } | ||
| 1777 | } | ||
| 1778 | else if (parlev < 0) /* can happen due to ill-conceived #if's. */ | ||
| 1779 | parlev = 0; | ||
| 1702 | break; | 1780 | break; |
| 1703 | case '{': | 1781 | case '{': |
| 1782 | if (definedef != dnone) | ||
| 1783 | break; | ||
| 1704 | if (typdef == ttypedseen) | 1784 | if (typdef == ttypedseen) |
| 1705 | typdef = tinbody; | 1785 | typdef = tinbody; |
| 1706 | switch (structdef) | 1786 | switch (structdef) |
| @@ -1726,15 +1806,19 @@ C_entries (c_ext) | |||
| 1726 | cblev++; | 1806 | cblev++; |
| 1727 | break; | 1807 | break; |
| 1728 | case '*': | 1808 | case '*': |
| 1729 | if (funcdef == flistseen) | 1809 | if (definedef != dnone) |
| 1730 | { | 1810 | break; |
| 1731 | MAKE_TAG_FROM_OTH_LB (TRUE); | 1811 | if (funcdef == fstartlist) |
| 1732 | funcdef = fignore; | 1812 | funcdef = fnone; /* avoid tagging `foo' in `foo (*bar()) ()' */ |
| 1733 | } | ||
| 1734 | break; | 1813 | break; |
| 1735 | case '}': | 1814 | case '}': |
| 1815 | if (definedef != dnone) | ||
| 1816 | break; | ||
| 1736 | if (!noindentypedefs && lp == newlb.buffer + 1) | 1817 | if (!noindentypedefs && lp == newlb.buffer + 1) |
| 1737 | cblev = 0; /* reset curly brace level if first column */ | 1818 | { |
| 1819 | cblev = 0; /* reset curly brace level if first column */ | ||
| 1820 | parlev = 0; /* also reset paren level, just in case... */ | ||
| 1821 | } | ||
| 1738 | else if (cblev > 0) | 1822 | else if (cblev > 0) |
| 1739 | cblev--; | 1823 | cblev--; |
| 1740 | if (cblev == 0) | 1824 | if (cblev == 0) |
| @@ -1745,6 +1829,27 @@ C_entries (c_ext) | |||
| 1745 | (void) strcpy (structtag, "<error 2>"); | 1829 | (void) strcpy (structtag, "<error 2>"); |
| 1746 | } | 1830 | } |
| 1747 | break; | 1831 | break; |
| 1832 | case '=': | ||
| 1833 | case '#': | ||
| 1834 | case '+': | ||
| 1835 | case '-': | ||
| 1836 | case '~': | ||
| 1837 | case '&': | ||
| 1838 | case '%': | ||
| 1839 | case '/': | ||
| 1840 | case '|': | ||
| 1841 | case '^': | ||
| 1842 | case '!': | ||
| 1843 | case '<': | ||
| 1844 | case '>': | ||
| 1845 | case '.': | ||
| 1846 | case '?': | ||
| 1847 | if (definedef != dnone) | ||
| 1848 | break; | ||
| 1849 | /* These surely cannot follow a function tag. */ | ||
| 1850 | if (funcdef != finlist && funcdef != fignore) | ||
| 1851 | funcdef = fnone; | ||
| 1852 | break; | ||
| 1748 | case '\0': | 1853 | case '\0': |
| 1749 | /* If a macro spans multiple lines don't reset its state. */ | 1854 | /* If a macro spans multiple lines don't reset its state. */ |
| 1750 | if (quotednl) | 1855 | if (quotednl) |