ctags 生成系统头文件、第三方库头文件的 tag

ctags为系统头文件目录生成tags

 

  

经常需要远程登录到Linux服务器上改配置、写程序,我使用的编辑器是vim。vim它小快灵,网络速度慢也能工作,并且vim+ctags+cscope的组合能很好的满足编程的时候经常用到的代码跳转功能,比如查看函数原型、符号智能补全、查找符号被引用处等。

 

但ctags为系统提供的头文件生成的索引总是不太对。比如对于/usr/include/sys/socket.h,里面有很多函数在ctags 处理的时候没有能加到索引里去。最后发现是__TRHOW的问题。以listen函数为例,在socket.h中,它的原型是:

 

extern int listen (int __fd, int __n) __THROW;

 

socket.h间接包含了sys/cdefs.h,__THROW就是在这个头文件中被定义的。其定义如下:

 

# if !defined __cplusplus && __GNUC_PREREQ (3, 3)        
# define __THROW       __attribute__ ((__nothrow__))    
# define __NTH(fct)    __attribute__ ((__nothrow__)) fct
# else                                                   
# if defined __cplusplus && __GNUC_PREREQ (2,8)         
#   define __THROW      throw ()                         
#   define __NTH(fct)   fct throw ()                     
# else                                                  
#   define __THROW                                       
#   define __NTH(fct)   fct                              
# endif                                                 
# endif                                                 

 

如果gcc正在编译c++文件,并且gcc版本大于2.8那么__THROW会被定义为throw()。如果正在编译c文件并且gcc版本在2.8 之前,__THROW则是一个空的宏定义,如果版本大于3.3,则__THROW被定义成一个attribute内包含的nothrow的形式。最后这个 形式表示这段c代码不会抛出异常。

 

正是这个复杂的宏定义干扰了ctags,对于所有像listen这样含有__THROW的原型,ctags一律都不能正确解析。其原因是ctags 本身不是一个编译器也没有专门的预处理器,它是通过直接解析源文件的语法来工作的,不进行语义的检查和宏展开。对于宏,它的能力仅限于识别定义、调用和简 单的条件编译的猜测。

 

为了不让__THROW干扰ctags,需要在运行ctags时使用-I选项。我一般使用下面的命令生成系统头文件tags

 

ctags -I __THROW --file-scope=yes --langmap=c:+.h --languages=c,c++ --links=yes --c-kinds=+p --fields=+S  -R -f ~/.vim/systags /usr/include /usr/local/include

 

其关键是-I __THROW部分和--c-kinds=+p部分。设置-I后,ctags会在处理文件时,就会忽略-I后面写出来的符号。而--c-kinds=+p 则告诉ctags需要为函数原型的声明也生成tag。--langmap=c:+.h表示.h视为c文件而不是c++文件。

 

最后,设置你的~/.vimrc,加入一行:
set tags+=~/.vim/systags
就可以享受系统库函数名补全、原型预览等功能了。

 

以前一直用Visual Studio写程序,这些功能都是已经有了的,不需要自己配置。在VIM里使用ctags、cscope和taglist插件和适当的配置一样可以达到同样的效果,而且有写地方还更方便了。

 http://blog.sina.com.cn/s/blog_8cd2fe830102vxg4.html

以上可用。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ctags 生成系统头文件、第三方库头文件的 tag

原文地址:http://blog.csdn.net/zklth/article/details/7027798

ctags 处理系统头文件问题提出:

vim编写程序时,不能跳转到系统头文件定义,不能自动完成自己编写结构成员。需要解决。

ctags 在使用vim编程和浏览代码是非常有用。可以用CTRL+]和CTRL+t 来回跳转关键字。
先生成自己工作目录的tags。最简单粗暴用法:

$cd yourwork
$ctags -R *
这样会生成一个tags文件。
不过,这种有个问题,成员变量没有包含在里面。所以自动完成对象的成员时没有提示。
解决办法:

$ctags -R –fields=+iaS –extra=+q *
–fields=[+|-]flags
–fields指定tags的可用扩展域(extension fields),以包含到tags入口。
i:继承信息Inheritance information
a:类成员的访问控制信息 Access (or export) of class members
S: 常规签名信息,如原型或参数表 Signature of routine(e.g. prototype or parameter list)
–extra=[+|-]flags
指定是否包含某种扩展信息到tags入口。
q:包含类成员信息(如c++,java,Eiffel)。
但就算是C 语言的结构,也需要这两个参数设置才能获取成员信息。

这样就能自动完成结构和类的成员了。

