comparison lib-src/etags.c @ 47157:e47f0756e65a

(consider_token, C_entries): Switch to C++ parsing when auto-detection is enabled and the `::' qualifier is met. (consider_token, C_entries): Several bugs corrected that tagged some declarations even though --declarations was not used. (plainc): New macro. (C_entries): Use it. (C_entries): Several cosmetic changes. (C_entries): Invalidate the token is some cases.
author Francesco Potortì <pot@gnu.org>
date Fri, 30 Aug 2002 16:38:58 +0000
parents 4098bad57f21
children 66c5d66d21f6
comparison
equal deleted inserted replaced
47156:293b7469c8bf 47157:e47f0756e65a
33 * 33 *
34 * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993. 34 * Francesco Potort́ <pot@gnu.org> has maintained and improved it since 1993.
35 * 35 *
36 */ 36 */
37 37
38 char pot_etags_version[] = "@(#) pot revision number is 16.46"; 38 char pot_etags_version[] = "@(#) pot revision number is 16.54";
39 39
40 #define TRUE 1 40 #define TRUE 1
41 #define FALSE 0 41 #define FALSE 0
42 42
43 #ifdef DEBUG 43 #ifdef DEBUG
1763 /* We found one of those! We must delete both the file description 1763 /* We found one of those! We must delete both the file description
1764 and all tags referring to it. */ 1764 and all tags referring to it. */
1765 { 1765 {
1766 fdesc *badfdp = *fdpp; 1766 fdesc *badfdp = *fdpp;
1767 1767
1768 if (DEBUG) 1768 /* Delete the tags referring to badfdp->taggedfname
1769 fprintf (stderr, 1769 that were obtained from badfdp->infname. */
1770 "Removing references to \"%s\" obtained from \"%s\"\n",
1771 badfdp->taggedfname, badfdp->infname);
1772
1773 /* Delete the tags referring to badfdp. */
1774 invalidate_nodes (badfdp, &nodehead); 1770 invalidate_nodes (badfdp, &nodehead);
1775 1771
1776 *fdpp = badfdp->next; /* remove the bad description from the list */ 1772 *fdpp = badfdp->next; /* remove the bad description from the list */
1777 free_fdesc (badfdp); 1773 free_fdesc (badfdp);
1778 } 1774 }
2566 * Use this structure to keep info about the token read, and how it 2562 * Use this structure to keep info about the token read, and how it
2567 * should be tagged. Used by the make_C_tag function to build a tag. 2563 * should be tagged. Used by the make_C_tag function to build a tag.
2568 */ 2564 */
2569 static struct tok 2565 static struct tok
2570 { 2566 {
2571 bool valid; 2567 char *line; /* string containing the token */
2572 bool named; 2568 int offset; /* where the token starts in LINE */
2573 int offset; 2569 int length; /* token length */
2574 int length; 2570 /*
2575 int lineno; 2571 The previous members can be used to pass strings around for generic
2576 long linepos; 2572 purposes. The following ones specifically refer to creating tags. In this
2577 char *line; 2573 case the token contained here is the pattern that will be used to create a
2574 tag.
2575 */
2576 bool valid; /* do not create a tag; the token should be
2577 invalidated whenever a state machine is
2578 reset prematurely */
2579 bool named; /* create a named tag */
2580 int lineno; /* source line number of tag */
2581 long linepos; /* source char number of tag */
2578 } token; /* latest token read */ 2582 } token; /* latest token read */
2579 2583
2580 /* 2584 /*
2581 * Variables and functions for dealing with nested structures. 2585 * Variables and functions for dealing with nested structures.
2582 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001) 2586 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2809 if (structdef == stagseen) 2813 if (structdef == stagseen)
2810 structdef = scolonseen; 2814 structdef = scolonseen;
2811 return FALSE; 2815 return FALSE;
2812 case st_C_template: 2816 case st_C_template:
2813 case st_C_class: 2817 case st_C_class:
2814 if (cblev == 0 2818 if ((*c_extp & C_AUTO) /* automatic detection of C++ language */
2815 && (*c_extp & C_AUTO) /* automatic detection of C++ language */ 2819 && cblev == 0
2816 && definedef == dnone && structdef == snone 2820 && definedef == dnone && structdef == snone
2817 && typdef == tnone && fvdef == fvnone) 2821 && typdef == tnone && fvdef == fvnone)
2818 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO; 2822 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
2819 if (toktype == st_C_template) 2823 if (toktype == st_C_template)
2820 break; 2824 break;
2915 { 2919 {
2916 case st_C_extern: 2920 case st_C_extern:
2917 fvextern = TRUE; 2921 fvextern = TRUE;
2918 /* FALLTHRU */ 2922 /* FALLTHRU */
2919 case st_C_typespec: 2923 case st_C_typespec:
2920 if (fvdef != finlist && fvdef != fignore && fvdef != vignore) 2924 switch (fvdef)
2921 fvdef = fvnone; /* should be useless */ 2925 {
2926 case finlist:
2927 case flistseen:
2928 case fignore:
2929 case vignore:
2930 break;
2931 default:
2932 fvdef = fvnone;
2933 }
2922 return FALSE; 2934 return FALSE;
2923 case st_C_ignore: 2935 case st_C_ignore:
2924 fvextern = FALSE; 2936 fvextern = FALSE;
2925 fvdef = vignore; 2937 fvdef = vignore;
2926 return FALSE; 2938 return FALSE;
2946 || (strneq (str, "__asm__", 7) && endtoken (str[7]))) 2958 || (strneq (str, "__asm__", 7) && endtoken (str[7])))
2947 { 2959 {
2948 fvdef = vignore; 2960 fvdef = vignore;
2949 return FALSE; 2961 return FALSE;
2950 } 2962 }
2951 if ((*c_extp & C_PLPL) && strneq (str+len-10, "::operator", 10)) 2963 if (strneq (str+len-10, "::operator", 10))
2952 { 2964 {
2965 if (*c_extp & C_AUTO) /* automatic detection of C++ */
2966 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
2953 fvdef = foperator; 2967 fvdef = foperator;
2954 *is_func_or_var = TRUE; 2968 *is_func_or_var = TRUE;
2955 return TRUE; 2969 return TRUE;
2956 } 2970 }
2957 if (cblev > 0 && !instruct) 2971 if (cblev > 0 && !instruct)
2984 #define curlb (lbs[curndx].lb) 2998 #define curlb (lbs[curndx].lb)
2985 #define newlb (lbs[newndx].lb) 2999 #define newlb (lbs[newndx].lb)
2986 #define curlinepos (lbs[curndx].linepos) 3000 #define curlinepos (lbs[curndx].linepos)
2987 #define newlinepos (lbs[newndx].linepos) 3001 #define newlinepos (lbs[newndx].linepos)
2988 3002
2989 #define cplpl ((c_ext & C_PLPL) == C_PLPL) 3003 #define plainc ((c_ext & C_EXT) == C_PLAIN)
3004 #define cplpl (c_ext & C_PLPL)
2990 #define cjava ((c_ext & C_JAVA) == C_JAVA) 3005 #define cjava ((c_ext & C_JAVA) == C_JAVA)
2991 3006
2992 #define CNL_SAVE_DEFINEDEF() \ 3007 #define CNL_SAVE_DEFINEDEF() \
2993 do { \ 3008 do { \
2994 curlinepos = charno; \ 3009 curlinepos = charno; \
3017 /* This function should never be called when token.valid is FALSE, but 3032 /* This function should never be called when token.valid is FALSE, but
3018 we must protect against invalid input or internal errors. */ 3033 we must protect against invalid input or internal errors. */
3019 if (!DEBUG && !token.valid) 3034 if (!DEBUG && !token.valid)
3020 return; 3035 return;
3021 3036
3022 if (!token.valid) /* this case is optimised away if !DEBUG */ 3037 if (token.valid)
3023 make_tag (concat (token_name.buffer, "##invalid token##", ""), 3038 make_tag (token_name.buffer, token_name.len, isfun, token.line,
3039 token.offset+token.length+1, token.lineno, token.linepos);
3040 else /* this case is optimised away if !DEBUG */
3041 make_tag (concat ("INVALID TOKEN:-->", token_name.buffer, ""),
3024 token_name.len + 17, isfun, token.line, 3042 token_name.len + 17, isfun, token.line,
3025 token.offset+token.length+1, token.lineno, token.linepos);
3026 else
3027 make_tag (token_name.buffer, token_name.len, isfun, token.line,
3028 token.offset+token.length+1, token.lineno, token.linepos); 3043 token.offset+token.length+1, token.lineno, token.linepos);
3029 3044
3030 token.valid = FALSE; 3045 token.valid = FALSE;
3031 } 3046 }
3032 3047
3242 { 3257 {
3243 if (midtoken) 3258 if (midtoken)
3244 { 3259 {
3245 if (endtoken (c)) 3260 if (endtoken (c))
3246 { 3261 {
3247 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1])) 3262 if (c == ':' && *lp == ':' && begtoken (lp[1]))
3263 /* This handles :: in the middle,
3264 but not at the beginning of an identifier.
3265 Also, space-separated :: is not recognised. */
3248 { 3266 {
3249 /* 3267 if (c_ext & C_AUTO) /* automatic detection of C++ */
3250 * This handles :: in the middle, but not at the 3268 c_ext = (c_ext | C_PLPL) & ~C_AUTO;
3251 * beginning of an identifier. Also, space-separated
3252 * :: is not recognised.
3253 */
3254 lp += 2; 3269 lp += 2;
3255 toklen += 2; 3270 toklen += 2;
3256 c = lp[-1]; 3271 c = lp[-1];
3257 goto still_in_token; 3272 goto still_in_token;
3258 } 3273 }
3275 lp += 1; 3290 lp += 1;
3276 c = *lp++; 3291 c = *lp++;
3277 toklen += lp - oldlp; 3292 toklen += lp - oldlp;
3278 } 3293 }
3279 token.named = FALSE; 3294 token.named = FALSE;
3280 if ((c_ext & C_EXT) /* not pure C */ 3295 if (!plainc
3281 && nestlev > 0 && definedef == dnone) 3296 && nestlev > 0 && definedef == dnone)
3282 /* in struct body */ 3297 /* in struct body */
3283 { 3298 {
3284 write_classname (&token_name, qualifier); 3299 write_classname (&token_name, qualifier);
3285 linebuffer_setlen (&token_name, 3300 linebuffer_setlen (&token_name,
3391 { 3406 {
3392 case fstartlist: 3407 case fstartlist:
3393 fvdef = finlist; 3408 fvdef = finlist;
3394 continue; 3409 continue;
3395 case flistseen: 3410 case flistseen:
3396 #if 0 3411 if (plainc || declarations)
3397 if (!instruct || members) 3412 {
3398 #endif 3413 make_C_tag (TRUE); /* a function */
3399 make_C_tag (TRUE); /* a function */ 3414 fvdef = fignore;
3400 fvdef = fignore; 3415 }
3401 break; 3416 break;
3402 case fvnameseen: 3417 case fvnameseen:
3403 fvdef = fvnone; 3418 fvdef = fvnone;
3404 break; 3419 break;
3405 } 3420 }
3452 if (structdef == stagseen) 3467 if (structdef == stagseen)
3453 { 3468 {
3454 structdef = scolonseen; 3469 structdef = scolonseen;
3455 break; 3470 break;
3456 } 3471 }
3457 #if 0 3472 /* Should be useless, but may be work as a safety net. */
3458 if (cplpl && fvdef == flistseen) 3473 if (cplpl && fvdef == flistseen)
3459 { 3474 {
3460 make_C_tag (TRUE); /* a function */ 3475 make_C_tag (TRUE); /* a function */
3461 fvdef = fignore; 3476 fvdef = fignore;
3462 break; 3477 break;
3463 } 3478 }
3464 #endif
3465 break; 3479 break;
3466 case ';': 3480 case ';':
3467 if (definedef != dnone) 3481 if (definedef != dnone)
3468 break; 3482 break;
3469 switch (typdef) 3483 switch (typdef)
3490 fvextern = FALSE; 3504 fvextern = FALSE;
3491 fvdef = fvnone; 3505 fvdef = fvnone;
3492 token.valid = FALSE; 3506 token.valid = FALSE;
3493 break; 3507 break;
3494 case flistseen: 3508 case flistseen:
3495 if ((declarations && typdef == tnone && !instruct) 3509 if (declarations
3496 || (members && typdef != tignore && instruct)) 3510 && (typdef == tnone || (typdef != tignore && instruct)))
3497 make_C_tag (TRUE); /* a function declaration */ 3511 make_C_tag (TRUE); /* a function declaration */
3498 /* FALLTHRU */ 3512 /* FALLTHRU */
3499 default: 3513 default:
3500 fvextern = FALSE; 3514 fvextern = FALSE;
3501 fvdef = fvnone; 3515 fvdef = fvnone;
3502 if (declarations 3516 if (declarations
3503 && structdef == stagseen && (c_ext & C_PLPL)) 3517 && cplpl && structdef == stagseen)
3504 make_C_tag (FALSE); /* forward declaration */ 3518 make_C_tag (FALSE); /* forward declaration */
3505 else 3519 else
3506 /* The following instruction invalidates the token.
3507 Probably the token should be invalidated in all other
3508 cases where some state machine is reset prematurely. */
3509 token.valid = FALSE; 3520 token.valid = FALSE;
3510 } /* switch (fvdef) */ 3521 } /* switch (fvdef) */
3511 /* FALLTHRU */ 3522 /* FALLTHRU */
3512 default: 3523 default:
3513 if (!instruct) 3524 if (!instruct)
3706 break; 3717 break;
3707 case '*': 3718 case '*':
3708 if (definedef != dnone) 3719 if (definedef != dnone)
3709 break; 3720 break;
3710 if (fvdef == fstartlist) 3721 if (fvdef == fstartlist)
3711 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */ 3722 {
3723 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
3724 token.valid = FALSE;
3725 }
3712 break; 3726 break;
3713 case '}': 3727 case '}':
3714 if (definedef != dnone) 3728 if (definedef != dnone)
3715 break; 3729 break;
3716 if (!ignoreindent && lp == newlb.buffer + 1) 3730 if (!ignoreindent && lp == newlb.buffer + 1)
3717 { 3731 {
3732 if (cblev != 0)
3733 token.valid = FALSE;
3718 cblev = 0; /* reset curly brace level if first column */ 3734 cblev = 0; /* reset curly brace level if first column */
3719 parlev = 0; /* also reset paren level, just in case... */ 3735 parlev = 0; /* also reset paren level, just in case... */
3720 } 3736 }
3721 else if (cblev > 0) 3737 else if (cblev > 0)
3722 cblev--; 3738 cblev--;
3739 else
3740 token.valid = FALSE; /* something gone amiss, token unreliable */
3723 popclass_above (cblev); 3741 popclass_above (cblev);
3724 structdef = snone; 3742 structdef = snone;
3725 /* Only if typdef == tinbody is typdefcblev significant. */ 3743 /* Only if typdef == tinbody is typdefcblev significant. */
3726 if (typdef == tinbody && cblev <= typdefcblev) 3744 if (typdef == tinbody && cblev <= typdefcblev)
3727 { 3745 {