C User's Guide |
Chapter 9
cscope:
Interactively Examining a C Program
cscope
is an interactive program that locates specified elements of code in C,lex
, oryacc
source files. Withcscope
, you can search and edit your source files more efficiently than you could with a typical editor. That's becausecscope
supports function calls--when a function is being called, when it is doing the calling--as well as C language identifiers and keywords.This chapter is a tutorial on the
cscope
browser provided with this release and is organized into the following sections:
- The cscope Process
- Basic Use
- Unknown Terminal Type Error
The
cscope
ProcessWhen
cscope
is called for a set of C,lex
, oryacc
source files, it builds a symbol cross-reference table for the functions, function calls, macros, variables, and preprocessor symbols in those files. You can then query that table about the locations of symbols you specify. First, it presents a menu and asks you to choose the type of search you would like to have performed. You may, for instance, wantcscope
to find all the functions that call a specified function.When
cscope
has completed this search, it prints a list. Each list entry contains the name of the file, the number of the line, and the text of the line in whichcscope
has found the specified code. In our case, the list also includes the names of the functions that call the specified function. You now have the option of requesting another search or examining one of the listed lines with the editor. If you choose the latter,cscope
invokes the editor for the file in which the line appears, with the cursor on that line. You can now view the code in context and, if you wish, edit the file as any other file. You can then return to the menu from the editor to request a new search.Because the procedure you follow depends on the task at hand, there is no single set of instructions for using
cscope
. For an extended example of its use, review thecscope
session described in the next section. It shows how you can locate a bug in a program without learning all the code.Basic Use
Suppose you are given responsibility for maintaining the program
prog
. You are told that an error message, out of storage, sometimes appears just as the program starts up. Now you want to usecscope
to locate the parts of the code that are generating the message. Here is how you do it.Step 1: Set Up the Environment
cscope
is a screen-oriented tool that can only be used on terminals listed in the Terminal Information Utilities (terminfo
) database. Be sure you have set theTERM
environment variable to your terminal type so thatcscope
can verify that it is listed in theterminfo
database. If you have not done so, assign a value toTERM
and export it to the shell as follows:In a Bourne shell, type:
$
TERM=
term_name;export TERM
In a C shell, type:
%
setenv TERM
term_name
You may now want to assign a value to the
EDITOR
environment variable. By default,cscope
invokes thevi
editor. (The examples in this chapter illustratevi
usage.) If you prefer not to usevi
, set theEDITOR
environment variable to the editor of your choice and exportEDITOR
, as follows:In a Bourne shell, type:
$
EDITOR=emacs; export EDITOR
In a C shell, type:
%
setenv EDITOR emacs
You may have to write an interface between
cscope
and your editor. For details, see Command-Line Syntax for Editors.If you want to use
cscope
only for browsing (without editing), you can set theVIEWER
environment variable topg
and exportVIEWER
.cscope
will then invokepg
instead ofvi
.An environment variable called
VPATH
can be set to specify directories to be searched for source files. See View Paths.Step 2: Invoke the
cscope
ProgramBy default,
cscope
builds a symbol cross-reference table for all the C,lex
, andyacc
source files in the current directory, and for any included header files in the current directory or the standard place. So, if all the source files for the program to be browsed are in the current directory, and if its header files are there or in the standard place, invokecscope
without arguments:
%
cscope
To browse through selected source files, invoke
cscope
with the names of those files as arguments:
%
cscope
file1.c
file2.c
file3.h
For other ways to invoke
cscope
, see Command-Line Options.
cscope
builds the symbol cross-reference table the first time it is used on the source files for the program to be browsed. By default, the table is stored in the filecscope.out
in the current directory. On a subsequent invocation,cscope
rebuilds the cross-reference only if a source file has been modified or the list of source files is different. When the cross-reference is rebuilt, the data for the unchanged files is copied from the old cross-reference, which makes rebuilding faster than the initial build, and reduces startup time for subsequent invocations.Step 3: Locate the Code
Now let's return to the task we undertook at the beginning of this section: to identify the problem that is causing the error message out of storage to be printed. You have invoked
cscope
, the cross-reference table has been built. Thecscope
menu of tasks appears on the screen.The
cscope
Menu of Tasks:
%cscope
cscope Press the ? key for helpFind this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:
Press the Return key to move the cursor down the screen (with wraparound at the bottom of the display), and
^p
(Control-p) to move the cursor up; or use the up (ua
) and down (da
) arrow keys. You can manipulate the menu and perform other tasks with the following single-key commands:
TABLE 9-1 cscope
Menu Manipulation CommandsTab Move to the next input field. Return Move to the next input field. ^n
Move to the next input field. ^p
Move to the previous input field. ^y
Search with the last text typed. ^b
Move to the previous input field and search pattern. ^f
Move to the next input field and search pattern. ^c
Toggle ignore/use letter case when searching. For example, a search for FILE
matchesfile
andFile
when ignoring the letter case.^r
Rebuild cross-reference. !
Start an interactive shell. Type ^d
to return tocscope
.^l
Redraw the screen. ?
Display the list of commands. ^d
Exit cscope.
If the first character of the text for which you are searching matches one of these commands, you can escape the command by entering a
/
(backslash) before the character.Now move the cursor to the fifth menu item,
Find this text string
, enter the text out of storage, and press the Return key.
cscope
Function: Requesting a Search for a Text String:
$cscope
cscope Press the ? key for helpFind this C symbolFind this global definitionFind functions called by this functionFind functions calling this functionFind this text string:out of storage
Change this text stringFind this egrep patternFind this fileFind files #including this file
Note – Follow the same procedure to perform any other task listed in the menu except the sixth,
Change
this
text
string
. Because this task is slightly more complex than the others, there is a different procedure for performing it. For a description of how to change a text string, see Examples.
cscope
searches for the specified text, finds one line that contains it, and reports its finding.
cscope
Function: Listing Lines Containing the Text String:
Text string: out of storageFile Line1 alloc.c 63 (void) fprintf(stderr, "/n%s: out of storage/n", argv0);Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:
After
cscope
shows you the results of a successful search, you have several options. You may want to change one of the lines or examine the code surrounding it in the editor. Or, ifcscope
has found so many lines that a list of them does not fit on the screen at once, you may want to look at the next part of the list. The following table shows the commands available aftercscope
has found the specified text:
TABLE 9-2 Commands for Use After an Initial Search 1
-9
Edit the file referenced by this line. The number you type corresponds to an item in the list of lines printed by cscope
.Space Display the next set of matching lines. +
Display the next set of matching lines. ^v
Display the next set of matching lines. --
Display the previous set of matching lines. ^e
Edit the displayed files in order. >
Append the list of lines being displayed to a file. |
Pipe all lines to a shell command.
Again, if the first character of the text for which you are searching matches one of these commands, you can escape the command by entering a backslash before the character.
Now examine the code around the newly found line. Enter
1
(the number of the line in the list). The editor is invoked with the filealloc.c
with the cursor at the beginning of line 63 ofalloc.c
.
cscope
Function: Examining a Line of Code:
{return(alloctest(realloc(p, (unsigned) size)));}/* check for memory allocation failure */static char *alloctest(p)char *p;{if (p == NULL) {(void) fprintf(stderr, "/n%s: out of storage/n", argv0);exit(1);}return(p);}~~~~~~~"alloc.c" 67 lines, 1283 characters
You can see that the error message is generated when the variable
p
isNULL
. To determine how an argument passed toalloctest()
could have beenNULL
, you must first identify the functions that callalloctest()
.Exit the editor by using normal quit conventions. You are returned to the menu of tasks. Now type
alloctest
after the fourth item,Find functions calling this function.
cscope
Function: Requesting a List of Functions That Callalloctest()
:
Text string: out of storageFile Line1 alloc.c 63(void)fprintf(stderr,"/n%s: out of storage/n",argv0);Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:alloctest
Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:
cscope
finds and lists three such functions.
cscope
Function:Listing
Functions That Callalloctest()
:
Functions calling this function: alloctestFile Function Line1 alloc.c mymalloc 33 return(alloctest(malloc((unsigned) size)));2 alloc.c mycalloc 43 return(alloctest(calloc((unsigned) nelem, (unsigned) size)));3 alloc.c myrealloc 53 return(alloctest(realloc(p, (unsigned) size)));Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:
Now you want to know which functions call
mymalloc()
.cscope
finds ten such functions. It lists nine of them on the screen and instructs you to press the space bar to see the rest of the list.
cscope
Function:Listing
Functions That Callmymalloc()
:
Functions calling this function: mymalloc File Function Line 1 alloc.c stralloc 24 return(strcpy(mymalloc(strlen(s) + 1), s)); 2 crossref.c crossref 47 symbol = (struct symbol *)mymalloc(msymbols * sizeof(struct symbol)); 3 dir.c makevpsrcdirs 63 srcdirs = (char **) mymalloc(nsrcdirs * sizeof(char*)); 4 dir.c addincdir 167 incdirs = (char **)mymalloc(sizeof(char *)); 5 dir.c addincdir 168 incnames = (char **)mymalloc(sizeof(char *)); 6 dir.c addsrcfile 439 p = (struct listitem *) mymalloc(sizeof(struct listitem)); 7 display.c dispinit 87 displine = (int *) mymalloc(mdisprefs * sizeof(int)); 8 history.c addcmd 19 h = (struct cmd *) mymalloc(sizeof(struct cmd)); 9 main.c main 212 s = mymalloc((unsigned )(strlen(reffile) +strlen(home) + 2)); * 9 more lines - press the space bar to display more *Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:
Because you know that the error message out of storage is generated at the beginning of the program, you can guess that the problem may have occurred in the function
dispinit()
(display initialization).To view
dispinit()
, the seventh function on the list, type7
.
cscope
Function: Viewingdispinit()
in the Editor:
voiddispinit(){/* calculate the maximum displayed reference lines */lastdispline = FLDLINE - 4;mdisprefs = lastdispline - REFLINE + 1;if (mdisprefs > 9) {mdisprefs = 9;}/* allocate the displayed line array */displine = (int *) mymalloc(mdisprefs * sizeof(int));}^L/* display a page of the references */voiddisplay(){char file[PATHLEN + 1]; /* file name */char function[PATLEN + 1];/* function name */char linenum[NUMLEN + 1]; /* line number */int screenline; /* screen line number */int width; /* source line display width */register int i, j;"display.c" 622 lines, 14326 characters
mymalloc()
failed because it was called either with a very large number or a negative number. By examining the possible values ofFLDLINE
andREFLINE
, you can see that there are situations in which the value ofmdisprefs
is negative, that is, in which you are trying to callmymalloc()
with a negative number.Step 4: Edit the Code
On a windowing terminal, you may have multiple windows of arbitrary size. The error message out of storage might have appeared as a result of running
prog
in a window with too few lines. In other words, that may have been one of the situations in whichmymalloc()
was called with a negative number. Now you want to be sure that when the program aborts in this situation in the future, it does so after printing the more meaningful error message screen too small. Edit the functiondispinit()
as follows.
cscope
Function: Correcting the Problem:
voiddispinit(){/* calculate the maximum displayed reference lines */lastdispline = FLDLINE - 4;mdisprefs = lastdispline - REFLINE + 1;if (mdisprefs > 9) {mdisprefs = 9;}/* allocate the displayed line array */displine = (int *) mymalloc(mdisprefs * sizeof(int));}^L/* display a page of the references */voiddisplay(){char file[PATHLEN + 1]; /* file name */char function[PATLEN + 1];/* function name */char linenum[NUMLEN + 1]; /* line number */int screenline; /* screen line number */int width; /* source line display width */register int i, j;"display.c" 622 lines, 14326 characters
You have fixed the problem we began investigating at the beginning of this section. Now if
prog
is run in a window with too few lines, it does not simply fail with the unedifying error message out of storage. Instead, it checks the window size and generates a more meaningful error message before exiting.Command-Line Options
As noted,
cscope
builds a symbol cross-reference table for the C,lex
, and source files in the current directory by default. That is,
%
cscope
is equivalent to:
%
cscope *.[chly]
We have also seen that you can browse through selected source files by invoking
cscope
with the names of those files as arguments:
%
cscope
file1.c
file2.c
file3.h
cscope
provides command-line options with greater flexibility in specifying source files to be included in the cross-reference. When you invokecscope
with the-s
option and any number of directory names (separated by commas):
%
cscope -s
dir1,dir2,dir3
cscope
builds a cross-reference for all the source files in the specified directories as well as the current directory. To browse through all of the source files whose names are listed in file (file names separated by spaces, tabs, or new-lines), invokecscope
with the-i
option and the name of the file containing the list:
%
cscope -i
file
If your source files are in a directory tree, use the following commands to browse through all of them:
%
find . -name '*.[chly]' -print | sort >
file%
cscope -i
file
If this option is selected, however,
cscope
ignores any other files appearing on the command-line.The
-I
option can be used forcscope
in the same way as the-I
option tocc
. See Include Files.You can specify a cross-reference file other than the default
cscope.out
by invoking the-f
option. This is useful for keeping separate symbol cross-reference files in the same directory. You may want to do this if two programs are in the same directory, but do not share all the same files:
%
cscope -f admin.ref admin.c common.c aux.c libs.c
%
cscope -f delta.ref delta.c common.c aux.c libs.c
In this example, the source files for two programs,
admin
anddelta
, are in the same directory, but the programs consist of different groups of files. By specifying different symbol cross-reference files when you invokecscope
for each set of source files, the cross-reference information for the two programs is kept separate.You can use the
-p
n option to specify thatcscope
display the path name, or part of the path name, of a file when it lists the results of a search. The number you give to-p
stands for the last n elements of the path name you want to be displayed. The default is1
, the name of the file itself. So if your current directory ishome/common
, the command:
%
cscope -p2
causes
cscope
to displaycommon/file1.c
,common/file2.c
, and so forth when it lists the results of a search.If the program you want to browse contains a large number of source files, you can use the
-b
option, so thatcscope
stops after it has built a cross-reference;cscope
does not display a menu of tasks. When you usecscope -b
in a pipeline with thebatch
(1) command,cscope
builds the cross-reference in the background:
%
echo 'cscope -b' | batch
Once the cross-reference is built, and as long as you have not changed a source file or the list of source files in the meantime, you need only specify:
%
cscope
for the cross-reference to be copied and the menu of tasks to be displayed in the normal way. You can use this sequence of commands when you want to continue working without having to wait for
cscope
to finish its initial processing.The
-d
option instructscscope
not to update the symbol cross-reference. You can use it to save time if you are sure that no such changes have been made;cscope
does not check the source files for changes.Note – Use the
-d
option with care. If you specify-d
under the erroneous impression that your source files have not been changed,cscope
refers to an outdated symbol cross-reference in responding to your queries.Check the cscope(1) man page for other command-line options.
View Paths
As we have seen,
cscope
searches for source files in the current directory by default. When the environment variableVPATH
is set,cscope
searches for source files in directories that comprise your view path. A view path is an ordered list of directories, each of which has the same directory structure below it.For example, suppose you are part of a software project. There is an official set of source files in directories below
/fs1/ofc
. Each user has a home directory (/usr/you
). If you make changes to the software system, you may have copies of just those files you are changing in/usr/you/src/cmd/prog1
. The official versions of the entire program can be found in the directory/fs1/ofc/src/cmd/prog1
.Suppose you use
cscope
to browse through the three files that compriseprog1
, namely,f1.c
,f2.c
, andf3.c
. You would setVPATH
to/usr/you
and/fs1/ofc
and export it, as in:In a Bourne shell, type:
$
VPATH=/usr/you:/fs1/ofc; export VPATH
In a C shell, type:
%
setenv VPATH /usr/you:/fs1/ofc
You then make your current directory
/usr/you/src/cmd/prog1
, and invokecscope
:
%
cscope
The program locates all the files in the view path. In case duplicates are found,
cscope
uses the file whose parent directory appears earlier inVPATH
. Thus, iff2.c
is in your directory, and all three files are in the official directory,cscope
examinesf2.c
from your directory, andf1.c
andf3.c
from the official directory.The first directory in
VPATH
must be a prefix of the directory you will be working in, usually$HOME
. Each colon-separated directory inVPATH
must be absolute: it should begin at/
.
cscope
and Editor Call Stacks
cscope
and editor calls can be stacked. That is, whencscope
puts you in the editor to view a reference to a symbol and there is another reference of interest, you can invokecscope
again from within the editor to view the second reference without exiting the current invocation of eithercscope
or the editor. You can then back up by exiting the most recent invocation with the appropriatecscope
and editor commands.Examples
This section presents examples of how
cscope
can be used to perform three tasks: changing a constant to a preprocessor symbol, adding an argument to a function, and changing the value of a variable. The first example demonstrates the procedure for changing a text string, which differs slightly from the other tasks on thecscope
menu. That is, once you have entered the text string to be changed,cscope
prompts you for the new text, displays the lines containing the old text, and waits for you to specify which of these lines you want it to change.Changing a Constant to a Preprocessor Symbol
Suppose you want to change a constant,
100
, to a preprocessor symbol,MAXSIZE
. Select the sixth menu item,Change
this
text
string
, and enter/100
. The1
must be escaped with a backslash because it has a special meaning (item 1 on the menu) tocscope
. Now press Return.cscope
prompts you for the new text string. TypeMAXSIZE
.
cscope
Function: Changing a Text String:
cscope Press the ? key for helpFind this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:/100
Find this egrep pattern:Find this file:Find files #including this file:To:MAXSIZE
cscope
displays the lines containing the specified text string, and waits for you to select those in which you want the text to be changed.
cscope
Function: Prompting for Lines to be Changed:
cscope Press the ? key for helpFind this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:/100
Find this egrep pattern:Find this file:Find files #including this file:To:MAXSIZE
You know that the constant
100
in lines 1, 2, and 3 of the list (lines 4, 26, and 8 of the listed source files) should be changed toMAXSIZE
. You also know that0100
inread.c
and100.0
inerr.c
(lines 4 and 5 of the list) should not be changed. You select the lines you want changed with the following single-key commands:
TABLE 9-3 Commands for Selecting Lines to be Changed 1
-9
Mark or unmark the line to be changed. *
Mark or unmark all displayed lines to be changed. Space Display the next set of lines. +
Display the next set of lines. -
Display the previous set of lines. a
Mark all lines to be changed. ^d
Change the marked lines and exit. Esc
Exit without changing the marked lines.
In this case, enter
1
,2
, and3
.The numbers you type are not printed on the screen. Instead,
cscope
marks each list item you want to be changed by printing a>
(greater than) symbol after its line number in the list.
cscope
Function: Marking Lines to be Changed:
Change "100" to "MAXSIZE"File Line1>init.c 4 char s[100];2>init.c 26 for (i = 0; i < 100; i++)3>find.c 8 if (c < 100) {4 read.c 12 f = (bb & 0100);5 err.c 19 p = total/100.0; /* get percentage */Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:Select lines to change (press the ? key for help):
Now type
^d
to change the selected lines.cscope
displays the lines that have been changed and prompts you to continue.
cscope
Function: Displaying Changed Lines of Text:
Changed lines:char s[MAXSIZE];for (i = 0; i < MAXSIZE; i++)if (c < MAXSIZE) {Press the RETURN key to continue:
When you press Return in response to this prompt,
cscope
redraws the screen, restoring it to its state before you selected the lines to be changed.The next step is to add the
#define
for the new symbolMAXSIZE
. Because the header file in which the#define
is to appear is not among the files whose lines are displayed, you must escape to the shell by typing!
. The shell prompt appears at the bottom of the screen. Then enter the editor and add the#define
.
cscope
Function: Exiting to the Shell:
Text string: 100File Line1 init.c 4 char s[100];2 init.c 26 for (i = 0; i < 100; i++)3 find.c 8 if (c < 100) {4 read.c 12 f = (bb & 0100);5 err.c 19 p = total/100.0; /* get percentage */Find this C symbol:Find this global definition:Find functions called by this function:Find functions calling this function:Find this text string:Change this text string:Find this egrep pattern:Find this file:Find files #including this file:$vi defs.h
To resume the
cscope
session, quit the editor and type^d
to exit the shell.Adding an Argument to a Function
Adding an argument to a function involves two steps: editing the function itself and adding the new argument to every place in the code where the function is called.
First, edit the function by using the second menu item,
Find
this
global definition
. Next, find out where the function is called. Use the fourth menu item,Find
functions
calling
this
function
, to obtain a list of all the functions that call it. With this list, you can either invoke the editor for each line found by entering the list number of the line individually, or invoke the editor for all the lines automatically by typing^e
. Usingcscope
to make this kind of change ensures that none of the functions you need to edit are overlooked.Changing the Value of a Variable
At times, you may want to see how a proposed change affects your code.
Suppose you want to change the value of a variable or preprocessor symbol. Before doing so, use the first menu item,
Find
this
C
symbol
, to obtain a list of references that are affected. Then use the editor to examine each one. This step helps you predict the overall effects of your proposed change. Later, you can usecscope
in the same way to verify that your changes have been made.Command-Line Syntax for Editors
cscope
invokes thevi
editor by default. You can override the default setting by assigning your preferred editor to theEDITOR
environment variable and exportingEDITOR
, as described in Step 1: Set Up the Environment. However,cscope
expects the editor it uses to have a command-line syntax of the form:
%
editor +
linenum filename
as does
vi
. If the editor you want to use does not have this command-line syntax, you must write an interface betweencscope
and the editor.Suppose you want to use
ed
. Becauseed
does not allow specification of a line number on the command-line, you cannot use it to view or edit files withcscope
unless you write a shell script that contains the following line:
/usr/bin/ed $2
Let's name the shell script
myedit
. Now set the value ofEDITOR
to your shell script and exportEDITOR
:In a Bourne shell, type:
$
EDITOR=myedit; export EDITOR
In a C shell, type:
%
setenv EDITOR myedit
When
cscope
invokes the editor for the list item you have specified, say, line 17 inmain.c
, it invokes your shell script with the command-line:
% myedit +17 main.c
myedit
then discards the line number ($1
) and callsed
correctly with the file name ($2
). Of course, you are not moved automatically to line 17 of the file and must execute the appropriateed
commands to display and edit the line.Unknown Terminal Type Error
If you see the error message:
Sorry, I don't know how to deal with your "term" terminal
your terminal may not be listed in the Terminal Information Utilities (
terminfo
) database that is currently loaded. Make sure you have assigned the correct value toTERM
. If the message reappears, try reloading the Terminal Information Utilities.If this message is displayed:
Sorry, I need to know a more specific terminal type than "unknown"
set and export the
TERM
variable as described in Step 1: Set Up the Environment.
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |