home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume6
/
cpr
< prev
next >
Wrap
Text File
|
1989-03-20
|
32KB
|
1,319 lines
Newsgroups: comp.sources.misc
From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Subject: v06i067: CPR a pretty printer for lots of C sources
Reply-To: Dennis Vadura <dvadura@watdragon.waterloo.edu>
Distribution: world
Organization: Computer Science Dept., University of Waterloo
Posting-number: Volume 6, Issue 67
Submitted-by: dvadura@watdragon.waterloo.edu (Dennis Vadura)
Archive-name: cpr
# This is a listing program for C sources, but handles other stuff as well. It
# pretty prints the specified files, and creates a table of contents.
# We use it arround here a lot.
#
# I posted this program to comp.sources about 3 years ago and it was quite
# popular. I have since improved the function finding ability, fixed up the
# handling of tabs and added a bunch of new features. So I decided to submit
# it again. It now compiles under DOS as well. There is no makefile, but
# the first two lines of cpr.c give the command lines to use for compiling it.
#
# This shar file contains:
# cpr.c - the C source for cpr
# cpr.t - the troff source for the man page
# cpr.p - preformatted version of the manpage.
#------------------------------------------------------------------------------
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watdragon!dvadura on Tue Feb 7 17:05:23 EST 1989
# Contents: cpr.c cpr.p cpr.t
echo x - cpr.c
sed 's/^@//' > "cpr.c" <<'@//E*O*F cpr.c//'
/* if UNIX: cc -O cpr.c
* if MSDOS: cc -O -DMSDOS cpr.c
*
* This program prints the files named in its argument list, preceding
* the output with a table of contents. Each file is assumed to be C
* source code (but doesn't have to be) in that 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 striken.
*
* By default blank space is inserted after every closing '}'
* character. Thus functions and structure declarations are nicely
* isolated in the output. The only drawback to this is that structure
* initialization tables sometimes produce lots of white space.
* The "-r" option removes this space, or changes it to the indicated
* length.
*
* The option "-l" indicates that the following argument is to be
* the page length used for output (changing the page length hasn't been
* tested much).
*
* The option "-s" indicates that the table of contents should be sorted
* by function name within each file.
*
* The option "-n" indicates that output lines should be numbered with
* the corresponding line number from the input file.
*
* The option "-p" indicates what proportion of the page in steps of 16
* should be used for deciding if a new function needs a new page.
* That is -p12 (the default) indicates that if a function starts
* within the top 12/16 (3/4) of the page then do it, otherwise put it
* on a new page. Thus the higher the number (upto 16) the closer to
* the bottom of the page will functions be started. -p0 says put each
* func on a new page.
*
* Try it! You'll like it. (I call it cpr.c)
*
* Written by:
* Paul Breslin
* Human Computing Resources Corp.
* 10 St. Mary St.
* Toronto, Ontario
* Canada, M4Y 1P9
*
* -- ...!decvax!utcsrgv!hcr!phb
*
* Sorting and standard input reading from:
* Rick Wise, CALCULON Corp., Rockville, MD.
* -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
*
* File modified time,
* numbered output,
* optional white space,
* improved function start tests from:
* David Wasley, U.C.Berkeley
* -- ...!ucbvax!topaz.dlw
* Modified the -r to leave variable amounts of space
* Patrick Powell, U. Waterloo
*
* Changed handling of form feeds to start a new page AND print heading:
* Terry Doner, U of Waterloo
*
* Fixed up to locate more functions, and added -p option
* Dennis Vadura, U of Waterloo
*
* It will find things like struct foo *f()...
* but not things like int
* f
* ()...
* ie. the constraint is that the () must appear on the same line
* as the function name.
*
* Clean up a bit for 80286 machines (lints a bit cleaner, too)
* Dan Frank, Prairie Computing
*
* Fixed a whole bunch of stuff and added lots of new flags.
* -S sort and be case insensitive.
* -N start numbering pages at 1 for each new file
* -T title cat the file title before the table of contents.
* -C print only the table of contents
* -c only try to look for function names in files whose suffix ends
* in .c
* -f file to handle file containing list of files to print. (for MSDOS)
* Dennis Vadura
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <string.h>
extern int errno; /* system error number */
extern char *sys_errlist[]; /* error message */
extern char *malloc() ; /* important for 8086-like systems */
#define BP 0xC /* Form feed */
#define TOC_SIZE 4096
#define NEWFILE 1
#define NEWFUNCTION 2
FILE *File;
int Braces; /* Keeps track of brace depth */
int LineNumber; /* Count output lines */
int PageNumber = 0; /* You figure this one out */
int PageLength = 66; /* -l <len> Normal paper length */
int PagePart = 12; /* Decision on paging for new fn*/
int PageEnd; /* Accounts for space at bottom */
int SawFunction;
int InComment;
int InString;
int Title=0;
int ResetPage=0;
int ContentsOnly=0;
int CaseInsensitive=0;
int OnlyCFiles=0;
long FileLineNumber; /* Input file line number */
char *TitleFile;
char *ProgName;
char Today[30];
char *Name; /* Current file name */
char FunctionName[80];
char FileDate[24]; /* Last modified time of file */
char SortFlag; /* -s == sort table of contents */
char NumberFlag; /* -n == output line numbers */
int Space_to_leave = 5; /* -r<number> space to leave */
int TabWidth = 0; /* -t <number> width of tabs */
main(argc, argv)
char **argv;
{
register int i;
char *ctime();
time_t thetime, time();
char *parm;
int c;
ProgName = argv[0];
thetime = time((time_t *)0);
strcpy(Today,ctime(&thetime));
for( i=1; argc > i; ++i )
{
if( argv[i][0] != '-'
|| argv[i][1] == '\0' ) break;
parm = argv[i];
while( c = *++parm ) switch( c ){
case 'f': goto endofoptions;
case 't':
if( argc < 3 ) Usage();
TabWidth = atoi(argv[++i]);
if( TabWidth < 0 )
TabWidth = 0;
break;
case 'T':
if( argc < 3 ) Usage();
TitleFile = argv[++i];
++Title;
break;
case 'l':
if( argc < 3 ) Usage();
PageLength = atoi(argv[++i]);
if( PageLength < 10) PageLength = 10;
break;
case 'S':
++CaseInsensitive;
case 's':
++SortFlag;
break;
case 'C':
++ContentsOnly;
break;
case 'c':
++OnlyCFiles;
break;
case 'n':
++NumberFlag;
break;
case 'N':
++ResetPage;
break;
case 'r':
if( (c = parm[1]) && isdigit( c )
&&( c = atoi( parm+1 )) > 0 ){
Space_to_leave = c;
}
else {
Space_to_leave = 0;
}
while( *parm ){
++parm;
}
--parm;
break;
case 'p':
if( (c = parm[1]) && isdigit( c )
&&( c = atoi( parm+1 )) >= 0 ){
PagePart = (c <= 16) ? c: 16;
}
while( *parm ){
++parm;
}
--parm;
break;
default:
Usage();
break;
}
}
endofoptions:
PageEnd = PageLength - ((PageLength > 30) ? 7 : 1);
StartTempFile();
if( i == argc )
{ /* no file names */
File = stdin;
Name = "Standard Input";
List();
}
for(; i < argc; ++i )
{
if( strcmp(argv[i], "-") == 0 )
{
File = stdin;
Name = "Standard Input";
List();
}
else if( strcmp(argv[i], "-f") == 0 )
{
char b[1024];
FILE *listf;
i++;
if( i == argc )
{
fprintf(stderr,"%s: missing file name for -f option\n", ProgName );
exit(1);
}
if( (listf = fopen( argv[i], "r" )) == NULL )
{
fprintf(stderr,"%s: list file '%s', not found\n", ProgName,
argv[i] );
exit(1);
}
while( fgets(b, 1024, listf) != NULL )
{
if( strlen(b) ) b[strlen(b)-1]=0;
if( strcmp(b, "-") != 0 )
{
if( (File = fopen( Name = b, "r" )) == NULL )
{
fprintf(stderr,"%s: Can't open file '%s': %s\n",
ProgName, Name, sys_errlist[errno] );
continue;
}
}
else
File = stdin;
List();
if( File != stdin ) fclose(File);
}
}
else {
if( (File = fopen( Name = argv[i], "r" )) == NULL )
{
fprintf(stderr,"%s: Can't open file '%s': %s\n",
ProgName, Name, sys_errlist[errno] );
continue;
}
List();
if( File != stdin ) fclose(File);
}
}
if( PageNumber > 1 || LineNumber > 0 )
putchar(BP);
EndTempFile();
DumpTableOfContents();
DumpTempFiles();
Done();
}
Usage()
{
fprintf(stderr, "Usage: %s [-cCnNsS] [-T title] [-t tabwidth] [-p[num]] [-r[num]] [-l pagelength] [[-f] file] ...\n",
ProgName);
exit(1);
}
int SaveOut;
char *TempName;
char *Temp2Name;
StartTempFile()
{
int Done();
extern char *mktemp();
CatchSignalsPlease(Done);
SaveOut = dup(1);
#ifdef MSDOS
TempName = "cpr0001.tmp";
#else
TempName = mktemp("/tmp/cprXXXXXX");
#endif
if( freopen(TempName, "w", stdout) == NULL )
{
fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
TempName, sys_errlist[errno]);
exit(1);
}
}
EndTempFile()
{
#ifdef MSDOS
Temp2Name = "cpr0002.tmp";
#else
Temp2Name = mktemp("/tmp/cprXXXXXX");
#endif
if( freopen(Temp2Name, "w", stdout) == NULL )
{
fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
Temp2Name, sys_errlist[errno]);
exit(1);
}
}
DumpTempFiles()
{
FILE *f;
char b[256];
register int pid, w;
fclose(stdout);
#ifndef MSDOS
dup(SaveOut);
while( (pid = fork()) < 0 ) sleep(1);
if( pid )
while ((w = wait((int *)0)) != pid && w != -1);
else
{
CatchSignalsPlease(SIG_DFL);
if( ContentsOnly )
execl( "/bin/cat", "cat", Temp2Name, (char *)0 );
else
execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
sys_errlist[errno]);
exit(0);
}
#else
CatchSignalsPlease(SIG_DFL);
if( (f=fopen(Temp2Name,"r")) == NULL )
fprintf(stderr,"%s: Can't open file '%s': %s\n",
ProgName, TitleFile, sys_errlist[errno] );
else
{
while( fgets(b, 256, f) != NULL )
write(SaveOut,b,strlen(b));
fclose(f);
}
if( !ContentsOnly )
if( (f=fopen(TempName,"r")) == NULL )
fprintf(stderr,"%s: Can't open file '%s': %s\n",
ProgName, TitleFile, sys_errlist[errno] );
else
{
while( fgets(b, 256, f) != NULL )
write(SaveOut,b,strlen(b));
fclose(f);
}
#endif
}
Done()
{
CatchSignalsPlease(SIG_DFL);
fclose( stdout );
if( TempName ) unlink( TempName );
if( Temp2Name ) unlink( Temp2Name );
exit(0);
}
CatchSignalsPlease(action)
int (*action)();
{
if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action);
#ifndef MSDOS
if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action);
#endif
}
List()
{
register int bp;
register char *bufp;
char buffer[256];
NewFile();
bp = Braces = 0;
InString = InComment = 0; /* reset for new file -DV */
SawFunction = 0;
bufp = buffer;
while( fgets(bufp, sizeof(buffer), File) != NULL )
{
++FileLineNumber;
if( bp ) NewFunction();
if( ++LineNumber >= PageEnd ) NewPage();
if( bufp[0] == '\f'
&& bufp[1] == '\n'
&& bufp[2] == '\0' )
{
NewPage(); /* was strcpy(bufp, "^L\n");*/
continue;
}
if( NumberFlag )
{
if( *bufp == '\n' )
printf(" ");
else
printf("%6ld ", FileLineNumber);
}
if( (Braces == 0) && LooksLikeFunction(bufp) )
AddToTableOfContents(NEWFUNCTION);
bp = PutLine(buffer);
}
}
PutLine(l)
register char *l;
{
extern char *EndComment();
extern char *EndString();
register char c;
int bp;
char *save;
bp = 0;
for( save = l; c = *l; ++l )
if( InComment )
l = EndComment(l);
else if( InString )
l = EndString(l);
else
switch(c)
{
case '{':
++Braces;
break;
case '}':
if( --Braces == 0 )
bp = 1;
break;
case '\'':
for( ++l; *l && *l != '\''; ++l )
if( *l == '\\' && *(l+1) ) ++l;
break;
case '"':
InString = 1;
break;
case '/':
if( *(l+1) == '*' )
{
InComment = 1;
++l;
}
break;
}
printf("%s", save);
return(bp);
}
char *
EndComment(p)
register char *p;
{
register char c;
/*
* Always return pointer to last non-null char looked at.
*/
while( c = *p++ )
if( c == '*' && *p == '/' )
{
InComment = 0;
return(p);
}
return(p-2);
}
char *
EndString(p)
register char *p;
{
register char c;
/*
* Always return pointer to last non-null char looked at.
*/
while( c = *p++ )
if( c == '\\' && *p )
{
++p;
continue;
}
else if( c == '"' )
{
InString = 0;
return(p-1);
}
return(p-2);
}
NewFunction()
{
register int i;
if( Space_to_leave <= 0 || !SawFunction ) return;
if( LineNumber + Space_to_leave > (PageLength * PagePart /16) )
NewPage();
else
{
for( i=0; i < (Space_to_leave); ++i ) putchar('\n');
LineNumber += Space_to_leave;
}
SawFunction = 0;
}
#define HEADER_SIZE 3
NewPage()
{
if( PageNumber >= 0 ) ++PageNumber;
putchar(BP);
LineNumber = 0;
PutHeader();
}
PutHeader()
{
register int i, l, j;
putchar('\n');
++LineNumber;
l = strlen(Name);
for( j=0; j < l; ++j )
printf("%c\b%c\b%c", Name[j], Name[j], Name[j]);
if( PageNumber > 0 )
{
printf(" %.17s", FileDate);
GoToColumn(l+19, 70);
printf("Page:%4d\n\n", PageNumber);
++LineNumber;
++LineNumber;
}
else
{
GoToColumn(l, 55);
printf("%s\n\n", Today);
++LineNumber;
++LineNumber;
}
}
GoToColumn(from, to)
register int from, to;
{
if( from < to)
{
if( TabWidth > 0 ){
from &= ~(TabWidth-1);
for( ; (from + TabWidth) <= to; from += TabWidth )
putchar('\t');
}
for( ; from < to; from++ )
putchar(' ');
}
}
#define isidchr(c) (isalnum(c) || (c == '_'))
/* This used to incorrectly identify a declaration such as
* int (*name[])() = { initializers ... }
* as a function. It also picked up this in an assembler file:
* #define MACRO(x) stuff
* MACRO(x):
* Fixed both of these. -IAN!
*/
LooksLikeFunction(s)
register char *s;
{
register char *p;
register int i;
char *save;
int t = TabWidth;
if( InComment || InString ) return(0);
if( OnlyCFiles )
{
char *e = Name+strlen(Name)-1;
if( *e != 'c' || e[-1] != '.' ) return(0);
}
if( !t ) t = 8;
save = s;
i = 0;
do
{
p = FunctionName;
while( *s && (*s == ' ') || (*s == '\t') ) ++s;
if( *s == '*' ) ++s;
if( *s && (*s == ' ') || (*s == '\t') ) continue;
if( !*s || ((*s != '_') && !isalpha(*s)) ) return(0);
while( isidchr(*s) )
*p++ = *s++;
*p = '\0';
while( *s && (*s == ' ') || (*s == '\t') ) ++s;
i++;
}
while ( *s && *s != '(' && i < 4 );
if( *s != '(' || *(s+1) == '*' ) return(0);
for (i = 0; *s; s++)
{
switch( *s )
{
case '(':
++i;
continue;
case ')':
--i;
break;
default:
break;
}
if( i == 0 ) break;
}
if( !*s ) return(0);
while( *s )
{
if( *s == '{') break;
if( *s == ';' || *s == ':' ) return(0);
++s;
}
/*
* This will cause the function name part of the line to
* be double striken. Note that this assumes the name and the opening
* parentheses are on the same line...
*/
if( p = strchr( save, '(' ) )
{
p--;
while( p != save && isidchr( *(p-1) ) ) p--;
for( i=0; save != p; save++ )
if( *save == '\t' )
{
putchar('\t');
i = ((i+t)/t)*t;
}
else
{
putchar(' ');
i++;
}
for( ; *p != '('; p++ )
if( *p == '\t' )
{
putchar('\t');
i = ((i+t)/t)*t;
}
else
{
putchar(*p);
i++;
}
}
else
for( i=0; *save && (*save == '*' || isidchr(*save)); ++save)
if( *save == '*' )
{
putchar(' ');
i++;
}
else
{
if( *save == '\t' )
i = ((i+t)/t)*t;
else
i++;
putchar(*save);
}
while( i --> 0 ) putchar('\b');
SawFunction = 1;
return(1);
}
static char *Toc[TOC_SIZE];
static int TocPages[TOC_SIZE];
static int TocCount;
AddToTableOfContents(type)
{
if( TocCount > TOC_SIZE )
return;
if( TocCount == TOC_SIZE )
{
fprintf(stderr, "%s: More than %d Table of contents entries; others ignored.\n",
ProgName, TOC_SIZE);
++TocCount;
return;
}
if( type == NEWFILE )
AddFile();
else
AddFunction();
}
AddFunction()
{
register int l;
register char *p;
/* This heuristic stops multiple occurrences of a function,
* selected by #ifdefs, to all end up many times over in the
* Table of Contents. One only needs to see it once. -IAN!
*/
if( TocCount > 0 && TocPages[TocCount-1] == PageNumber
&& strcmp(Toc[TocCount-1],FunctionName) == 0 )
return;
l = strlen(FunctionName);
p = Toc[TocCount] = (char *)malloc(l+1);
strcpy(p, FunctionName);
TocPages[TocCount] = PageNumber;
++TocCount;
}
AddFile()
{
register int i, l;
register int len;
char temp[20];
len = strlen(Name) + 20;
len = (len < 130) ? 130 : len;
Toc[TocCount] = (char *)malloc(len);
sprintf(Toc[TocCount], "\n File: %s ", Name);
l = strlen(Toc[TocCount]);
if( l < 64 )
{
if( TabWidth > 0 ){
i = ((64 - l) /TabWidth) + 1;
while( i-- > 0 )
Toc[TocCount][l++] = '\t';
}
else{
while( l < 64 )
Toc[TocCount][l++] = ' ';
}
Toc[TocCount][l++] = '\0';
}
sprintf(temp, " Page %4d\n", PageNumber);
strcat(Toc[TocCount], temp);
++TocCount;
}
NewFile()
{
GetFileTime();
if( ResetPage ) PageNumber=0;
NewPage();
AddToTableOfContents(NEWFILE);
FileLineNumber = 0;
}
GetFileTime()
{
struct stat st;
extern char *ctime();
if( File == stdin )
strncpy(FileDate, &Today[4], 20);
else
{
fstat(fileno(File), &st);
strncpy(FileDate, ctime((time_t *)&st.st_mtime) + 4, 20);
}
strncpy(&FileDate[12], &FileDate[15], 5);
FileDate[18] = '\0';
}
DumpTableOfContents()
{
register int i, j;
int index[TOC_SIZE];
if( TocCount == 0 ) return;
for (i = 0; i < TocCount; i++) index[i] = i;
if( SortFlag )
SortTable(index);
Name = "Table of Contents";
PageNumber = -1;
LineNumber = 0;
if( Title )
{
FILE *f;
int n;
char b[256];
if( (f=fopen(TitleFile,"r")) == NULL )
fprintf(stderr,"%s: Can't open file '%s': %s\n",
ProgName, TitleFile, sys_errlist[errno] );
else
{
while( fgets(b, 256, f) != NULL )
{
if( strlen(b) ) b[strlen(b)-1]=0;
puts(b);
LineNumber++;
if( ++LineNumber >= PageEnd ) NewPage();
}
fclose(f);
}
}
else
NewPage();
for( i=0; i < TocCount; ++i )
{
if( Toc[index[i]][0] == '\n' )
{
if( (LineNumber + 5) >= PageEnd ) NewPage();
printf("%s", Toc[index[i]]);
LineNumber += 2;
continue;
}
if( ++LineNumber >= PageEnd ) NewPage();
printf(" %s ", Toc[index[i]]);
for( j=strlen(Toc[index[i]]); j < 48; ++j ) putchar('.');
printf(" %4d\n", TocPages[index[i]]);
}
if( ContentsOnly ) NewPage();
}
SortTable(index)
register int *index;
{
register int i, temp, flag;
char name1[256];
char name2[256];
do {
flag = 0;
for (i = 0; i < TocCount - 1; i++)
{
if( Toc[index[i]][0] == '\n' || Toc[index[i+1]][0] == '\n' )
continue; /* don't sort across file names */
strcpy( name1, Toc[index[i]] );
strcpy( name2, Toc[index[i+1]] );
if( CaseInsensitive )
{
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);
}
if( strcmp(name1, name2) > 0)
{
temp = index[i];
index[i] = index[i+1];
index[i+1] = temp;
flag = 1;
}
}
}
while( flag );
}
@//E*O*F cpr.c//
chmod u=rw,g=,o= cpr.c
echo x - cpr.p
sed 's/^@//' > "cpr.p" <<'@//E*O*F cpr.p//'
CPR(P) Unsupported Software CPR(P)
NNAAMMEE
cpr - print 'C' files
SSYYNNOOPPSSIISS
ppuubblliicc ccpprr [-cCnNsS] [-T title] [-t tabwidth] [-p[num]]
[-r[num]] [-l pagelength] [[-f] file] ...
DDEESSCCRRIIPPTTIIOONN
_c_p_r prints the files named in its argument list, preceding
the output with a table of contents. If a filename is pre-
ceded by --ff then the specified file is assumed to contain a
list of files to be printed. The filename "-" specifies
standard input. Each file printed is assumed to be C source
code (but doesn't have to be see -c option below) in that
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.
By default, blank lines are inserted after every closing '}'
character. Thus functions and structure declarations are
nicely isolated in the output. The only drawback to this is
that structure initialization tables sometimes produce lots
of white space. The --rr[n] option changes the space left to
the specified number of lines. If no number is specified,
no space is left.
The option --ll indicates that the following argument is to be
the page length used for output, rather than the default 66
lines.
The option --cc forces cpr to "look" for functions only in
files whose suffix ends in '.c'.
The option --CC forces cpr to produce only a table of con-
tents, the file contents themselves are not printed.
The option --TT ttiittllee causes cpr to print the contents of the
file ttiittllee before printing the table of contents.
The option --ss indicates that the table of contents should be
sorted by function name within each file. Specifying --SS
performs the sort in a case-insensitive manner.
The option --nn indicates that output lines should be numbered
with the corresponding line number from the input file.
The option --NN forces page numbering to start with page 1 for
each file processed.
The option --tt _t_a_b_w_i_d_t_h causes output to be produced that
will look correct with tabs expanded every _t_a_b_w_i_d_t_h columns.
Formatted 89/02/07 UW 1
CPR(P) Unsupported Software CPR(P)
(The default is every 8 columns.) A _t_a_b_w_i_d_t_h of zero
suppresses use of tabs; all output will be spaced using
blanks.
The option --pp pprrooppoorrttiioonn indicates what proportion of the
page in steps of 16 should be used for deciding if a new
function needs a new page. That is -p12 (the default) indi-
cates that if a function starts within the top 12/16 (3/4)
of the page then do it, otherwise put it on a new page.
Thus the higher the number (up to 16) the closer to the bot-
tom of the page will functions be started. --pp00 says put
each function on a new page.
FFIILLEESS
/tmp/cpr$$ - temp files holding text
SSEEEE AALLSSOO
cb(1), cat(1), fold(1), num(1), pr(1)
DDIIAAGGNNOOSSTTIICCSS
Various messages about being unable to open files. Self
explanatory.
BBUUGGSS
This program sometimes thinks some declarations are func-
tions. Functions 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.
AAUUTTHHOORR
Paul Breslin original, Human Computing Resources
Corp.
Rick Wise sorting and use of standard input, CAL-
CULON Corp.
David Wasley numbering, times, etc., U. C. Berkley.
Patrick Powell variable number of lines between func-
tions, University of Waterloo
Ian! D. Allen variable tabs; redundant TOC suppres-
sion, University of Waterloo
Dennis Vadura more options; better function recogni-
tion, University of Waterloo
Formatted 89/02/07 UW 2
CPR(P) Unsupported Software CPR(P)
SSUUPPPPOORRTT
This software is _n_o_t supported by MFCF.
Send complaints or suggestions to dvadura@dragon.
Formatted 89/02/07 UW 3
@//E*O*F cpr.p//
chmod u=rw,g=,o= cpr.p
echo x - cpr.t
sed 's/^@//' > "cpr.t" <<'@//E*O*F cpr.t//'
@.\" to produce the man page.
@.\" troff -man -Tdumb cpr.tf | ddumb >cpr.p
@.\"
@.TH CPR P UW
@.SH "NAME"
cpr \- print 'C' files
@.SH "SYNOPSIS"
@.B public cpr
[-cCnNsS] [-T title] [-t tabwidth] [-p[num]] [-r[num]] [-l pagelength]
[[-f] file] ...
@.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
then the specified file is assumed to contain a list of files to be
printed. The filename "-" specifies standard input.
Each file printed is assumed to be C
source code (but doesn't have to be see -c option below)
in that 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.
@.PP
By default, blank lines are inserted after every closing '}'
character. Thus functions and structure declarations are nicely
isolated in the output. The only drawback to this is that structure
initialization tables sometimes produce lots of white space.
The \fB\-r\fP[n] option changes the space left to the specified
number of lines. If no number is specified, no space is left.
@.PP
The option \fB\-l\fP indicates that the following argument is to be
the page length used for output, rather
than the default 66 lines.
@.PP
The option \fB\-c\fP forces cpr to "look" for functions only in files
whose suffix ends in '.c'.
@.PP
The option \fB\-C\fP forces cpr to produce only a table of contents, the
file contents themselves are not printed.
@.PP
The option \fB\-T title\fP causes cpr to print the contents of the file
@.B title
before printing the table of contents.
@.PP
The option \fB\-s\fP indicates that the table of contents should be sorted
by function name within each file.
Specifying \fB\-S\fP performs the sort in a case-insensitive manner.
@.PP
The option \fB\-n\fP indicates that output lines should be numbered with
the corresponding line number from the input file.
@.PP
The option \fB\-N\fP forces page numbering to start with page 1 for each
file processed.
@.PP
The option \fB\-t\fI\ tabwidth\fR
causes output to be produced that will look correct with tabs expanded every
@.I tabwidth
columns.
(The default is every 8 columns.)
A
@.I tabwidth
of zero suppresses use of tabs; all output will be spaced using blanks.
@.PP
The option
@.B -p proportion
indicates what proportion of the page in steps of 16
should be used for deciding if a new function needs a new page.
That is -p12 (the default) indicates that if a function starts
within the top 12/16 (3/4) of the page then do it, otherwise put it
on a new page.
Thus the higher the number (up to 16) the closer to
the bottom of the page will functions be started.
@.B -p0
says put each function on a new page.
@.SH "FILES"
@.nf
/tmp/cpr$$ \- temp files holding text
@.fi
@.SH "SEE ALSO"
cb(1), cat(1), fold(1), num(1), pr(1)
@.SH "DIAGNOSTICS"
Various messages about being unable to open files.
Self explanatory.
@.SH "BUGS"
This program sometimes thinks some declarations are functions.
Functions 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 "AUTHOR"
@.IP "Paul Breslin" 2.0i
original, Human Computing Resources Corp.
@.IP "Rick Wise" 2.0i
sorting and use of standard input, CALCULON Corp.
@.IP "David Wasley" 2.0i
numbering, times, etc., U. C. Berkley.
@.IP "Patrick Powell" 2.0i
variable number of lines between functions, University of Waterloo
@.IP "Ian! D. Allen" 2.0i
variable tabs; redundant TOC suppression, University of Waterloo
@.IP "Dennis Vadura" 2.0i
more options; better function recognition,
University of Waterloo
@.SH SUPPORT
This software is
@.I not
supported by
@.SM MFCF.
@.PP
Send complaints or suggestions to dvadura@dragon.
@//E*O*F cpr.t//
chmod u=rw,g=,o= cpr.t
exit 0
--
--------------------------------------------------------------------------------
Dennis Vadura, Computer Science Dept., UUCP,BITNET: dvadura@water
University of Waterloo, Waterloo, Ont. EDU,CDN,CSNET: dvadura@waterloo
================================================================================
--
--------------------------------------------------------------------------------
Dennis Vadura, Computer Science Dept., UUCP,BITNET: dvadura@water
University of Waterloo, Waterloo, Ont. EDU,CDN,CSNET: dvadura@waterloo
================================================================================