Mercurial > emacs
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 { |