探索Linux下面如何阅读代码

1. 参考资料

参考资料:

2. 要点

baidu之后,发现有3点:

  • ctags:可以ctags --version检查本机上安装的ctags是否为下面这个版本,本文接下来的示例即以此ctags进行演练
    flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --version
    Exuberant Ctags 5.9~svn20110310, Copyright (C) 1996-2009 Darren Hiebert
      Compiled: Nov  9 2011, 17:40:39
      Addresses: <dhiebert@users.sourceforge.net>, http://ctags.sourceforge.net
      Optional compiled features: +wildcards, +regex
    flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 
    

  • cscope
  • taglist



3. ctags

当然,要学会游泳,最好的方式就是下水。所以,这里就通过一系列的命令熟悉整个环境。


3.1 建立tags文件

先用最简单的方式进行实践,比如用ctags -R .对当前目录下的文件生成tags文件。

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ll
总用量 368
drwxr-xr-x 4 flying-bird flying-bird  4096  6月 22 10:31 ./
drwxrwxr-x 8 flying-bird flying-bird  4096  6月 18 22:20 ../
-rw-rw-r-- 1 flying-bird flying-bird  1514  6月 18 19:01 Android.mk
-rw-rw-r-- 1 flying-bird flying-bird  1154  6月 18 19:01 Asec.h
-rw-rw-r-- 1 flying-bird flying-bird  2227  6月 18 19:01 CleanSpec.mk
-rw-rw-r-- 1 flying-bird flying-bird 23457  6月 18 19:01 CommandListener.cpp
-rw-rw-r-- 1 flying-bird flying-bird  2466  6月 18 19:01 CommandListener.h
-rw-rw-r-- 1 flying-bird flying-bird 65366  6月 18 19:01 cryptfs.c
-rw-rw-r-- 1 flying-bird flying-bird  5680  6月 18 19:01 cryptfs.h
-rw-rw-r-- 1 flying-bird flying-bird  8518  6月 18 19:01 Devmapper.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1270  6月 18 19:01 Devmapper.h
-rw-rw-r-- 1 flying-bird flying-bird 15543  6月 18 19:01 DirectVolume.cpp
-rw-rw-r-- 1 flying-bird flying-bird  2767  6月 18 19:01 DirectVolume.h
-rw-rw-r-- 1 flying-bird flying-bird  2674  6月 18 19:01 Ext4.cpp
-rw-rw-r-- 1 flying-bird flying-bird   894  6月 18 19:01 Ext4.h
-rw-rw-r-- 1 flying-bird flying-bird  6943  6月 18 19:01 Fat.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1138  6月 18 19:01 Fat.h
-rw-rw-r-- 1 flying-bird flying-bird  4679  6月 18 19:01 fstrim.c
-rw-rw-r-- 1 flying-bird flying-bird   723  6月 18 19:01 fstrim.h
drwxrwxr-x 8 flying-bird flying-bird  4096  6月 18 19:01 .git/
-rw-rw-r-- 1 flying-bird flying-bird  2525  6月 18 19:01 hash.h
-rw-rw-r-- 1 flying-bird flying-bird  7524  6月 18 19:01 Loop.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1294  6月 18 19:01 Loop.h
-rw-rw-r-- 1 flying-bird flying-bird  5063  6月 18 19:01 main.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1440  6月 18 19:01 NetlinkHandler.cpp
-rw-rw-r-- 1 flying-bird flying-bird   949  6月 18 19:01 NetlinkHandler.h
-rw-rw-r-- 1 flying-bird flying-bird  2673  6月 18 19:01 NetlinkManager.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1247  6月 18 19:01 NetlinkManager.h
-rw-rw-r-- 1 flying-bird flying-bird  6542  6月 18 19:01 Process.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1439  6月 18 19:01 Process.h
-rw-rw-r-- 1 flying-bird flying-bird  1334  6月 18 19:01 ResponseCode.cpp
-rw-rw-r-- 1 flying-bird flying-bird  2865  6月 18 19:01 ResponseCode.h
drwxrwxr-x 2 flying-bird flying-bird  4096  6月 18 19:01 tests/
-rw-rw-r-- 1 flying-bird flying-bird  4249  6月 18 19:01 vdc.c
-rw-rw-r-- 1 flying-bird flying-bird   732  6月 18 19:01 VoldCommand.cpp
-rw-rw-r-- 1 flying-bird flying-bird   839  6月 18 19:01 VoldCommand.h
-rw-rw-r-- 1 flying-bird flying-bird   819  6月 18 19:01 VoldUtil.c
-rw-rw-r-- 1 flying-bird flying-bird   810  6月 18 19:01 VoldUtil.h
-rw-rw-r-- 1 flying-bird flying-bird 19816  6月 18 19:01 Volume.cpp
-rw-rw-r-- 1 flying-bird flying-bird  3328  6月 18 19:01 Volume.h
-rw-rw-r-- 1 flying-bird flying-bird 48540  6月 18 19:01 VolumeManager.cpp
-rw-rw-r-- 1 flying-bird flying-bird  5585  6月 18 19:01 VolumeManager.h
-rw-rw-r-- 1 flying-bird flying-bird  2037  6月 18 19:01 Xwarp.cpp
-rw-rw-r-- 1 flying-bird flying-bird  1049  6月 18 19:01 Xwarp.h
flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags -R .
flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ll tags 
-rw-rw-r-- 1 flying-bird flying-bird 48915  6月 22 10:34 tags
flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 