但是,对于系统的函数,还是没有跳转。如socket定义,inetaddr_in这样的结构没有自动变量完成。
最简单做法:

$ctags –fields=+iaS –extra=+q -R -f ~/.vim/systags /usr/include /usr/local/include
然后在.vimrc里设置

set tags+=~/.vim/systags
这样虽然基本能跳转到系统函数定义,一个问题是某些系统函数并没有加入到systags里。
如/usr/incluce/socket.h的socket系列函数,memset等很多关键函数都没有到tag里:

extern int listen (int __fd, int __n) __THROW;
这是因为 __THROW的宏定义让ctags不再认为该系列函数是函数。
同理,如memcpy系列函数:
如/usr/include/string.h的

extern int strcmp (__const char *__s1, __const char *__s2)
__THROW __attribute_pure__ __nonnull ((1, 2));
还有attribute_pure ,nonull等属性,都需要忽略。如果需要#if 0里面的定义,可以–if0=yes来忽略 #if 0这样的定义。

$ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ –file-scope=yes –langmap=c:+.h –languages=c,c++ –links=yes –c-kinds=+p –c++-kinds=+p –fields=+iaS –extra=+q -R -f ~/.vim/systags /usr/include /usr/local/include
这样.vim/systags里面是全的,但内容过多。一个函数定义的跳转,会有几十个候选。这时我们可以简化一下,将-R去掉,自己指定目录:

$ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ –file-scope=yes –langmap=c:+.h –languages=c,c++ –links=yes –c-kinds=+p –c++-kinds=+p –fields=+iaS –extra=+q  -f ~/.vim/systags /usr/include/* /usr/include/sys/* /usr/include/bits/*  /usr/include/netinet/* /usr/include/arpa/* /usr/include/mysql/*
还可以包含一些自己编程需要的路径。注意后面加*号。
这样生成的系统tags就少多了。不会有太多不相干的定义。

在机器上只需要执行以下脚本即可,将相关目录加上即可。

[plain] view plaincopy

  1. ==============================================================================
  2. #!/bin/bash
  3.  
  4. #
  5. # File: ctags.sh
  6. # Author: zhankunlin
  7. # Date: 2011-11-30
  8. # Desc: ctags 生成系统库以及ACE, SQLITE, ORACLE相关函数的tags, 存放于 ~/.vim/systags 文件中
  9. #
  10.  
  11. mkdir -p ~/.vim;
  12.  
  13. ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ –file-scope=yes –langmap=c:+.h –languages=c,c++ –links=yes –c-kinds=+p –c++-kinds=+p –fields=+iaS –extra=+q  -f ~/.vim/systags /usr/include/* /usr/include/sys/* /usr/include/bits/*  /usr/include/netinet/* /usr/include/arpa/* /sdb1/development/ACE-5.8.0/include/* /sdb1/development/sqlite3/include/* /sdd1/oracle/11gR2_database_X64/product/11.2.0.1.0/db_1/rdbms/public/*
  14.  
  15. printf ‘\n\n”ctags”
  16. “=========================”
  17. set tags+=~/.vim/systags
  18. “=========================”‘ >> ~/.vimrc
  19.  
  20. ================================================================================

Posted in Uncategorized and tagged linux on May 30, 2013. Leave a comment

ctags索引系统头文件与结构体

在使用VIM的过程中,虽然VIM能提供补全功能,但碰到了两个严重的问题,一是定义在系统头文件中函数无法索引;二是结构体不能够自动补全。

解决方法如下:

ctags --fields=+iaS --extra=+q -R -f ~/systags /usr/include /usr/local/include

之后在 /etc/vimrc 中添加:

set tags+=~/systags

紧接着碰到了另外一个问题,包含特殊宏的函数与结构,依然无法索引:

ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ --file-scope=yes --langmap=c:+.h --languages=c,c++ --links=yes --c-kinds=+p --c++-kinds=+p --fields=+iaS --extra=+q -R -f ~/systags /usr/include /usr/local/include

接着又碰到一个问题,索引速度过慢,查找定义时,返回结构过多,去掉-R,自行制定头文件路径,但这个需要明确的知道会调用到哪些文件:

ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ --file-scope=yes --langmap=c:+.h --languages=c,c++ --links=yes --c-kinds=+p --c++-kinds=+p --fields=+iaS --extra=+q -f ~/systags /usr/include/* /usr/include/sys/* /usr/include/bits/* /usr/include/netinet/* /usr/include/arpa/* /usr/include/mysql/*

参考:
[1].ctags 处理系统头文件
[2].ctags为系统头文件目录生成tags

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值