Mercurial > emacs
comparison lib-src/etags.c @ 4937:50db67ef8d64
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.
author | Francesco Potortì <pot@gnu.org> |
---|---|
date | Mon, 08 Nov 1993 18:52:56 +0000 |
parents | 710950ca1b49 |
children | d3bd7baee39f |
comparison
equal
deleted
inserted
replaced
4936:35e9402cb6bf | 4937:50db67ef8d64 |
---|---|
23 * FORTRAN added by Jim Kleckner. | 23 * FORTRAN added by Jim Kleckner. |
24 * Ed Pelegri-Llopart added C typedefs. | 24 * Ed Pelegri-Llopart added C typedefs. |
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 |
32 #include <../src/config.h> | 32 #include <../src/config.h> |
33 #endif | 33 #endif |
351 char *curfile, /* current input file name */ | 351 char *curfile, /* current input file name */ |
352 *outfile, /* output file */ | 352 *outfile, /* output file */ |
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 |
360 int append_to_tagfile; /* -a: append to tags */ | 360 int append_to_tagfile; /* -a: append to tags */ |
361 int emacs_tags_format; /* emacs style output (no -e option any more) */ | 361 int emacs_tags_format; /* emacs style output (no -e option any more) */ |
1329 */ | 1329 */ |
1330 typedef enum | 1330 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 */ |
1337 } FUNCST; | 1338 } FUNCST; |
1338 FUNCST funcdef; | 1339 FUNCST funcdef; |
1408 #define newlb (lbs[newndx].lb) | 1409 #define newlb (lbs[newndx].lb) |
1409 #define curlinepos (lbs[curndx].linepos) | 1410 #define curlinepos (lbs[curndx].linepos) |
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); \ |
1416 lineno++; \ | 1426 lineno++; \ |
1417 charno += readline (&curlb, inf); \ | 1427 charno += readline (&curlb, inf); \ |
1421 } while (FALSE) | 1431 } while (FALSE) |
1422 | 1432 |
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 |
1429 #define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \ | 1441 #define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \ |
1430 newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos)) | 1442 newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos)) |
1441 TOKEN tok; /* latest token read for funcdef & structdef */ | 1453 TOKEN tok; /* latest token read for funcdef & structdef */ |
1442 char nameb[BUFSIZ]; /* latest token name for funcdef & structdef */ | 1454 char nameb[BUFSIZ]; /* latest token name for funcdef & structdef */ |
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; |
1448 | 1461 TOKEN savetok; /* saved token during preprocessor handling */ |
1462 logical saveisfunc; | |
1463 char savenameb[BUFSIZ]; /* ouch! */ | |
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; |
1452 lp = curlb.buffer; | 1469 lp = curlb.buffer; |
1453 *lp = 0; | 1470 *lp = 0; |
1454 | 1471 |
1455 definedef = dnone; funcdef = fnone; typdef= tnone; structdef= snone; | 1472 definedef = dnone; funcdef = fnone; typdef= tnone; structdef= snone; |
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 (); |
1462 | 1480 |
1463 while (!feof (inf)) | 1481 while (!feof (inf)) |
1520 else | 1538 else |
1521 switch (c) | 1539 switch (c) |
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 == '*') |
1531 { | 1553 { |
1532 lp++; | 1554 lp++; |
1536 else if (cplpl && *lp == '/') | 1558 else if (cplpl && *lp == '/') |
1537 { | 1559 { |
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 { |
1545 /* entering or exiting rules section in yacc file */ | 1568 /* entering or exiting rules section in yacc file */ |
1546 lp++; | 1569 lp++; |
1550 midtoken = inquote = inchar = incomm = quotednl = FALSE; | 1573 midtoken = inquote = inchar = incomm = quotednl = FALSE; |
1551 cblev = 0; | 1574 cblev = 0; |
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; |
1558 continue; | 1583 continue; |
1559 } /* switch (c) */ | 1584 } /* switch (c) */ |
1561 | 1586 |
1562 /* Consider token only if some complicated conditions are satisfied. */ | 1587 /* Consider token only if some complicated conditions are satisfied. */ |
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 |
1576 * of an identifier. | 1602 * of an identifier. |
1577 */ | 1603 */ |
1608 | 1634 |
1609 if (structdef == stagseen | 1635 if (structdef == stagseen |
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 */ |
1619 } | 1646 } |
1620 else | 1647 else |
1629 continue; | 1656 continue; |
1630 } | 1657 } |
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 { |
1666 case fstartlist: | |
1667 funcdef = finlist; | |
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; | |
1639 break; | 1679 break; |
1640 case ftagseen: | 1680 case dsharpseen: |
1641 funcdef = fnone; | 1681 /* Take a quick peek ahead for define directive, |
1642 break; | 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; |
1649 toklen = 1; | 1698 toklen = 1; |
1650 midtoken = TRUE; | 1699 midtoken = TRUE; |
1653 } | 1702 } |
1654 } /* if must look at token */ | 1703 } /* if must look at token */ |
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; |
1674 MAKE_TAG_FROM_OTH_LB (FALSE); | 1736 MAKE_TAG_FROM_OTH_LB (FALSE); |
1675 } | 1737 } |
1677 funcdef = fnone; | 1739 funcdef = fnone; |
1678 /* FALLTHRU */ | 1740 /* FALLTHRU */ |
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: |
1757 funcdef = fstartlist; | |
1758 break; | |
1759 case flistseen: | |
1691 funcdef = finlist; | 1760 funcdef = finlist; |
1692 break; | 1761 break; |
1693 case finlist: | |
1694 case flistseen: | |
1695 funcdef = fnone; | |
1696 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) |
1707 { | 1787 { |
1708 case skeyseen: /* unnamed struct */ | 1788 case skeyseen: /* unnamed struct */ |
1724 funcdef = fnone; | 1804 funcdef = fnone; |
1725 } | 1805 } |
1726 cblev++; | 1806 cblev++; |
1727 break; | 1807 break; |
1728 case '*': | 1808 case '*': |
1729 if (funcdef == flistseen) | 1809 if (definedef != dnone) |
1810 break; | |
1811 if (funcdef == fstartlist) | |
1812 funcdef = fnone; /* avoid tagging `foo' in `foo (*bar()) ()' */ | |
1813 break; | |
1814 case '}': | |
1815 if (definedef != dnone) | |
1816 break; | |
1817 if (!noindentypedefs && lp == newlb.buffer + 1) | |
1730 { | 1818 { |
1731 MAKE_TAG_FROM_OTH_LB (TRUE); | 1819 cblev = 0; /* reset curly brace level if first column */ |
1732 funcdef = fignore; | 1820 parlev = 0; /* also reset paren level, just in case... */ |
1733 } | 1821 } |
1734 break; | |
1735 case '}': | |
1736 if (!noindentypedefs && lp == newlb.buffer + 1) | |
1737 cblev = 0; /* reset curly brace level if first column */ | |
1738 else if (cblev > 0) | 1822 else if (cblev > 0) |
1739 cblev--; | 1823 cblev--; |
1740 if (cblev == 0) | 1824 if (cblev == 0) |
1741 { | 1825 { |
1742 if (typdef == tinbody) | 1826 if (typdef == tinbody) |
1743 typdef = tend; | 1827 typdef = tend; |
1744 structdef = snone; | 1828 structdef = snone; |
1745 (void) strcpy (structtag, "<error 2>"); | 1829 (void) strcpy (structtag, "<error 2>"); |
1746 } | 1830 } |
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; | |
1747 break; | 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) |
1751 CNL_SAVE_DEFINEDEF; | 1856 CNL_SAVE_DEFINEDEF; |