分类: LINUX
2008-09-21 16:53:10
Using Cscope
is a popular utility, and most modern distributions include it. Although Cscope was originally intended only for use with C code, it actually works well with languages like C++ and Java. Cscope comes with an ncurses-based GUI, but it also supports a command-line interface to communicate with other application that can be used as front ends, including major editors such as Emacs and Vim.
When you invoke Cscope, it scans source files in the current
directory and stores the information it collects in its internal
database. You can use the -R
option for Cscope to scan
subdirectories recursively. If you don't want to use Cscope's GUI, but
want to query its database from another application instead (as
described below), use the -b
option. If you're using Cscope on a large or system-related project, consult for additional instructions on how to optimise Cscope to work faster with big sets of files.
By default the GUI front end is activated automatically after you generate the database (or you can use the -d
option to tell Cscope to use a database that has already been
generated). It has a two-panel interface; you enter search queries in
the bottom panel, and results are displayed in the top. You can press
Tab to switch between the panels and Ctrl-D to exit the program.
In the bottom panel, use the arrow keys to move between search fields. Using this panel, you can:
Every time you perform a search, Cscope displays each result with a number, the file name, the name of the function (when applicable), the line number, and the line of code itself. If you select one of the results with the arrow keys and press Enter or the appropriate number key, Cscope will launch the default system editor (set by the EDITOR environment variable) for this file with the cursor positioned on the appropriate line (this may not work for unsupported editors, but Emacs and Vim behave properly).
Using (X)Emacs as the front end
Using Cscope with Emacs is easy. If you don't already have commands starting with cscope-
and a Cscope menu available in Emacs, you can integrate Cscope with
Emacs by installing xcscope.el. You can obtain it from the
contrib/xcscope subdirectory of the Cscope source tarball. Just copy
the cscope-indexer script into some convenient directory in $PATH and
the xcscope.el file to some directory where Emacs can find it (consult
the load-path variable -- ``C-h v load-path``
in Emacs). Then add the line (require 'xcscope)
to ~/.emacs or ~/.emacs.d/init.el.
The comments in the first lines of the xcscope.el file serve as the documentation.
The package adds all the Cscope search commands to the Cscope
submenu on the Emacs menu and makes them available via key bindings
when you're editing source files. For example, if you want to look for
a symbol, either select Cscope -> Symbol in the menu, or type M-x cscope-find-this-symbol
, or press C-c s s
, then enter the symbol name (the word that is under the cursor will be used if you enter nothing).
Search results will be presented in the *cscope* buffer, grouped by
file name and shown as n
or p
to select the next or previous search result (or C-c s n
and C-c s p
when the *cscope* buffer is not active). N
or P
will select the next or previous file (or C-C s N
and C-c s P
Using Cscope from Vim
If you prefer Vim to Emacs, Cscope still has you covered. First of all, your version of Vim should be compiled with the --enable-cscope
option. Most binary Linux distributions do so. Gentoo users should enable the cscope
USE flag. I'll assume that you have Vim 6.x or 7.x. The Vim reference
manual contains an article on using its Cscope interface; you might
find it at /usr/share/vim/vim&version/doc/if_cscop.txt. You can also read a on using Cscope with Vim.
In Vim, you invoke Cscope search commands in this fashion: :cscope find search type search string
(you can type :cs f
instead of cscope find
if you want), where search type can be
symbol
or s
-- find all references to a symbol;global
or g
-- find a global definitioncalls
or c
-- find calls of the specified functioncalled
or d
-- find functions that the specified function callstext
or t
-- find some textfile
or f
-- open a fileinclude
or i
-- find files that #include the specified fileSearch results will be displayed as a menu at the bottom of your Vim
window. You can type the number of the search result you want to jump
to and press Enter. If you use the :scscope
or :scs
command instead of :cscope
, your Vim window will split in two horizontally and the Cscope search result you choose will be put in the new window.
In Vim, jumping to a result from a Cscope query is just like jumping to any tag; you can use Ctrl-T
to pop back to where you were before the search and use :tnext
:tprevious
to cycle through results. and
If you want to invoke search commands for the words under the cursor, you should install the
plugin (just stick this file in the $HOME/.vim/plugin directory).
Documentation for the plugin is contained in its file as comments. When
using this plugin you type Ctrl-\
instead of :cscope
and Ctrl-spacebar
instead of :scscope
,
and the search will be processed for the word that is under the cursor
(e.g. if you move the cursor to the word "initialize" and type Ctrl-\ s
you will invoke the search for references to the symbol "initialize").
SilentBob
Why using SilentBob for generating tags? |
---|
SilentBob uses syntax analysis to parse source files, which makes it faster than a utility like Exuberant Ctags, which uses regular expressions to locate the appropriate line in a file. In a test run on the sources for the Linux kernel (version 2.6.19) Exuberant Ctags generated the tags table in 90 seconds, while SilentBob did its job in 10 seconds (on a 2.6MHz Celeron). SilentBob also supports multithreading optimizations. Another difference is the format of tags tables: In tables created by Exuberant Ctags, regular expressions are used to locate the appropriate line in a file. This means that if you edit the file, and the position of some definition is changed, you don't need to rebuild the tags table. This is good for Exuberant Ctags because it means you don't need to regenerate the table often, but it also means that if you are viewing huge files, jumping to a tag definition will be much slower than if line numbers were used. That's why SilentBob uses line number in its tags tables; however, that means you have to update the tags table after every major edit. |
You can get source tarball and deb packages from the downloads section of the software's site. After installation, invoke SilentBob three times in the directory with source code:
bob --make-ctags
bob --cfiles
bob -L cfiles --call-tags
This will generate three files: tags
, the common tags table; cfiles
, a list of C/C++ files; and call_tags
,
the call tags table. The call tags table contains tags for function
calls, so if you want to find all the calls of some function, you can
point Vim to use the call tags table (:set tags=./call_tags
) and use the same commands as for searching tags (:tag function-name
:tnext
and :tprevious
to cycle through results). These index files can be used by SilentBob to build call trees and backward call trees. and
For Perl and Python, only tags tables and file lists are supported:
bob <--perl | --python> --make-ctagsThe second command will generate a
bob <--perl | --python> --files
perl_files
or python_files
file.
Once you have a tags table, SilentBob can show you a call tree:
bob [--depth N] function
--depth
option allows you to limit the depth of the tree. If the only thing you need to know is which functions are called by function, specify --depth 0
. Otherwise, you will be shown which functions are called by functions called by functions (...) called by function.
Note that you can use this option with the tags table generated by SilentBob for Python and Perl files. Tables generated by Exuberant Ctags are not supported.
The call tags table is used to generate a backward call tree:
bob [--depth N] -u function
This will show functions which call functions (...) which call function. In this case specify --depth 1
to see only functions which call function
SilentBob can also use the created cfiles file to search for text within C/C++ code. It checks operators; strings and comments are ignored.
bob list of files --cgrep pieces of text, separated by comma
You can specify -L ./cfiles
to use generated file list. Pieces of text should be from one operator, so if you are looking for testing of T variable, use:
bob -L ./cfiles --cgrep if,T
SilentBob also includes a tags
utility that lets you to view the tag definitions in a C/C++ file in a console. Invoke tags tag1 tag2 ... tagN
to strip the fragments of code you are interested in from code --
function definitions, global variable declarations, etc. -- and you
will see the fragments of code you need.