3.2 了解tags文件

tags文件的内容包括宏、class、member function、function等所在的文件。示例如下:



tags文件一开始是注释信息,接下来是tags list,每一行的格式:tag name, file name, line number, tag kind. 其中kind含义如下:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --list-kinds=c
c  classes
d  macro definitions
e  enumerators (values inside an enumeration)
f  function definitions
g  enumeration names
l  local variables [off]
m  class, struct, and union members
n  namespaces
p  function prototypes [off]
s  structure names
t  typedefs
u  union names
v  variable definitions
x  external and forward variable declarations [off]
flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --list-kinds=c++
c  classes
d  macro definitions
e  enumerators (values inside an enumeration)
f  function definitions
g  enumeration names
l  local variables [off]
m  class, struct, and union members
n  namespaces
p  function prototypes [off]
s  structure names
t  typedefs
u  union names
v  variable definitions
x  external and forward variable declarations [off]
flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 


3.3 打开tag所在的文件

然后用vim -t tagName命令,就可以打开tagName定义所在的文件,并自动定位到tagName所在的那一行。

示例:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ vim -t usage

上述命令的执行效果:


要了解这一点,可以查看vim命令的帮助即可:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ vim -h
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:10:09)

用法: vim [参数] [文件 ..]       编辑指定的文件
  或: vim [参数] -               从标准输入(stdin)读取文本
  或: vim [参数] -t tag          编辑 tag 定义处的文件
  或: vim [参数] -q [errorfile]  编辑第一个出错处的文件

参数:
   --			在这以后只有文件名
   -g			使用图形界面 (同 "gvim")
   -f  或  --nofork	前台: 启动图形界面时不 fork
   -v			Vi 模式 (同 "vi")
   -e			Ex 模式 (同 "ex")

上面这个功能还是非常强的,因为经常需要查找某个函数的定义,用上面这个命令就非常方便了。


3.4 ts & tp & tn

这3个命令的全称分别是tag list, tag preview, tag next. 

前面介绍了可以用vim -t tagName打开一个source file,如果在多个文件中定义了多个名为tagName的language objects,那么这个vim命令也只是打开第一个包括了tagName的这个文件。——包括相同tag名称的文件,是按照文件名进行排序。

此时,可以通过ts来参考当前tagName还存在于哪些文件中。作为例子,我们以整个Android源码创建tags文件。然后执行vim -t usage命令:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ ll tags
-rw-rw-r-- 1 flying-bird flying-bird 1920673761  6月 22 11:00 tags
flying-bird@flying-bird:~/android/android_4.4.2_r2$ vim -t usage

效果如下:



此时执行:ts看usage这个tag一共出现了几次:



这里显示了所有的usage。对于这种有多屏的情况,可以键入空格翻到下一屏。要跳转到目标文件,先Esc,此时屏幕最下面提示输入数字&回车:



比如输入231,然后回车,就自动打开对应的文件:


是不是非常方便?!


