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;