由于#ifdef,ctags在源文件上阻塞,大括号不平衡

由于#ifdef,ctags在源文件上阻塞,大括号不平衡,c,c-preprocessor,ctags,exuberant-ctags,C,C Preprocessor,Ctags,Exuberant Ctags,我正在使用ctags为我正在处理的一个C项目生成一个tags文件,但是文件中缺少许多函数。这似乎是由于使用#ifdef导致源文件中大括号不平衡所致。一个(简化的)示例: 所以显然ctags不喜欢文件中的预处理器技巧 有没有办法让CTAG处理这个问题 ctags的主页甚至明确提到了这个问题,但表明ctags可以解决这个问题。然而,这似乎不起作用 这是一个充满活力的Ctags 5.8(Debian软件包1:5.8-4) 编辑: 我还对处理这类构造的CTAG的替代方案感兴趣。在将文件交给CTAG之前,

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

所以显然
ctags
不喜欢文件中的预处理器技巧

有没有办法让CTAG处理这个问题

ctags
的主页甚至明确提到了这个问题,但表明
ctags
可以解决这个问题。然而,这似乎不起作用

这是一个充满活力的Ctags 5.8(Debian软件包1:5.8-4)

编辑:


我还对处理这类构造的CTAG的替代方案感兴趣。

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

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

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

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

由于CTAG的问题,我最终使用了它


虽然它并不完美,但它比ctags更好地处理宏,并且它可以像ctags一样与vim集成(请参见)。

您可以运行
unifdef
工具,有选择地(临时地)用空行替换代码的非活动部分
(unifdef-l-U\U MSC\U 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;
}

unifdef
在许多操作系统上作为软件包提供(例如FreeBSD、各种Linux发行版、Cygwin)。主页:

好主意。但是,问题是,
ctags
处理的中间文件中的行号将与原始源文件中的行号不同,因此使用ctags跳转到正确的行可能不起作用。尽管如此,我还是会尝试一下。此外,这还会生成将
.h
.c
文件合并到一个文件中的文件,因此不清楚CTAG应该如何找到要跳转到的原始源文件(因为它可能是
.c
文件或包含的
.h
文件之一)。我会看到…预处理器输出应该包括指示源块来自哪些文件和行的指令。ctags是否会尊重这些是个问题。进一步看,我发现ctags有一个选项
−−线−指令
,这似乎是为了使CTAG能够成功地处理每个处理器的输出,并且仍能在原始源文件中找到行。也许这真的会起作用…当然我可以重写代码,但这不是我的项目,我必须在很多地方重写代码。我不认为这是一个解决ctags中缺陷的好方法。有趣的想法(和有趣的工具)。这就是你所说的“统一定义”吗?@sleske-Yup;它在许多操作系统上作为一个软件包提供(例如FreeBSD、各种Linux发行版、Cygwin)。@sleske注意到有几个版本。有些人使用
-b
代替
-l
替换空行。
struct mystruct {
        long member;
}
#ifndef _MSC_VER
__attribute__ ((packed))
#endif
;
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _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;
}
$ 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: