我正在使用ctags
为我正在处理的C项目生成tags
文件,但文件中缺少许多功能。这似乎是由于使用#ifdef
导致源文件中的不平衡大括号造成的。一个(简化的)例子:
#include <stdio.h>
struct mystruct {
long member;
#ifndef _MSC_VER
}__attribute__ ((packed));
#else /* _MSC_VER */
};
#pragma pack(pop)
#endif /* _MSC_VER */
char* greeting_text(){
return "Hello world\n";
}
int main( int argc, const char* argv[] ){
char * greeting = greeting_text();
printf(greeting);
return 0;
}
这在Linux下编译并与gcc -Wall
完美配合。但是,如果我使用ctags problem.c
解析它,tags
文件只包含mystruct
的条目 - 函数丢失。
ctags --verbose
报告:
OPENING problem.c as C language file
problem.c: unexpected closing brace at line 8
problem.c: retrying file with fallback brace matching algorithm
OPENING problem.c as C language file
problem.c: unexpected closing brace at line 8
显然ctags
不喜欢文件中的预处理器技巧。
有没有办法让ctags
处理这个?
ctags
的联合帮助页甚至明确提到了这个问题,但表明ctags
可以解决这个问题。但是,这似乎不起作用......
这是使用Exuberant Ctags 5.8(Debian包1:5.8-4)。
修改
我也对处理这些结构的ctags的替代品感兴趣。
答案 0 :(得分:2)
由于ctags的问题,我最终使用了cscope。
虽然它并不完美,但它比ctags更好地处理宏,并且它可以像ctags一样与vim集成(参见http://vimdoc.sourceforge.net/htmldoc/if_cscop.html#:cscope)。
答案 1 :(得分:1)
我会尝试在文件上运行预处理器(gcc -E
),然后再将它们提供给ctags。这是否会产生好结果我不确定,但值得一试。当然,代码的所有组件都应该出现,但是ctags会识别gcc在输出中留下的其他文件引用吗?不确定。
答案 2 :(得分:1)
您可以尝试重写代码,以便只有一个右括号,例如:
struct mystruct {
long member;
}
#ifndef _MSC_VER
__attribute__ ((packed))
#endif
;
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */
当然,您可以定义一些便利宏,以便于阅读。
答案 3 :(得分:1)
您可以运行unifdef
工具,选择性地(暂时)用空行(unifdef -l -U_MSC_VER)
替换代码的非活动部分。结果是
#include <stdio.h>
struct mystruct {
long member;
}__attribute__ ((packed));
char* greeting_text(){
return "Hello world\n";
}
int main( int argc, const char* argv[] ){
char * greeting = greeting_text();
printf(greeting);
return 0;
}
Ctags解析这个问题没有问题,并且行号保持不变(如果按行号创建ctags搜索,则很重要):
$ cat tags
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.6 //
greeting_text y.c /^char* greeting_text(){$/;" f
main y.c /^int main( int argc, const char* argv[] ){$/;" f
member y.c /^ long member;$/;" m struct:mystruct file:
mystruct y.c /^struct mystruct {$/;" s file:
unifdef
在许多操作系统上都可用作软件包(例如FreeBSD,各种Linux distris,Cygwin)。主页:http://dotat.at/prog/unifdef/