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)