由于#ifdef,ctags在源文件上使用不平衡的大括号

我正在使用ctags为我正在处理的C项目生成一个tags文件,但文件中缺少许多function。 这似乎是由于使用#ifdef导致源文件中的不平衡大括号引起的。 一个(简化的)例子:

 #include  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的替代品感兴趣。

由于ctags的问题,我最终使用了cscope 。

虽然它并不完美,但它比ctags更好地处理宏,并且它可以像ctags一样集成vim(参见http://vimdoc.sourceforge.net/htmldoc/if_cscop.html#:cscope )。

我会尝试在文件上运行预处理器( gcc -E ),然后再将它们提供给ctags。 这是否会产生好结果我不确定,但值得一试。 当然,代码的所有组件都应该出现,但是ctags会识别gcc在输出中留下的其他文件引用吗? 不确定。

您可以尝试重写代码,以便只有一个右括号,例如:

 struct mystruct { long member; } #ifndef _MSC_VER __attribute__ ((packed)) #endif ; #ifdef _MSC_VER #pragma pack(pop) #endif /* _MSC_VER */ 

当然,您可以定义一些便利宏以使其更易于阅读。

您可以运行unifdef工具来选择性地(并临时)用空行替换代码的非活动部分(unifdef -l -U_MSC_VER) 。 结果是

 #include  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 yc /^char* greeting_text(){$/;" f main yc /^int main( int argc, const char* argv[] ){$/;" f member yc /^ long member;$/;" m struct:mystruct file: mystruct yc /^struct mystruct {$/;" s file: 

unifdef作为一个软件包在许多操作系统上都可用(例如FreeBSD,各种Linux distris,Cygwin)。 主页: http : //dotat.at/prog/unifdef/