Mercurial > emacs
changeset 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 | 35e9402cb6bf |
children | dfb65242faf4 |
files | lib-src/etags.c |
diffstat | 1 files changed, 139 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/etags.c Mon Nov 08 15:06:59 1993 +0000 +++ b/lib-src/etags.c Mon Nov 08 18:52:56 1993 +0000 @@ -25,7 +25,7 @@ * Gnu Emacs TAGS format and modifications by RMS? * Sam Kendall added C++. * - * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 9.7 + * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 9.8 */ #ifdef HAVE_CONFIG_H @@ -353,7 +353,7 @@ *white = " \f\t\n", /* white chars */ *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ /* token starting chars */ - *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$", + *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", /* valid in-token chars */ *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; @@ -1331,6 +1331,7 @@ { fnone, /* nothing seen */ ftagseen, /* function-like tag seen */ + fstartlist, /* just after open parenthesis */ finlist, /* in parameter list */ flistseen, /* after parameter list */ fignore, /* before open brace */ @@ -1410,6 +1411,15 @@ #define othlinepos (lbs[1-curndx].linepos) #define newlinepos (lbs[newndx].linepos) +/* Save and restore token state. This is used when preprocessor defines + are handled, to avoid disturbing active function/typedef/struct states. */ +#define TOKEN_SAVED_P (savetok.lineno > 0) +#define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \ + savetok.len = toklen, strcpy(savenameb, nameb)) +#define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \ + toklen = tok.len, strcpy(nameb, savenameb), \ + savetok.lineno = 0) + #define CNL_SAVE_DEFINEDEF \ do { \ SET_FILEPOS (curlinepos, inf, charno); \ @@ -1423,6 +1433,8 @@ #define CNL \ do { \ CNL_SAVE_DEFINEDEF; \ + if (TOKEN_SAVED_P) \ + RESTORE_TOKEN; \ definedef = dnone; \ } while (FALSE) @@ -1443,9 +1455,14 @@ register int tokoff; /* offset in line of start of latest token */ register int toklen; /* length of latest token */ int cblev; /* current curly brace level */ + int parlev; /* current parenthesis level */ logical incomm, inquote, inchar, quotednl, midtoken; logical cplpl; + TOKEN savetok; /* saved token during preprocessor handling */ + logical saveisfunc; + char savenameb[BUFSIZ]; /* ouch! */ + savetok.lineno = 0; curndx = newndx = 0; lineno = 0; charno = 0; @@ -1456,6 +1473,7 @@ next_token_is_func = yacc_rules = FALSE; midtoken = inquote = inchar = incomm = quotednl = FALSE; cblev = 0; + parlev = 0; cplpl = c_ext & C_PLPL; C_create_stabs (); @@ -1522,9 +1540,13 @@ { case '"': inquote = TRUE; + if (funcdef != finlist && funcdef != fignore) + funcdef = fnone; continue; case '\'': inchar = TRUE; + if (funcdef != finlist && funcdef != fignore) + funcdef = fnone; continue; case '/': if (*lp == '*') @@ -1538,7 +1560,8 @@ c = 0; break; } - continue; + else + break; case '%': if ((c_ext & YACC) && *lp == '%') { @@ -1552,6 +1575,8 @@ yacc_rules = !yacc_rules; continue; } + else + break; case '#': if (lp == newlb.buffer + 1 && definedef == dnone) definedef = dsharpseen; @@ -1563,13 +1588,14 @@ if (((cblev == 0 && structdef != scolonseen) || (cblev == 1 && cplpl && structdef == sinbody)) && definedef != dignorerest - && funcdef != finlist) + && (funcdef != finlist + || (definedef != dnone && definedef != dignorerest))) { if (midtoken) { if (endtoken (c)) { - if (cplpl && c == ':' && *lp == ':' && intoken (*(lp + 1))) + if (cplpl && c == ':' && *lp == ':' && begtoken(*(lp + 1))) { /* * This handles :: in the middle, but not at beginning @@ -1610,9 +1636,10 @@ || typdef == tend) tok.named = TRUE; - if (funcdef == ftagseen - || structdef == stagseen - || typdef == tend) + if (definedef == dnone + && (funcdef == ftagseen + || structdef == stagseen + || typdef == tend)) { if (newndx == curndx) curndx = 1 - curndx; /* switch line buffers */ @@ -1631,18 +1658,40 @@ } /* if (midtoken) */ else if (begtoken (c)) { - switch (funcdef) + switch (definedef) { - case flistseen: - MAKE_TAG_FROM_OTH_LB (TRUE); - funcdef = fignore; + case dnone: + switch (funcdef) + { + case fstartlist: + funcdef = finlist; + continue; + case flistseen: + MAKE_TAG_FROM_OTH_LB (TRUE); + funcdef = fignore; + break; + case ftagseen: + funcdef = fnone; + break; + } + if (structdef == stagseen) + structdef = snone; break; - case ftagseen: - funcdef = fnone; - break; + case dsharpseen: + /* Take a quick peek ahead for define directive, + so we can avoid saving the token when not absolutely + necessary. [This is a speed hack.] */ + if (c == 'd' && strneq(lp, "efine", 5) + && iswhite(*(lp + 5))) + { + SAVE_TOKEN; + definedef = ddefineseen; + lp += 6; + } + else + definedef = dignorerest; + continue; } - if (structdef == stagseen) - structdef = snone; if (!yacc_rules || lp == newlb.buffer + 1) { tokoff = lp - 1 - newlb.buffer; @@ -1655,19 +1704,32 @@ /* Detect end of line, colon, comma, semicolon and various braces - after having handled the last token on the line.*/ + after having handled a token.*/ switch (c) { case ':': + if (definedef != dnone) + break; if (structdef == stagseen) structdef = scolonseen; - else if (yacc_rules && funcdef == ftagseen) - { - MAKE_TAG_FROM_OTH_LB (FALSE); - funcdef = fignore; - } + else + switch (funcdef) + { + case ftagseen: + if (yacc_rules) + { + MAKE_TAG_FROM_OTH_LB (FALSE); + funcdef = fignore; + } + break; + case fstartlist: + funcdef = fnone; + break; + } break; case ';': + if (definedef != dnone) + break; if (cblev == 0 && typdef == tend) { typdef = tnone; @@ -1679,28 +1741,46 @@ case ',': /* FALLTHRU */ case '[': + if (definedef != dnone) + break; if (funcdef != finlist && funcdef != fignore) funcdef = fnone; if (structdef == stagseen) structdef = snone; break; case '(': + if (definedef != dnone) + break; switch (funcdef) { case ftagseen: - funcdef = finlist; + funcdef = fstartlist; break; - case finlist: case flistseen: - funcdef = fnone; + funcdef = finlist; break; } + parlev++; break; case ')': - if (funcdef == finlist) - funcdef = flistseen; + if (definedef != dnone) + break; + if (--parlev == 0) + { + switch (funcdef) + { + case fstartlist: + case finlist: + funcdef = flistseen; + break; + } + } + else if (parlev < 0) /* can happen due to ill-conceived #if's. */ + parlev = 0; break; case '{': + if (definedef != dnone) + break; if (typdef == ttypedseen) typdef = tinbody; switch (structdef) @@ -1726,15 +1806,19 @@ cblev++; break; case '*': - if (funcdef == flistseen) - { - MAKE_TAG_FROM_OTH_LB (TRUE); - funcdef = fignore; - } + if (definedef != dnone) + break; + if (funcdef == fstartlist) + funcdef = fnone; /* avoid tagging `foo' in `foo (*bar()) ()' */ break; case '}': + if (definedef != dnone) + break; if (!noindentypedefs && lp == newlb.buffer + 1) - cblev = 0; /* reset curly brace level if first column */ + { + cblev = 0; /* reset curly brace level if first column */ + parlev = 0; /* also reset paren level, just in case... */ + } else if (cblev > 0) cblev--; if (cblev == 0) @@ -1745,6 +1829,27 @@ (void) strcpy (structtag, "<error 2>"); } break; + case '=': + case '#': + case '+': + case '-': + case '~': + case '&': + case '%': + case '/': + case '|': + case '^': + case '!': + case '<': + case '>': + case '.': + case '?': + if (definedef != dnone) + break; + /* These surely cannot follow a function tag. */ + if (funcdef != finlist && funcdef != fignore) + funcdef = fnone; + break; case '\0': /* If a macro spans multiple lines don't reset its state. */ if (quotednl)