注意此时打开的是第231个usage的文件。此时:tn就是打开下一个即232 usage对应的文件,即在当前序号下跳转到下一个文件。对应地,可以练习tp的效果。如果要跳转很远的地方、或直接通过目录&文件名来跳转,还是像前面的操作那样,即输入:ts,列出所有的usage列表,上下翻屏,然后输入数字。


如此,通过:ts, :tp, :tn等就可以快速找到目标tag的位置。


3.5 Ctrl + ]

这个命令也非常有用,其作用是跳转到当前光标所在tag的所在。比如说当前行有一个函数调用,光标在这个函数调用处,通过在命令模式下输入Ctrl+]就可以跳转到该函数定义的地方。

相对应地,如果要再回到上次这个函数调用处呢?就是在命令模式下输入Ctrl+T。

再强调一下,这两个输入不需要先:,而是直接Ctrl+] 和 Ctrl+T。


比如下面这个例子,注意光标的位置(104行):



此时键入Ctrl+]之后,就是下面的效果:



如果再次Ctrl+T就回到上一次的地方。


需要补充的是,上面两个命令的跳转并不局限于当前打开的文件,而可以在vim的多个文件之间,必要情况下,会自动打开新的文件。


3.6 :ta tag

:ta tag是要先输入:的vim命令,它的作用是跳转到tag的定义所在。下面这个示例是以整个Android源码系统创建的tag file来操作,比如在某个文件中输入了:ta VolumeManager,如下:


回车后,就会打开VolumeManager所在的文件:



4. cscope

4.1 安装

直接从ubuntu软件中心,输入cscope,安装cscope.sourceforge.net对应的cscope即可。或者到这个网站上下载代码安装。


检查安装是否成功:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ cscope --version
cscope: version 15.7a
flying-bird@flying-bird:~/android/android_4.4.2_r2$ cscope --help
Usage: cscope [-bcCdehklLqRTuUvV] [-f file] [-F file] [-i file] [-I dir] [-s dir]
              [-p number] [-P path] [-[0-8] pattern] [source files]

