本节所用命令的帮助入口:
在前面的文章中介绍了利用 ctags 生成的 tag 文件,跳转到标签定义的地方。但如果想查找函数在哪里被调用,或者标签在哪些地方出现过, ctags 就无能为力了,这时需要使用更为强大的 cscope 。
Cscope 具有纯正的 Unix 血统,它最早是由贝尔实验室为 PDP-11 计算机开发的,后来成为商用的 AT&T Unix 发行版的组成部分。直到 2000 年 4 月,这个工具才由 SCO 公司以 BSD license 开源发行。
Cscope 的主页在 http://cscope.sourceforge.net/ ,如果你的计算机上没有 cscope ,你可以在此处下载它,在写本文时,它的最新版本是 15.6 。安装它非常简单,你只需要在 cscope 的源代码目录中执行下面三条命令:
在 windows 上也可以使用 cscope ,在 cscope 的主页上可以下载到由 DJGPP 编译器编译的 windows 版的 cscope ,不过这个版本不能和 VIM 一起工作。或者你可以下载 cygwin 工具包 (http://www.cygwin.com/ ) ,这个工具包中也包含了 cscope 。
在 http://iamphet.nm.ru/cscope/ 有 Sergey Khorev 预编译的一个 Win32 版本的 cscope ,这个版本的 cscope 可以很好的与 windows 版本的 VIM 搭配使用。
要使用 cscope 的强大功能,首先需要为你的代码生成一个 cscope 数据库。生成数据库很简单,在你的项目根目录运行下面的命令:
这些选项的含义见后面。这个命令会生成三个文件: cscope.out, cscope.in.out, cscope.po.out 。其中 cscope.out 是基本的符号索引,后两个文件是使用 "-q" 选项生成的,可以加快 cscope 的索引速度。
在缺省情况下, cscope 在生成数据库后就会进入它自己的查询界面,我们一般不用这个界面,所以使用了“ -b ”选项。如果你已经进入了这个界面,按 CTRL-D 退出。
Cscope 在生成数据库中,在你的项目目录中未找到的头文件,会自动到 /usr/include 目录中查找。如果你想阻止它这样做,使用“ -k ”选项。
Cscope 缺省只解析 C 文件 (.c 和 .h) 、 lex 文件 (.l) 和 yacc 文件 (.y) ,虽然它也可以支持 C++ 以及 Java ,但它在扫描目录时会跳过 C++ 及 Java 后缀的文件。如果你希望 cscope 解析 C++ 或 Java 文件,需要把这些文件的名字和路径保存在一个名为 cscope.files 的文件。当 cscope 发现在当前目录中存在 cscope.files 时,就会为 cscope.files 中列出的所有文件生成索引数据库。通常我们使用 find 来生成 cscope.files 文件,仍以 VIM 7.0 的源代码为例:
这条命令把 ~src/vim70 目录下的所有普通文件都加入了 cscope.files ,这样, cscope 会解析该目录下的每一个文件。上面的 cscope 命令并没有使用“ -R ”参数,因为在 cscope.files 中已经包含了子目录中的文件。
注意 : find 命令输出的文件以相对路径表示,所以 cscope.out 的索引也相对于当前路径。如果你要在其它路径中使用当前的 cscope.out ,需要使用下面介绍的 -P 选项。
Cscope 只在第一次解析时扫描全部文件,以后再调用 cscope ,它只扫描那些改动过的文件,这大大提高了 cscope 生成索引的速度。
下表中列出了 cscope 的常用选项:
要在 VIM 中使用 cscope 的功能,需要在编译 VIM 时选择“ +cscope ”。 VIM 的 cscope 接口先会调用 cscope 的命令行接口,然后分析其输出结果找到匹配处显示给用户。
在 VIM 中使用 cscope 非常简单,首先调用“ cscope add ”命令添加一个 cscope 数据库,然后就可以调用“ cscope find ”命令进行查找了。 VIM 支持 8 种 cscope 的查询功能,如下:
例如,我们想在 VIM 7.0 的源代码中查找调用 do_cscope() 函数的函数,我们可以输入:“ :cs find c do_cscope ”,回车后发现没有找到匹配的功能,可能并没有函数调用 do_cscope() 。我们再输入“ :cs find s do_cscope ”,查找这个 C 符号出现的位置,现在 VIM 列出了这个符号出现的所有位置。
我们还可以进行字符串查找,它会双引号或单引号括起来的内容中查找。还可以输入一个正则表达式,这类似于 egrep 程序的功能,但它是在交叉索引数据库中查找,速度要快得多。
VIM 提供了一些选项可以调整它的 cscope 功能:
<!--[if !supportLists]-->- <!--[endif]-->cscopeprg 选项用于设置 cscope 程序的位置。
<!--[if !supportLists]-->- <!--[endif]-->cscopequickfix 设定是否使用 quickfix 窗口来显示 cscope 的结果,详情请“ :help cscopequickfix ”;
<!--[if !supportLists]-->- <!--[endif]-->如果你想 VIM 同时搜索 tag 文件以及 cscope 数据库,设置 cscopetag 选项;
<!--[if !supportLists]-->- <!--[endif]-->cscopetagorder 选项决定是先查找 tag 文件还是先查找 cscope 数据库。设置为 0 则先查找 cscope 数据库,设置为 1 先查找 tag 文件。我通常设置为 1 ,因为在 tag 文件中查找到的结果,会把最佳匹配列在第一位。
VIM 的帮助页中给出了使用 cscope 的建议方法,使用命令“ :help cscope-suggestions ”查看。
下面是我的 vimrc 中关于 cscope 接口的设置:
下面的两个链接是 cscope 主页提供的 cscope 使用方法,也可以作为参考:
VIM/cscope 指导: http://cscope.sourceforge.net/cscope_vim_tutorial.html
在大项目中使用 cscope : http://cscope.sourceforge.net/large_projects.html
在 VIM 的网站上有很多与 cscope 相关的插件,有兴趣可以去看一下。这里是搜索结果: 点这里 。
我以前写的一篇关于 VIM/ctag/cscope 的文章:
http://blog.csdn.net/easwy/archive/2006/08/31/1150909.aspx
[ 参考文档 ]
<!--[if !supportLists]-->1. <!--[endif]-->VIM 帮助文件
<!--[if !supportLists]-->2. <!--[endif]-->http://vimcdoc.sourceforge.net/
<!--[if !supportLists]-->3. <!--[endif]-->http://cscope.sourceforge.net/
<!--[if !supportLists]-->4. <!--[endif]-->http://iamphet.nm.ru/cscope/
<!--[if !supportLists]-->5. <!--[endif]-->cscope 手册
[ 尾记 ]
本文可以自由应用于非商业用途。转载请注明出处。
原文链接: http://blog.csdn.net/easwy
vim+cscope的使用
在vim中,使用Cscope来快速定位函数的定义,查找函数的原型,很方便。
在我Fedora8的机器中,已经默认安装了cscope这个程序。
刚刚使用cscope,不是很熟悉,很多“先进的”功能留待以后慢慢挖掘。 这里先写一下vim中简单的使用cscope,以便能够在源代码中:
1. 快速切换至函数的定义。
2. 函数的声明.
3. 查找某个函数被使用的情况。
首先,让vim支持cscope,在~/.vimrc中加入:
"set cscopequickfix=s-,c-,d-,i-,t-,e-"
其次,要在源代码目录内生成相关的cscope的信息.
这里以libpcap代码为例
#cd /usr/code/libpcap
#cscope -Rbq
#把生成的cscope文件导入到vim中来
#:cs add /usr/code/libpcap/cscope.out /usr/code/libpcap/
下面就可以在vim中进行实际演练操作了.
1.把光标移到某个函数上,使用Ctrl+],就可以跳到函数的定义中.
2.查找某个函数的声明和定义:
:cs find g strcpy
3.如果出现找出多个函数声明和定义的情况,可以使用quickFix窗口进行选择切换:
:cw
另外,更多功能可以查找相关的帮助,以下转载了一些cs find的技巧. 可以用得着.
-----以下为转载的. 作者(吴垠)
--------http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx
cscope的主要功能是通过同的子命令"find"来实现的
"cscope find"的用法:
cs find c|d|e|f|g|i|s|t name
0 或 s | 查找本 C 符号(可以跳过注释) |
1 或 g | 查找本定义 |
2 或 d | 查找本函数调用的函数 |
3 或 c | 查找调用本函数的函数 |
4 或 t | 查找本字符串 |
6 或 e | 查找本 egrep 模式 |
7 或 f | 查找本文件 |
8 或 i | 查找包含本文件的文件 |
如果每次查找都要输入一长串命令的话还真是件讨人厌的事情, Cscope的帮助手册中推荐了一些快捷键的用法, 下面是其中一组, 也是我用的, 将下面的内容添加到~/.vimrc中, 并重启vim:
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR> nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR> nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR> nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR> nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR> nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR> nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR> nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR> |
当光标停在某个你要查找的词上时, 按下<C-_>g, 就是查找该对象的定义, 其他的同理.
按这种组合键有一点技巧,按了<C-_>后要马上按下一个键,否则屏幕一闪就回到nomal状态了
<C-_>g的按法是先按"Ctrl+Shift+-", 然后很快再按"g"在vim中,使用Cscope来快速定位函数的定义,查找函数的原型,很方便。
在我Fedora8的机器中,已经默认安装了cscope这个程序。
刚刚使用cscope,不是很熟悉,很多“先进的”功能留待以后慢慢挖掘。 这里先写一下vim中简单的使用cscope,以便能够在源代码中:
1. 快速切换至函数的定义。
2. 函数的声明.
3. 查找某个函数被使用的情况。
首先,让vim支持cscope,在~/.vimrc中加入:
"set cscopequickfix=s-,c-,d-,i-,t-,e-"
其次,要在源代码目录内生成相关的cscope的信息.
这里以libpcap代码为例
#cd /usr/code/libpcap
#cscope -Rbq
#把生成的cscope文件导入到vim中来
#:cs add /usr/code/libpcap/cscope.out /usr/code/libpcap/
下面就可以在vim中进行实际演练操作了.
1.把光标移到某个函数上,使用Ctrl+],就可以跳到函数的定义中.
2.查找某个函数的声明和定义:
:cs find g strcpy
3.如果出现找出多个函数声明和定义的情况,可以使用quickFix窗口进行选择切换:
:cw
另外,更多功能可以查找相关的帮助,以下转载了一些cs find的技巧. 可以用得着.
-----以下为转载的. 作者(吴垠)
--------http://blog.csdn.net/wooin/archive/2007/10/31/1858917.aspx
cscope的主要功能是通过同的子命令"find"来实现的
"cscope find"的用法:
cs find c|d|e|f|g|i|s|t name
0 或 s | 查找本 C 符号(可以跳过注释) |
1 或 g | 查找本定义 |
2 或 d | 查找本函数调用的函数 |
3 或 c | 查找调用本函数的函数 |
4 或 t | 查找本字符串 |
6 或 e | 查找本 egrep 模式 |
7 或 f | 查找本文件 |
8 或 i | 查找包含本文件的文件 |
如果每次查找都要输入一长串命令的话还真是件讨人厌的事情, Cscope的帮助手册中推荐了一些快捷键的用法, 下面是其中一组, 也是我用的, 将下面的内容添加到~/.vimrc中, 并重启vim:
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR> nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR> nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR> nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR> nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR> nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR> nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR> nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR> |
当光标停在某个你要查找的词上时, 按下<C-_>g, 就是查找该对象的定义, 其他的同理.
按这种组合键有一点技巧,按了<C-_>后要马上按下一个键,否则屏幕一闪就回到nomal状态了
<C-_>g的按法是先按"Ctrl+Shift+-", 然后很快再按"g"