.+c "Instrumenting Your Program"
.lp
If you're impatient, you need only read the first two sections.
.sh 1 "Using lc"
.lp
The first step is to copy the source from the GCT \fIdemo\fR directory
to your own directory.  (The person who installed GCT can tell you
where the demo files are.)  It is generally a good idea to make a copy
of your source before instrumenting it.  The problem is not so much
GCT - which is careful not to destroy your source - as you.  It's not
unknown for people to get confused, remove the wrong files, and
discover that they've wiped out the original source.
.lp
Take a look at the directory.  You'll see many files.  Some of
the more important are:
.ip "lc.c        "
This is the source for the program you'll instrument.  It's a program
that counts the lines of code and comments in C programs.
.ip "lc.1        "
This is the manpage, suitable for formatting with \fBnroff\fR.
\fIlc.1t\fR is more useful when using \fBtroff\fR output for printing.
.ip Makefile
This is the makefile for the program.
.ip run-suite
This is a test suite driver for \fBlc\fR.  The test data (C programs)
are in the files named \fIlc1\fR, \fIlc2\fR, and so on.  This test suite was developed using
techniques described elsewhere\**, but a few tests were removed for this
tutorial.
.(f
\** Brian Marick,
\*(lqExperience with the Cost of Test Suite Coverage Measures\*(rq,
\fIPacific Northwest Software Quality Conference\fR, October, 1991.
Also available as a compressed postscript file in
cs.uiuc.edu:/pub/testing/experience.ps.Z.
.)f
\fBrun-suite\fR is actually a poor test suite driver.
It doesn't compare the actual output of \fBlc\fR to the
expected output.  It just sends output to /dev/null, so it's useless
for actually finding bugs.  It's fine for this tutorial,
though.
.lp
Type
.nf
\fH
	% make
	% lc lc.c
\fR
.fi
to see how \fBlc\fR works.  You should see this output:
.nf
.ta 4 +4 +5 +5 +4 +4 +5 +4 +4 +4
\fH
% lc lc.c
	Pure	Pure	Both		Total	Total	Total
	Code	Comment	Cod&Com	Blank	Code	Comment	Lines	Pages

lc.c	311	437	62	117	373	499	927	28
\fR
.fi
"Pure Code" means lines of code with no comments, "Pure Comment" means
lines with only comments; "Both Cod&Com" means lines containing both.
"Blank" lines contain neither code nor comments.
.ne 4
.lp
Now type 
.nf
\fH
	% make clean
\fR
.fi
to delete the executables; we'll be building new ones.
.sh 1 "If You're Impatient"
.lp
If you don't care about the step-by-step process of instrumentation,
just type
.nf
\fH
	% make -f Makefile.gct gct
\fR
.fi
and proceed to the next chapter.  If you want to use GCT regularly,
you'll want to read this chapter eventually.
.sh 1 "Deciding What to Measure"
.lp
The first step is to tell GCT what to measure.   That 
information is kept in the file \fIgct-ctrl\fR,
which contains:
.nf
\fH
	(coverage branch multi loop relational)
	lc.c
\fR
.fi
The first line tells GCT we want branch, multi-condition, loop, and
relational operator coverage.  These are the types of coverage I
recommend for detailed testing of code (unit and subsystem testing).
We'll see what these coverages mean when we look at GCT's reports.
Other types of coverage are possible; see the User's Manual.
.lp
The second line tells GCT to measure coverage only for
\fIlc.c\fR.
.sh 1 "Instrumenting the Program"
.lp
The next
step is to \fIinstrument\fR the program so that it collects data about
its execution as it runs.
.lp
To do this, we use a modifed version of the program's original
makefile.  For most makefiles, the changes are minor.  The modified
makefile is the file \fIMakefile.gct\fR.  Examine that file, and
you'll see that there's a target called \fHgct\fR.  But, rather than
using \fBmake\fR, we'll do the instrumentation by hand.  Each
following section explains what a particular line of the \fHgct\fR
target does.  Type the first command in each section to do what
\fBmake\fR would have done.
.sh 2 "Instrumenting"
.lp
\fH% gct-init\fR\**
.lp
.(f
\** If the shell cannot find \fBgct-init\fR, the directory that GCT
was installed in must not be in your search path ($PATH).  Ask the
person who 
installed GCT where it is.
.)f
This program copies a number of files into your directory.  You should
never need to look at the internals of these files, but 
here's what they contain:
.ip gct-ps-defs.h
A makefile usually invokes the C compiler separately for each source
file.  GCT is invoked in the same way.  This file stores information
about where the previous invocation left off.
.ip gct-ps-defs.c
For speed, coverage data is stored in the memory of the instrumented
program.  This
file defines that in-core log; it is linked into the final executable.
.ip gct-write.c
To be useful, the log must outlive the execution of the
program - it must be written to disk.  This program contains a
routine that writes this log.  It also contains a routine that reads
in a previous version of the log, so that the log accumulates over
several tests.
.ip gct-defs.h
This file contains various C macros used to manipulate the log.
.sh 2 Instrumentation
.lp
In this step, we tell the makefile to compile the program in the
normal way, but to use GCT as the "compiler".
.lp
\fH% make all "CC=gct -DTESTING"\fR
.lp
You should see something like this:
.ne 4
.nf
\fH
gct -DTESTING   -c  lc.c
gct -DTESTING -o lc lc.o
\fR
.fi
\fBmake\fR gives \fIlc.c\fR to GCT.  The result is an instrumented
file, also called \fIlc.c\fR.  The makefile then invokes GCT to
produce an executable.  Since GCT sees no C source, it does nothing.
The actual creation of the executable comes later.
.lp
The \fHTESTING\fR define is used to make the instrumented program read
and write the log file.  GCT stores the original source in the file
\fIgct_backup/lc.c\fR.  If you examine that file, you'll see two uses
of the define.
.np
The first is in this code:
.ne 11
.nf
\fH
#ifdef TESTING

myexit(status)
{
  gct_writelog("LOG");
  exit(status);
}
#define exit myexit

#endif
\fR
.fi
This is a standard trick to ensure the log is written out (into the
file \fILOG\fR) any time the program exits.
.np
The second is in \fImain()\fR where
.nf
\fH
    gct_readlog("LOG");
\fR
.fi
is used to read the log (if it exists) when the program starts.
.lp
If you're curious, look inside the instrumented source, in \fIlc.c\fR.
The code is difficult to read, because it's been preprocessed and
because GCT doesn't preserve indentation.  You can recognize
instrumentation by the use of the string "_G".
For a statement like
.nf

	\fHif (function(a))\fR

.fi
GCT replaces it with (in effect):
.nf
\fH
	if ( (\fItemporary\fH=(function(a)), _G2(34, \fItemporary\fH), \fItemporary\fH))
\fR
.fi
The value of the \fHif\fR's test is first saved in a temporary variable.
The \fH_G2\fR macro records whether the \fHif\fR was
taken true or false.  
The branch is the 34th log entry.
Finally, the temporary variable is used as the value of
the \fHif\fR's test, so that the program's execution is unaffected by the
instrumentation.  
\fH_G\fR is a macro that expands out to only a few
instructions, so the instrumented program is not much slower than the
original.  (The amount of slowdown varies, of course, depending on the
program and how much instrumentation you turn on.)
.sh 2 "Compiling Support Code"
.lp
\fH% cc -c gct-ps-defs.c\fR
.br
\fH% cc -c gct-write.c\fR
.lp
This compiles the definitions of \fIgct_writelog\fR,
\fIgct_readlog\fR, and the in-core table that holds the log.
.sh 2 "Making the Executable"
.lp
\fH% make all "OBJ=lc.o gct-ps-defs.o gct-write.o"\fR
.lp
Having instrumented the program, we now need to compile it.  When
making the final executables, we need to link in the files we just
compiled, since the instrumented program refers to their contents.
You should see:
.nf
\fH
cc   -c  lc.c
cc -o lc lc.o gct-ps-defs.o gct-write.o
\fR
.fi
.lp
You now have an instrumented \fBlc\fR.  You'll be able to run tests and get
information about coverage.  This information will refer to the line
numbers in the original (uninstrumented) file.  You certainly do not
want to look at the instrumented file to figure out what the coverage
information is telling you.  
.sh 2 "Restoring the Original Source"
.lp
\fH% grestore\fR
.lp
restores the original source.  You no longer need the instrumented
version.

