[comp.sources.d] CPR bugfix, manual page

dmt@pegasus.ATT.COM (Dave Tutelman) (11/30/89)

A couple of followup points on CPR:
   -	A fix to a bug, which seems to bite on Suns, pointed out by
	Mel Melchner and John Limpert.
   -	A non-bug fix suggested by John Limpert.
   -	An "application note" from Mike Slomin, for MSDOS users.
   -	A manual page, provided by Mike Slomin.
Thanks for the help!

THE BUG:
Suns core dump trying to print the synopsis.  It IS a bug (sorry, folks)
and the systems I used were just more tolerant of wrong code.  The fix,
in file cpr.c, is:


Change line 161, to be
	"-	File name for the Standard Input.",
-->	NULL
	};

Change line 353, to be
-->	for (i=0; synopsis[i]; i++)
		fprintf (stderr,"%s\n",synopsis[i]);


NON-BUG PROBLEM, noticed by John Limpert:

Some C compilers get confused by 'c=*p', they attempt to parse it
   as 'c =* p', the old style assignment operator syntax.  Changing
   the code to 'c= *p' removes this ambiguity.

*** report.c.orig	Mon Nov 27 16:05:11 1989
--- report.c	Mon Nov 27 17:38:25 1989
***************
*** 293,299
           {
              char *p;
              char c;
!             for(p=name1; c=*p; p++ )
                 if( islower(c) ) *p=toupper(c);
              for(p=name2; c=*p; p++ )
                 if( islower(c) ) *p=toupper(c);

--- 293,299 -----
           {
              char *p;
              char c;
!             for(p=name1; c= *p; p++ )
                 if( islower(c) ) *p=toupper(c);
              for(p=name2; c= *p; p++ )
                 if( islower(c) ) *p=toupper(c);
***************
*** 295,301
              char c;
              for(p=name1; c=*p; p++ )
                 if( islower(c) ) *p=toupper(c);
!             for(p=name2; c=*p; p++ )
                 if( islower(c) ) *p=toupper(c);
           }
  

--- 295,301 -----
              char c;
              for(p=name1; c= *p; p++ )
                 if( islower(c) ) *p=toupper(c);
!             for(p=name2; c= *p; p++ )
                 if( islower(c) ) *p=toupper(c);
           }



APPLICATION NOTES, from Mike Slomin:

If cpr is
compiled in MSC5.1, it apparently is rather stack intensive,
and the stack should be set to 32768 (the easiest way is
to do this in the link using the /stack flag, otherwise it
can be done with 'exemod').  Even in TurboC, I would guess
that the stack can be run out - especially since Borland
defaults it to 128 bytes. 
>>>	I hadn't noticed any problem with my Turbo version, and I've
>>>	been using it heavily.  Dave T.

While I normally vary the stack
size by using the MS linker and the /stack flag, it can be
done using
		extern int _stklen = 16384;
before main() in a TURBOC 1.5 or 2.0 environment.  I've
compiled the program both ways, in MSC5 and TC2, and found
that it runs about 25% faster in the TC version.


