Another search technique is “browsing.” Browsing uses information generated by the compiler to help you find pieces of code quickly. This section introduces you to some of the capabilties of the Source Browser. The browser is a handy tool for moving about in projects, large and small.
In addition to navigating through your program, you can use the browser to explore the relationships between parts of the project. The browser database contains full information about where each symbol is defined and used and about the relationships among modules, constants, macros, variables, functions, and classes. Note that the browser files can be very large.
Note :
This section uses the COUNT project you created in Chapter 3. If you did not create this project or if you have since deleted it, you must create it now. For instructions on how to create the COUNT project, see “Creating the Project,”.
Before you can use the PWB Source Browser, you must build a browser database. PWB helps you maintain this database automatically as a part of a normal project build.
·To build a browser database:
1.Open the COUNT project using the Open Project command from the Project menu.
2.From the Options menu, choose Browse Options.
PWB displays the Browse Options dialog box.
3.Select the Generate Browse Information check box.
4.Choose OK.
The browser changes the project makefile to build the project. It adds compiler options for creating browser information (.SBR files). It includes a BSCMAKE command which combines the .SBR files and creates a browser database (a .BSC file).
5.From the Project menu, choose Rebuild All.
Rebuilding the entire project ensures that the database contains up-to-date information for all files in your program.
When the build completes, the following new files are on your disk:
COUNT.BSC, the browser database
COUNTBUF.SBR, a zero-length “placeholder” for COUNTBUF.
COUNTCH.SBR, a placeholder for COUNTCH.
COUNT.SBR, a placeholder for COUNT.
After adding each .SBR file's contribution to the database, BSCMAKE truncates it and leaves the empty .SBR file on disk to provide an up-to-date target for later builds. Leaving these files on the disk ensures that a browser database is not rebuilt unless it is out-of-date with respect to its source files.
A PWB project is not required to create a browser database (although it is convenient). For information on how to build a browser database for non-PWB projects, see “Building Databases for Non-PWB Projects” on page 104.
When you are working on a program, it's easy to forget where a particular variable, constant, or function is defined. You can use the Find command to locate occurrences of a symbol, but that offers little information about which one is the definition. To make such searches easier, you can choose Goto Definition from the Browse menu to jump directly to the definition of any symbol in your program.
The following procedure uses the COUNT project to demonstrate how powerful the browser can be.
·To go to the definition of CountWords:
1.From the Window menu, choose Close All.
2.Open COUNT.C.
3.Move the cursor to the CountWords call on line 80.
4.From the Browse menu, choose Goto Definition.
PWB displays the Goto Definition dialog box.
Notice that CountWords is highlighted and the defining file's name is displayed in the list box to the right. More than one defining file is listed if a name is defined in several scopes.
5.Choose OK.
PWB opens COUNTBUF.C and shows the definition of CountWords.
Often when analyzing an existing program's flow, or when looking for opportunities for optimization, it's useful to refer to a “call tree.” A call tree is a view of your program that provides, for each function, a list of other functions called.
·To generate a call tree of COUNT:
1.From the Browse menu, choose Call Tree.
PWB displays the Display Tree dialog box.
2.Choose COUNT.C from the Modules list box.
Notice that the Functions list box changes to show only the functions in COUNT.C.
3.Choose OK to see the call tree.
The call tree for COUNT.C is as follows:
CountFile
+-fopen?
+-printf[13]?
+-fread?
+-CountWords
| +-Analyze[2]
| +-strchr[3]?
+-fclose?
main
+-CountFile[2]...
+-printf?
+-gets?
Syllables
Three kinds of annotations appear in the call tree:
?
A symbol followed by a question mark is used by your program but not defined in any of the program files in the browse database. These are often library functions.
[n]
The number n between square brackets shows symbols that are used more than once. In the preceding example, CountFile is shown as:
CountFile[2]
This means that there are two references to CountFile in main.
... (ellipsis)
The ellipsis means that the full information for the function appears elsewhere in the call tree.
As you write your program, you will occasionally remove function calls or references to global variables. This can leave unused code in your program or make the program's data larger than it needs to be. The browser database contains information about where every function and variable is referenced, so you can easily find the ones that are not used.
The COUNT project that you have been working with contains an unused function and an unreferenced global variable. This section shows how to use the Source Browser to find and remove the extra code and data.
The system include files define many more functions than many programs use. Therefore, unreferenced functions in your program are easiest to find when using a browser database that does not contain the system include files. This example begins by building a browser database for COUNT that does not contain information defined by system include files.
·To build the COUNT browser database:
1.Make sure that debug options are turned on. Debug options select the fast compiler and do not generate intrinsic functions. If you perform a release build which generates intrinsics, you will find many unused intrinsic functions defined by the compiler. For information on how to select debug options, see “Setting Build Options”.
2.From the Options menu, choose Browse Options.
PWB displays the Browse Options dialog box.
3.In the Browse Options dialog box, turn on the Exclude System Include Files and the Include Unreferenced Symbols check boxes.
4.Choose OK.
Now that the browse options are set, rebuild the project and browser database by choosing Rebuild All from the Project menu. With the updated browser database, you can obtain a list of references for functions and variables.
·To get a list of references for function and variables:
1.From the Browse menu, choose List References.
PWB displays the List References dialog box.
2.Turn on the Functions and Variables options, and then choose OK.
PWB opens the Browser Output window and creates the list of references. Each name is followed by a colon and a list of functions that refer to the name.
FUNCTION CALLED BY LIST
-------- --------------
Analyze: CountWords[2]
CountFile: main[2]
CountWords: CountFile
fclose: CountFile
fopen: CountFile
fread: CountFile
gets: main
main:
printf: main CountFile[13]
strchr: Analyze[3]
Syllables:
·To find an unreferenced symbol:
Search for the regular expression :$.
This pattern specifies a colon at the end of the line. It finds names that are followed by an empty list of references.
PWB positions you at the first unreferenced name (main) in the Browser Output window. The function main must be kept in the program, so you want the next unreferenced name.
To find all unreferenced items with one search, you can perform a logged search and add only <browse> (the Browser Output pseudofile) to the file list. This is especially useful for large projects. Because there are only two unused symbols in the COUNT project, it is simpler to repeat the search.
·To find the next unreferenced symbol:
Execute the Psearch function (press F3) to repeat the regular-expression search.
PWB finds the Syllables function.
·To go to the definition of Syllables in the source:
1.From the Browse menu, choose Goto Definition.
Because the cursor is on Syllables in the Browser Output window, PWB automatically selects the definition.
2.Choose OK.
PWB jumps to the definition of Syllables in COUNT.C where you can remove the unused function. Now you can remove the unused variable by following the same steps.
·To find the unused variable:
1.Return to the Browser Output window.
2.Press F3 to find the next unreferenced variable Consonants.
3.Choose Goto Definition, and then choose OK.
PWB jumps to the definition of Consonants.
You can delete the line to remove the definition of the extra variable. The only remaining cleanup is to remove the declarations for Syllables and Consonants from the COUNT.H file.
Advanced Browser Database Information
In the previous sections, you learned the basics of building a browser database and some useful applications of the Source Browser. In this section, you will find information on what goes into a browser database and how to estimate the disk requirements to build one. You will also learn how to build a database for non-PWB projects and how to build a single database for related projects.
Estimating .SBR and .BSC File Size
When you build a browser database, you first create an .SBR file for each source file in the project. Each of these files contains the following information:
The name of the source file and the files it includes.
Every symbol defined in the source file and the files it includes.
These symbols are the names of all functions, types (including the names of all classes, structures, and enumerations and their members), macros (including symbols in the expanded macro), and variables in the file. These symbols also include all parameters and local variables for the functions.
For C++, the names are the decorated names (names with encoded type information), which can take up about half of the .SBR file size. For more information on decorated names, see Appendix B.
The location of all symbol definitions in the files.
The location of all references to every symbol in the files.
Linkage information.
This is a tremendous amount of information about your program and can therefore occupy a large quantity of disk space. The benefit is that the Source Browser provides fast, sophisticated access to this database of knowledge about your program.
For C source files, the .SBR file is typically half the size of the preprocessed source file (that is, the source file with comments removed, all files included, and all macros expanded).
For C++, the expansion of the .SBR file is from approximately 2 to 20 times the size of the source file. This dramatic expansion occurs because:
More information is defined in C++ include files than in C include files.
The database contains decorated symbol names.
Intuitively, you might assume that the resulting browser database (.BSC file) is approximately the sum of all the .SBR files. However, the browser database is the union of the information in the component .SBR files. This means that the .BSC file is not extrememly large. Much of the information in the .SBR files is defined in include files, which are common to many modules in the project. The union of the .SBR files is relatively small because most of the include-file information is duplicated in each .SBR file.
A 400K .BSC file is common for a modestly sized program. At the time this book was written, the largest known browser database was about four megabytes.
Building Databases for Non-PWB Projects
The simplest way to build a browser database for non-PWB projects is to build the browser database separately from the project. You can use a makefile or a batch file for this purpose. The process requires only two steps:
1.Create an .SBR file for each module. The simplest way to do this is to run the compiler with the options to produce an .SBR file and no other files. For example, the CL command line:
CL /Zs /W0 /Fr *.c
specifies that the compiler processes all .C files in the current directory, checks syntax only ( /Zs) and issues no warnings ( /W0 ). Therefore, no object files are produced. However, browser information (.SBR files) are generated
( /Fr ).
2.Combine the .SBR files into a browser database.
The syntax for this command is:
BSCMAKE options /oproject.BSC *.sbr
For complete information on BSCMAKE options and syntax, see Chapter 21.
The process of creating a browser database changes little between projects. Therefore, you could use a batch file for many projects similar to the following example:
ECHO OFF
REM Require at least one command-line option
IF %1.==. GOTO USAGE
REM Compile to generate only .SBR files
CL /Zs /W0 /Fr *.c
REM Build the browser database
BSCMAKE %2 %3 %4 %5 %6 %7 %8 /o%1.BSC *.sbr
GOTO END
:USAGE
REM Print instructions
ECHO -Usage: %0 project [option]...
ECHO - project Base name of browser database
ECHO - [option]... List of BSCMAKE options
:END
This batch file assumes that all the project sources are in the current directory. It requires that you specify the name of the browser database and allows BSCMAKE options. You may want to change this file to specify different BSCMAKE or compiler options.
If your project's sources are distributed across several directories, you must write a custom batch file or makefile to build the database. For more information on the BSCMAKE utility, see Chapter 21.
·To use a custom browser database in PWB:
1.From the Browse menu, choose Open Custom.
2.Choose the Use Custom Database button.
3.Select your custom browser database and choose OK.
If you want to save this database name permanently, choose Save Current Database.
4.Choose OK.
The PWB Source Browser opens your custom database.
You can now browse your non-PWB project.
If you are using a makefile to build your project, you can choose Open Project from the Project menu and open it as a non-PWB project makefile. If the project makefile has the same base name as the browser database and resides in the same directory, PWB automatically opens the database when you open the project. For more information on using a non-PWB makefile for a project in PWB, see “Using a Non-PWB Makefile”.
If you have two or more closely related projects, you can combine the browser databases for the projects. For example, if two large programs differ only in one or two modules so that most of the sources are shared between the two projects, it can be useful to browse both projects with a single browser database.
·To build a combined browser database:
1.Generate the .SBR files for both projects.
2.Pass all of the .SBR files to BSCMAKE to build the combined database.
The resulting database is the inclusive-OR of the information in the two projects.