[comp.lang.postscript] A Tracing Package

cosell@bbn.com (Bernie Cosell) (06/01/90)

I've just finished a fairly mind-hurting excursion into getting some
PostScript code debugged ((a really working version os bbfig, about
which you folks will find out in a day or two when I get a chance to
post it).  BUT... in the course of working on it, I found it _very_
hard to debug: bbfig messes with all of the graphics operators, and it
was computing the bounding box wrong... and I faced the problem of
trying to figure out how to figure out what it was doing.

Unfortunately, around here the serial lines from the printers don't go
anyplace useful (off to the central spool manager, where the info isn't
accessible to ordinary users), and so 'print' and '==' just weren't available.
SO...  I wrote the following package.  What it does is defines a bunch of
printing operators which you can use to sprinkle 'print' statements around in
your postscript file, and what'll happen is that all of the 'printed' text
will be stashed away and you can print it out at your convenience.

For example, with bbfig, I modifed its 'showpage' catcher to call tracedump,
so you'd get <page of drawing> <page of traceinfo> <page of drawing><page of
traceinfo> ... etc.  And as an example of how it could be used, here's a
little snippet of a thing I did to print out the bounding box for bbfig:

% Print out bb's current notion of its bounding box

/bb-debug-bb
{
    (Bounding Box: ) traceprint
    bb-llx bb-lly bb-debug-coord
    (; ) traceprint
    bb-urx bb-ury bb-debug-coord
    (\n) traceprint
} def

% Print out a coordinate on the stack:  x y ---
/bb-debug-coord
{
    (\() traceprint exch trace= (, ) traceprint trace= (\)) traceprint
} def

I'd appreciate comments, improvements, etc, on the package if you care to.

Enjoy

   __
  /  )                              Bernie Cosell
 /--<  _  __  __   o _              BBN Sys & Tech, Cambridge, MA 02138
/___/_(<_/ (_/) )_(_(<_             cosell@bbn.com

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

%!
%   Tracing package for PostScript

%  The idea is to allow you to print out 'interesting' things as your
%   PostScript job runs and thereby let you get some clue as to what is
%   happening.  Some of the printing machinery is based on the ehandler.ps
%   routines described in the Green Book

% Bernie Cosell, BBN, 31 May 1990

/$tracedict 15 dict def

$tracedict begin
/tracing false def    % Whether package is enabled or not
/chunk 100 def        % Number of entries in each array of strings
/list chunk 1 add array def % Head of the chain of strings-to-print
/curlist list def     % Array-chunk currently being filled
/curused 0 def        % Number of strings stored in the current array-chunk

/lmargin 72 def       % Page limits for printing
/tmargin 720 def
end % $tracedict

% - tracebegin - ; Starts the trace package.
/tracebegin
{
    $tracedict begin
    /tracing true store
    end % $tracedict
} def

% - traceend - ; Stop tracing
/traceend
{
    $tracedict begin
    /tracing false store
    end % $tracedict
} def

% <string> traceprint - ; "Print" a string into the trace array
/traceprint
{
    $tracedict begin
    tracing
    {
        curlist curused 3 -1 roll put
        curused 1 add 
        dup chunk ge
        {    % Array is full, add a new one to the chain
	    chunk 1 add array
	    dup curlist 4 2 roll put
	    /curlist exch store
	    0
        } if
        /curused exch store
    }
    {
	pop
    } ifelse
    end % $tracedict
} def

% <any> trace= - ; Produce a text representation of the object on the stack
/trace=
{
    { 25 string cvs } stopped { ( ??? ) } if
    traceprint
} def

% - tracedump -  ; Actually print out the saved trace messages
		 % Assumes that a showpage has been done and we have a page
		 % to ourselves
/tracedump
{
    $tracedict begin
    gsave
    erasepage
    initgraphics
    /Courier findfont 10 scalefont setfont
    lmargin tmargin moveto
    lmargin tmargin 10 sub moveto
    list
    {  % Repeat over all arrays that are not the 'last' array
	dup curlist eq { exit } if  % Hit the last array
	0 1 chunk 1 sub
	    { 1 index exch get traceshow } for
	chunk get
    } loop
%  Now clean up the last chunk
    0 1 curused 1 sub
       { 1 index exch get traceshow } for
    /list exch store
    /curused 0 store
    showpage
    grestore
    end % $tracedict
} def

% - Fancy version of 'show' which knows about CR's
$tracedict begin
/newline (\n) 0 get def
% Utility routine: <char> ifnl - ; goes to left margin if <char> is newline
/ifnl
{
    newline eq
      { currentpoint exch pop lmargin exch moveto 0 -10 rmoveto } 
    if
} def

/traceshow
{
    dup length 0 ne
        { dup 0 get ifnl } if
    { ifnl pop } exch kshow
} def


% Now bind everythign up so we don't get bagged by the user's
%  random definitions..

% key tracebind - ; this will do a 'bind' on the procedure given by 'key'
/tracebind
{
    dup where
    {
	exch
	2 copy
        get 
	systemdict begin
	$tracedict begin
	   bind 
	end end
	put
    } 
    { undefined } ifelse
} def

/tracebegin tracebind
/traceend tracebind
/traceprint tracebind
/trace= tracebind
/tracedump tracebind
/ifnl tracebind
/traceshow tracebind

end % $tracedict