9.16 Debugging Report Programs

What a nice world it would be if all programs written ran correctly the first time. However, most programs seem to have problems from time to time. Most of the problems are quite obvious: output in wrong columns, output not sorted, etc. At times, things are not at all obvious. Such things as totals not being correct, break code executing at the wrong times, etc. This is when you need to enter the world of debugging.

The Report Writer offers two methods of debugging. The first method utilizes the PRINT statement. Program complies go very fast, so there is little time lost in sprinkling your program with some PRINT statements to tell you what is going on. As a suggestion for printing values, when you print something, identify where in the code you are, what it is you are printing, and then the value. This produces rather verbose output, but at least you can follow what is happening. WARNING: Printing variables declared as TOTAL resets them to zero.

The second debugging method is a built-in program trace. This trace shows what is being executed, which procedures are being called, what fields or variables are being used (and their values), and what operations are performed. Note: When a totaling variables value is displayed, it is not reset to zero by the trace feature. A sample trace segment follows:

Line Instr Operand

19 CALL new_subscriber

42 Match First record from file: sub

Starting keyed search.

44 PRINT NL

Line Instr Operand

16 CALL headings

30 PRINT TAB(n)

Push constant = 20

31 PRINT value

Push string = 'S u b s c r i b t i o n L i s t'

32 PRINT TAB(n)

Push constant = 60

32 PRINT value:length

Push variable: 10 todays_date = 08/25/82

Len =

Push constant = 10

32 PRINT value

Push string = 'Page'

33 PRINT value

Push variable: 7 page = 1

33 PRINT NL

34 PRINT value

Push string = 'Subscriber name'

34 PRINT TAB(n)

Push constant = 36

35 PRINT value

Push string = 'Magazine'

35 PRINT TAB(n)

Push constant = 52

35 PRINT value

Push string = 'Date Started'

36 PRINT TAB(n)

Push constant = 68

36 PRINT value

Push string = 'Issues Left'

36 PRINT NL

36 PRINT NL

40 Return

16 Return

44 PRINT value

Push variable: 5 name = Edmond J Brown

48 Return

19 Return

23 Test

Push Eof on file: scripts

False, Goto 24

24 CALL details

50 PRINT TAB(n)

Push constant = 3

50 PRINT value

Push variable: 1 magazine = rd

50 PRINT TAB(n)

Push constant = 52

51 PRINT value

Push variable: 2 started = 01/01/82

51 PRINT TAB(n)

Push constant = 68

51 PRINT value

Push variable: 3 issues = 24

51 PRINT NL

53 Return

24 READ next record, file: scripts

Line Instr Operand

19 CALL new_subscriber

42 Match First record from file: sub

Starting keyed search.

44 PRINT NL

44 PRINT value

Push variable: 5 name = Martha Q Dziedziak

48 Return

19 Return

24 GOTO 23

This trace was produced by running the following program:

1 /* list subscriptions */

3 FILE scripts IS "script" /* subscriptions file */

4 FILE sub IS "sub" /* subscriber file */

6 FIELDS IN scripts ARE

7 subscriber, magazine,

8 started, issues;

10 FIELDS IN sub ARE

11 subscriber, name;

13 MAIN

14 BEGIN

15 AT TOP OF PAGE

16 DO headings;

18 CHECK scripts, AT TOP OF subscriber

19 DO new_subscriber;

21 SELECT FROM scripts

22 SORTED BY subscriber;

23 FOR EACH scripts

24 DO details;

25 END

28 PROCEDURE headings /* print page headings */

29 BEGIN

30 PRINT TAB(20),

31 "S u b s c r i p t i o n L i s t",

32 TAB(60), $todays_date:10 "Page",

33 $page, NL;

34 PRINT "Subscriber name", TAB(36),

35 "Magazine", TAB(52), "Date Started",

36 TAB(68), "Issues Left", NL, NL;

37 END

40 PROCEDURE new_subscriber /* lookup new subscriber */

41 BEGIN

42 FIND IN sub

43 WHERE subscriber EQ scripts.subscriber;

44 PRINT NL, name;

45 END

48 PROCEDURE details /* print one subscription */

49 BEGIN

50 PRINT TAB(36), magazine, TAB(52),

51 started, TAB(68), issues, NL;

52 END

The line numbers are not part of the report program. They are shown here to help line up the line number in the trace output with the line of the report.

It is possible to start the Report Writer with the trace feature enabled. This requires that you use the command wtr(C-1) instead of grace(C-1). This also implies that you must use the command crw(C-1) first. Suppose you wanted to start the report magazine.rpt with the trace feature turned on. The command sequence to do this would be:

crw magazine.rpt

wtr -d a.rw pfile

The last argument in the wtr command, pfile, is used to store the output of the report. This keeps the report output from mingling with the trace output (which can be very confusing!). The only reason you might have starting the Report Writer with the debugger (-d) enabled is to look at the symbol tables that are printed at the beginning.

Most of the trace output is self-explanatory. The only unusual thing printed is the message:

Line Instr Operands

This indicates when the code for a break statement is being executed. There is always a Return associated with this message.

The trace feature can be turned on and off from within a report by setting the report attribute TRACE to a value of true (feature turned on), or false (feature turned off). The Report Writer parameters $TRUE and $FALSE work quite well for this purpose. The following code illustrates turning the trace feature on and off.

SET TRACE := $TRUE; /*program trace is now on */

FOR EACH master

DO details;

SET TRACE := $FALSE; /* program trace is now off */

DO summary;