MANUAL PAGE, from Mike Slomin:
=============================== Cut Here ===================
.deTH
.PD
.nrIN \\n()Mu
.ift .ds ]H \\$1\^(\^\\$2\^)
.ifn .ds ]H \\$1\\$2
.if\\n()s .ds ]D
.if\\n()t .ds ]D MS-DOS
.ifn .ds ]D MS-DOS
.ds]L
.if!\\$3 .ds ]L (\^\\$3\^)
.if!\\$4 .ds ]D \\$4
.wh0 }H
.wh-\\n(:mu }F
.em}M
.if\\n(nl .bp
.nr)I \\n()Mu
.nr)R 0
.}E
.DT
.ifn \{.na
.nh\}
.ift \{.bd S 3 3
.hy14 \}
..
.TH CPR.EXE
.SH NAME
.B cpr
\- 'pretty print' C files
.SH SYNOPSIS
.B cpr
[
.B \-cCnNsSxX
] [
.B \-T title
] [
.B \-t tabwidth
] 
.br
[
.B \-l pagelength
] [
.B \-w pagewidth
] [
.B \-p space
] 
.br
[
.B \-r blanklines
] [
.B \-f argument_file
] [
.B \-
]
.SH DESCRIPTION
.I cpr
prints the files named in its argument list, preceding the output
with a table of contents.  If a filename is preceded by 
.B \-f
the specified file is assumed to contain a list of files to be
printed.  The filename "-" specifies the standard input.  Each file
printed is assumed to be C source code (but does not have to, see
.B \-c
below) and the program searches for the beginning and end of
functions.  Function names are added to the table of contents,
provided the name starts at the beginning of a line.  The function
name in the output is double struck.
.P
By default, blank lines are inserted after every closing '}'
character.  Thus, functions and structure declearations are
nicely isolated in the output.  The only drawback to this is
that structure initialization tables sometimes produce
excessive white space.  The
.B \-r num
option changes this space or removes it, see below.
.P
Because of the limitations of \fIcpr\fR (see below), it is not
fully a substitute for \fIcb\fR(1), and in some cases it will
be best first to process files through \fIcb\fR before they
are formatted for printing by this program.
.sp 1
.SH OPTIONS
.SH ""
.SS "PAGE SIZE OPTIONS - "
.TP
.B \-l num
\fInum\fR specifies the page length in the printout.  Default
is 66.
.TP
.B \-w num
\fInum\fR specifies the page width.  Lines are folded to that width,
using a reasonably aesthetic folding algorithm.  The default, in
the absence of
.B \-w
is not to fold lines.
.SS "LINE NUMBERING OPTIONS - "
.TP
.B \-n
Number output lines with the corresponding line number from the
input file.
.TP
.B \-N
Page numbers start at 1 for each file processed.
.if n bp
.SS "PROGRAM FORMATTING OPTIONS - "
.TP
.B \-p num
Determines what proportion of the page in steps of 16 should be
used for deciding if a new function needs a new page.  That is,
.B \-p12
(the default) indicates that if a function starts within the top
12/16 (three quarters) of the page, print the function on that page;
otherwise, print it on a new page.  The higher the number (up to 16)
the closer to the bottom new functions will be started. 
.B \-p0
means that each function will start on a new page.
.TP
.B \-r num
Determines how many blank lines are inserted after every
closing '}' character.  If no number is specified after
.B \-r
no space is left.  The default is 5.
.SS "TABLE OF CONTENTS OPTIONS - "
The table of contents includes a list of files and the page
numbers on which they begin, followed by an index of functions.
If none of the following are selected, the functions will be
listed in their order of appearance, by file.
.TP
.B \-s
Sort the index of functions by function name within each file.
.TP
.B \-S
Sort the index of functions by function name within each file using
a case-insensitive sort.
.TP
.B \-x
Sort the index of functions across all files (like \fIxref\fR).
.TP
.B \-X
Sort the index of functions across all files using a case-insensitive
sort.
.TP
.B \-C
Print only the table of contents, not the source files.
.TP
.B \-c
Examine only files with the extension '.c' for files to list in
the table of contents.
.TP
.B \-T file
The contents of \fIfile\fR will be printed before the table of
contents (i.e., as a title).
.SS "MISCELLANEOUS OPTIONS - "
.TP
.B \-t num
Width of a tabstop (default is 8).
.TP
.B \-f argfile
The contents of the file
.I argfile
are to be treated as command line arguments.  (Thus, you can make
a "cpr.rc" file in DOS, or ".cprrc" file in *NIX, with the proper
options, to initialize \fIcpr\fR to the options you wish.)
.TP
.B \-?
A help screen will be sent to stderr (generally the screen), but
no processing will be done.  This help screen is more verbose than
the usage message printed on error, and briefly summarizes the command
line options.
.SH FILES
/tmp/cpr$$	- temp files holding text (*nix)
.br
\&.\ecpr*.tmp	- temp files holding text (DOS)
.SH LIMITATIONS
This program sometimes thinks some declarations are 
functions.  Function declarations whose opening '(' is 
not found on the same line as the function name will not be
recognized as functions.  Use of macros to define functions will
also confuse it.  Comments are not recognized, and #ifdef's are
not processed, so stuff inside them gets interpreted.  If the same
function definition appears multiple times on the same page, only
one entry is made in the table of contents to reduce the number
of redundant entries.
.SH HISTORY
Written by:
.in +.5i
Paul Breslin,
Human Computing Resources Corp.,
10 St. Mary Street,
Toronto, Ontario, Candada, M4Y 1P9
.br
\&...!decvax!utcsrgv!hcr!phb
.in -.5i

Sorting and use of standard input:
.in +.5i
Rick Wise,
CALCULON Corp.,
Rockville, MD
.br
\&...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
.in -.5i

File modified time, numbered output, optional white space, improved
function start tests:
.in +.5i
David Wasley,
Univ. Calif. Berkeley
.br
\&...!ucbvax!topaz.dlw
.in -.5i

Variable number of lines between functions:
.in +.5i
Patrick Powell,
Univ. of Waterloo
.in -.5i

Variable tabs, redundant table of contents suppression:
.in +.5i
Ian D. Allen,
Univ. of Waterloo
.in -.5i

Handling of form feeds to start a new page and print headings:
.in +.5i
Terry Doner,
Univ. of Waterloo
.in -.5i

Additional options (i.e, -S, -N, -T, -c, -C, -f) and 
better function recognition.  It will find:
.nf
	struct foo *f()
but not:
	int
	f
	()
.fi
The constraint is that the () must appear on the same line as the
function name.
.in +.5i
Dennis Vadura,
Univ. of Waterloo
.br
\&...dvadura@dragon
.in -.5i

Cleaned up a bit for 80286 machines (lints a bit cleaner too):
.in +.5i
Dan Frank,
Prairie Computing
.in -.5i

Ported to TurboC on MSDOS, enabled wildcard expansion for systems
that do not support it, broke big source file into several C files
plus header, fixed argument parsing to be more forgiving, changed
\-f option to handle all args in a free-form file and not just
filenames, added options (-?, -x, -X, -w):
.in +.5i
Dave Tutelman,
AT&T Bell Labs
.br
\&...att!pegasus!dmt
.SH "SEE ALSO"
cb(1), cat(1), fold(1), num(1), pr(1)