使用Vim开发软件-程序员的利器CScope

本节所用命令的帮助入口:

 

:help cscope

在前面的文章中介绍了利用 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 的源代码目录中执行下面三条命令:

 

./configure
make
make install

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 -Rbq

这些选项的含义见后面。这个命令会生成三个文件: 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 的源代码为例:

 

cd ~/src/vim70
find . –type f > cscope.files
cscope -bq

这条命令把 ~src/vim70 目录下的所有普通文件都加入了 cscope.files ,这样, cscope 会解析该目录下的每一个文件。上面的 cscope 命令并没有使用“ -R ”参数,因为在 cscope.files 中已经包含了子目录中的文件。

注意 find 命令输出的文件以相对路径表示,所以 cscope.out 的索引也相对于当前路径。如果你要在其它路径中使用当前的 cscope.out ,需要使用下面介绍的 -P 选项。

Cscope 只在第一次解析时扫描全部文件,以后再调用 cscope ,它只扫描那些改动过的文件,这大大提高了 cscope 生成索引的速度。

下表中列出了 cscope 的常用选项:

 

-R:   在生成索引文件时,搜索子目录树中的代码
-b:   只生成索引文件,不进入cscope的界面
-q:   生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度
-k:   在生成索引文件时,不搜索/usr/include目录
-i:   如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到哪儿去找源文件列表。可以使用“-”,表示由标准输入获得文件列表。
-I dir:   在-I选项指出的目录中查找头文件
-u:   扫描所有文件,重新生成交叉索引文件
-C:   在搜索时忽略大小写
-P path:   在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件所在的目录也可以使用它了。

要在 VIM 中使用 cscope 的功能,需要在编译 VIM 时选择“ +cscope ”。 VIM cscope 接口先会调用 cscope 的命令行接口,然后分析其输出结果找到匹配处显示给用户。

VIM 中使用 cscope 非常简单,首先调用“ cscope add ”命令添加一个 cscope 数据库,然后就可以调用“ cscope find ”命令进行查找了。 VIM 支持 8 cscope 的查询功能,如下:

 

s:   查找C语言符号,即查找函数名、宏、枚举值等出现的地方
g:   查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
d:   查找本函数调用的函数
c:   查找调用本函数的函数
t:   查找指定的字符串
e:   查找egrep模式,相当于egrep功能,但查找速度快多了
f:   查找并打开文件,类似vim的find功能
i:   查找包含本文件的文

例如,我们想在 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 setting
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if has("cscope")
  set csprg=/usr/bin/cscope
  set csto=1
  set cst
  set nocsverb
  " add any database in current directory
  if filereadable("cscope.out")
      cs add cscope.out
  endif
  set csverb
endif

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>

下面的两个链接是 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"


你可能感兴趣的:(使用Vim开发软件-程序员的利器CScope)