-b            Build the cross-reference only.
-C            Ignore letter case when searching.
-c            Use only ASCII characters in the cross-ref file (don't compress).
-d            Do not update the cross-reference.
-e            Suppress the <Ctrl>-e command prompt between files.
-F symfile    Read symbol reference lines from symfile.
-f reffile    Use reffile as cross-ref file name instead of cscope.out.
-h            This help screen.
-I incdir     Look in incdir for any #include files.
-i namefile   Browse through files listed in namefile, instead of cscope.files
-k            Kernel Mode - don't use /usr/include for #include files.
-L            Do a single search with line-oriented output.
-l            Line-oriented interface.
-num pattern  Go to input field num (counting from 0) and find pattern.
-P path       Prepend path to relative file names in pre-built cross-ref file.
-p n          Display the last n file path components.
-q            Build an inverted index for quick symbol searching.
-R            Recurse directories for files.
-s dir        Look in dir for additional source  files.
-T            Use only the first eight characters to match against C symbols.
-U            Check file time stamps.
-u            Unconditionally build the cross-reference file.
-v            Be more verbose in line mode.
-V            Print the version number.

Please see the manpage for more information.
flying-bird@flying-bird:~/android/android_4.4.2_r2$ 


4.2 分析源代码文件

首先准备要分析的文件列表,然后用cscope命令进行分析:

find . -name "*.h" > cscope.files
find . -name "*.c" >> cscope.files
find . -name "*.cc" >> cscope.files
find . -name "*.cpp" >> cscope.files
find . -name "*.java" >> cscope.files
cscope -bkq -i cscope.files


最后生成的文件:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ ll cs*
-rw-rw-r-- 1 flying-bird flying-bird   17915097  6月 22 13:44 cscope.files
-rw-rw-r-- 1 flying-bird flying-bird   62021632  6月 22 13:51 cscope.in.out
-rw-rw-r-- 1 flying-bird flying-bird 1082712155  6月 22 13:51 cscope.out
-rw-rw-r-- 1 flying-bird flying-bird  777698136  6月 22 13:51 cscope.po.out
flying-bird@flying-bird:~/android/android_4.4.2_r2$ 

4.3 配置cscope

http://cscope.sourceforge.net/cscope_vim_tutorial.html下载csope_maps.vim,并拷贝到/etc/vim/目录下。修改vimrc文件,让它source这个文件:

flying-bird@flying-bird:/etc/vim$ ll
总用量 36
drwxr-xr-x   2 root root  4096  6月 22 14:07 ./
drwxr-xr-x 136 root root 12288  6月 22 08:42 ../
-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim
-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc
-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc
-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tiny
flying-bird@flying-bird:/etc/vim$ sudo vi vimrc
flying-bird@flying-bird:/etc/vim$ cat vimrc
" All system-wide defaults are set in $VIMRUNTIME/debian.vim (usually just
。。。。。。。。。。。。。。。。。。
" Source a global configuration file if available
if filereadable("/etc/vim/vimrc.local")
  source /etc/vim/vimrc.local
endif

if filereadable("/etc/vim/cscope_maps.vim")
  source /etc/vim/cscope_maps.vim
endif

flying-bird@flying-bird:/etc/vim$ 

4.4 使用

4.4.1 打开vim

可以使用vim打开一个文件,如:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ gvim -t VolumeManager

此时,和ctags打开第一个定义tag的文件不同的是,现在会首先把所有文件都列出来,供你选择:


4.4.2 Ctrl + \ + S

当光标落在某个tag,此时按下Ctrl + \ + S(快速顺序按下),就会列出这个tag所有出现的地方。示例:


和ctags一样,Ctrl + T会跳会上一次的地方。


4.4.3 多窗口

通过gvim的菜单调出”文件浏览器“窗口;还可以把下面的output窗口拉出来,从而形成多窗口。效果:



5. taglist

5.1 下载&安装

http://vim-taglist.sourceforge.net/index.html下载,比如taglist_46.zip。

安装方法可以参考http://vim-taglist.sourceforge.net/installation.html

5.1.1 filetype on

有文档提到要设置filetype on.

在/etc/vim/vimrc中,有这么一段话:

" Uncomment the following to have Vim load indentation rules and plugins
" according to the detected filetype.
"if has("autocmd")
"  filetype plugin indent on
"endif

经过验证,没有打开这个注释,下面的各项操作也是可以的。


5.1.2 system

在vim或者gvim环境中,输入“:echo exists('*system')”,其结果要求为1.


5.1.3 解压缩taglist

flying-bird@flying-bird:/etc/vim$ ll
总用量 36
drwxr-xr-x   2 root root  4096  6月 22 14:08 ./
drwxr-xr-x 136 root root 12288  6月 22 17:44 ../
-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim
-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc
-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc
-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tiny
flying-bird@flying-bird:/etc/vim$ sudo cp ~/taglist_46.zip .
[sudo] password for flying-bird: 
flying-bird@flying-bird:/etc/vim$ ll
总用量 88
drwxr-xr-x   2 root root  4096  6月 22 19:08 ./
drwxr-xr-x 136 root root 12288  6月 22 17:44 ../
-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim
-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc
-rw-r--r--   1 root root 51455  6月 22 19:08 taglist_46.zip
-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc
-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tiny
flying-bird@flying-bird:/etc/vim$ sudo unzip taglist_46.zip -d .
Archive:  taglist_46.zip
  inflating: ./plugin/taglist.vim    
  inflating: ./doc/taglist.txt       
flying-bird@flying-bird:/etc/vim$ 

5.1.4 helptags

cd到doc目录,以root用户启动vim,然后输入:helptags .命令:

flying-bird@flying-bird:/etc/vim$ cd doc/
flying-bird@flying-bird:/etc/vim/doc$ ll
总用量 80
drwxr-xr-x 2 root root  4096  6月 22 19:08 ./
drwxr-xr-x 4 root root  4096  6月 22 19:08 ../
-rwxr-xr-x 1 root root 69979  2月 26  2013 taglist.txt*
flying-bird@flying-bird:/etc/vim/doc$ sudo vim
flying-bird@flying-bird:/etc/vim/doc$ 

执行之后会在docs目录下面生成一个tags文件。


5.2 效果

以上配置完成之后,重启vim或gvim。输入:TlistToggle命令即可打开左边的符号窗口,或者输入:help taglist调出taglist的帮助窗口。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值