home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-11-26 | 47.9 KB | 1,887 lines |
- Newsgroups: comp.sources.misc
- organization: AT&T Bell Labs - Lincroft, NJ
- subject: v09i010: New version of CPR - C Pretty-printer
- from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Reply-To: dmt@pegasus.ATT.COM (Dave Tutelman)
-
- Posting-number: Volume 9, Issue 10
- Submitted-by: dmt@pegasus.ATT.COM (Dave Tutelman)
- Archive-name: cpr_dt
-
- : This is a shar archive. Extract with sh, not csh.
- : The rest of this file will extract:
- : readme cpr.c parsargs.c list.c fold.c report.c wildfile.c cpr.h makefile
- echo extracting - readme
- sed 's/^X//' > readme << '!EOR!'
- X
- X README FILE FOR CPR
- X ^^^^^^^^^^^^^^^^^^^
- X
- XOK, we gotta have a README file, so you can tell what this does and
- Xwhere it came from. Well, I pulled it off the net myself early this
- Xyear (1989), and found it sort of useful. It's a pretty-printer for
- XC programs.
- X
- XWHAT IT DOES:
- X - Paginates, with meaningful page headers.
- X - Makes a table of contents for files and functions.
- X - Won't start a function at the bottom of a page. (In fact,
- X has an option to print only one function per page.)
- X
- XWHAT IT DOESN'T DO:
- X - Indent.
- X - Put brackets on separate lines.
- X - Other stuff that "C beautifiers" do.
- X
- XWhen I inherited a couple of pretty big C programs to maintain, the
- Xfirst thing I did was to try to get a bunch of listings with CPR. I
- Xfound that CPR as I received it wasn't up to the job. It certainly
- Xwas after I added a few enhancements. Here's the enhanced version,
- Xcast back upon the waters of the net. The enhancements are:
- X
- X - Any arguments can appear in a file rather than on the command
- X line, and in pretty free form. (As received, you could only have
- X filename arguments in a file, one name per line.)
- X - The table of contents can contain a single sorted index of
- X all functions across all files.
- X - The option "-?" will give a help screen for the options
- X (more like the PC idiom than the usual UNIX utility).
- X - Lines can be "intelligently" folded if they go beyond the
- X width of a page. (You wouldn't believe this program I
- X inherited, and its 160-column lines.)
- X
- XThis remains public domain, which is as I found it. (It's free, and
- Xworth every penny :-)
- X
- X Dave Tutelman
- XPHYSICAL: 16 Tilton Drive AT&T Bell Labs
- X Wayside, NJ 07712 Lincroft, NJ 07738
- XAUDIBLE: (201) 922-9576 (201) 576-2194
- XLOGICAL: att!pegasus!dmt
- X
- XContributors to the code include:
- X * Written by:
- X * Paul Breslin
- X * Human Computing Resources Corp.
- X * 10 St. Mary St.
- X * Toronto, Ontario
- X * Canada, M4Y 1P9
- X *
- X * -- ...!decvax!utcsrgv!hcr!phb
- X *
- X * Sorting and standard input reading from:
- X * Rick Wise, CALCULON Corp., Rockville, MD.
- X * -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
- X *
- X * File modified time,
- X * numbered output,
- X * optional white space,
- X * improved function start tests from:
- X * David Wasley, U.C.Berkeley
- X * -- ...!ucbvax!topaz.dlw
- X *
- X * Modified the -r to leave variable amounts of space
- X * Patrick Powell, U. Waterloo
- X *
- X * Changed handling of form feeds to start a new page AND print heading:
- X * Terry Doner, U of Waterloo
- X *
- X * Fixed up to locate more functions, and added -p option
- X * Dennis Vadura, U of Waterloo
- X *
- X * It will find things like struct foo *f()...
- X * but not things like int
- X * f
- X * ()...
- X * ie. the constraint is that the () must appear on the same line
- X * as the function name.
- X *
- X * Clean up a bit for 80286 machines (lints a bit cleaner, too)
- X * Dan Frank, Prairie Computing
- X *
- X * Fixed a whole bunch of stuff and added lots of new flags.
- X * -S sort and be case insensitive.
- X * -N start numbering pages at 1 for each new file
- X * -T title cat the file title before the table of contents.
- X * -C print only the table of contents
- X * -c only try to look for function names in files whose suffix ends
- X * in .c
- X * -f file to handle file containing list of files to print. (for MSDOS)
- X * Dennis Vadura
- X *
- X * Set to work better in MS-DOS (and Turbo C).
- X * Ported to Turbo C on MS-DOS.
- X * Enabled wildcard expansion for systems that don't support it.
- X * Broke BIG source file into several C files plus header.
- X * Fixed argument parsing to be more forgiving.
- X * Changed -f option to handle all args in a free-form file,
- X * not just filenames.
- X * Added options:
- X * -? Help screen.
- X * -x,-X Sort TOC across files, giving function index (xref-like?).
- X * -w (n) Fold lines to a page width (fairly good-looking line folding).
- X * Dave Tutelman - att!pegasus!dmt - 10/89
- X
- X
- !EOR!
- echo extracting - cpr.c
- sed 's/^X//' > cpr.c << '!EOR!'
- X/* CPR - Pretty-Printer for C programs
- X *
- X * This program prints the files named in its argument list, preceding
- X * the output with a table of contents. Each file is assumed to be C
- X * source code (but doesn't have to be) in that the program searches
- X * for the beginning and end of functions. Function names are added to
- X * the table of contents, provided the name starts at the beginning of
- X * a line. The function name in the output is double striken.
- X *
- X * PAGE SIZE
- X * The option "-l" indicates that the following argument is to be
- X * the page length used for output (changing the page length hasn't been
- X * tested much).
- X * The option "-w" indicates that the following argument is to be
- X * the page width (and lines are folded to that width, using a
- X * reasonably aesthetic folding algorithm). The default, in the
- X * absence of "-w" is not to fold lines.
- X *
- X * NUMBERING OF LINES & PAGES
- X * The option "-n" indicates that output lines should be numbered with
- X * the corresponding line number from the input file.
- X * The option "-N" indicates that page numbers start at 1 within each
- X * file.
- X *
- X * FORMATTING THE PROGRAM
- X * The option "-p" indicates what proportion of the page in steps of 16
- X * should be used for deciding if a new function needs a new page.
- X * That is -p12 (the default) indicates that if a function starts
- X * within the top 12/16 (3/4) of the page then do it, otherwise put it
- X * on a new page. Thus the higher the number (upto 16) the closer to
- X * the bottom of the page will functions be started. -p0 says put each
- X * func on a new page.
- X *
- X * By default blank space is inserted after every closing '}'
- X * character. Thus functions and structure declarations are nicely
- X * isolated in the output. The only drawback to this is that structure
- X * initialization tables sometimes produce lots of white space.
- X * The "-r" option removes this space, or changes it to the indicated
- X * length.
- X *
- X * TABLE OF CONTENTS OPTIONS
- X * The option "-s" indicates that the table of contents should be sorted
- X * by function name within each file.
- X * The option "-S" also calls for a sorted table of contents, but with
- X * a case-insensitive sort.
- X * The option "-x" indicates that the table of contents should include
- X * a sorted index of functions across all files.
- X * The option "-X" also calls for a sorted index of functions, but with
- X * a case-insensitive sort.
- X *
- X * The option "-C" indicates that ONLY the table of contents is to
- X * be printed, not the source files themselves.
- X *
- X * The option "-c" indicates that only files with the extension ".c"
- X * should be examined for files to list in the table of contents.
- X *
- X * The option "-T" indicates that the following argument is a file
- X * name; the contents of that file is to be printed verbatim in the
- X * output before the table of contents, as a Title Paragraph.
- X *
- X * MISCELLANEOUS OPTIONS
- X * The option "-?" indicates that a help screen for CPR be sent
- X * to stderr (generally the screen), but no processing done.
- X * The help screen is more verbose than the usage message that's
- X * printed on error, and summarizes all options of CPR.
- X *
- X * The option "-f" indicates that the following argument is a file
- X * name; the contents of that file are to be treated just as command
- X * line arguments. (Thus you can, for example, make a ".cprrc" file
- X * with the right options and source files, in each of your
- X * source directories.)
- X *
- X * HISTORY
- X *
- X * Written by:
- X * Paul Breslin
- X * Human Computing Resources Corp.
- X * 10 St. Mary St.
- X * Toronto, Ontario
- X * Canada, M4Y 1P9
- X *
- X * -- ...!decvax!utcsrgv!hcr!phb
- X *
- X * Sorting and standard input reading from:
- X * Rick Wise, CALCULON Corp., Rockville, MD.
- X * -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
- X *
- X * File modified time,
- X * numbered output,
- X * optional white space,
- X * improved function start tests from:
- X * David Wasley, U.C.Berkeley
- X * -- ...!ucbvax!topaz.dlw
- X * Modified the -r to leave variable amounts of space
- X * Patrick Powell, U. Waterloo
- X *
- X * Changed handling of form feeds to start a new page AND print heading:
- X * Terry Doner, U of Waterloo
- X *
- X * Fixed up to locate more functions, and added -p option
- X * Dennis Vadura, U of Waterloo
- X *
- X * It will find things like struct foo *f()...
- X * but not things like int
- X * f
- X * ()...
- X * ie. the constraint is that the () must appear on the same line
- X * as the function name.
- X *
- X * Clean up a bit for 80286 machines (lints a bit cleaner, too)
- X * Dan Frank, Prairie Computing
- X *
- X * Fixed a whole bunch of stuff and added lots of new flags.
- X * -S sort and be case insensitive.
- X * -N start numbering pages at 1 for each new file
- X * -T title cat the file title before the table of contents.
- X * -C print only the table of contents
- X * -c only try to look for function names in files whose suffix ends
- X * in .c
- X * -f file to handle file containing list of files to print. (for MSDOS)
- X * Dennis Vadura
- X *
- X * Set to work better in MS-DOS (and Turbo C).
- X * Ported to Turbo C on MS-DOS.
- X * Enabled wildcard expansion for systems that don't support it.
- X * Broke BIG source file into several C files plus header.
- X * Fixed argument parsing to be more forgiving.
- X * Changed -f option to handle all args in a free-form file,
- X * not just filenames.
- X * Added options:
- X * -? Help screen.
- X * -x,-X Sort TOC across files, giving function index (xref-like?).
- X * -w (n) Fold lines to a page width (fairly good-looking line folding).
- X * Dave Tutelman - att!pegasus!dmt - 10/89
- X */
- X
- X#include <sys/types.h>
- X#include <ctype.h>
- X#include <stdio.h>
- X#include <signal.h>
- X#include <string.h>
- X
- Xchar *synopsis [] = {
- X"OPTIONS:",
- X"-c Look for functions only if file is a '.c' file.",
- X"-C Produce ONLY table of contents, no listing.",
- X"-n Number lines in the listing.",
- X"-N Start each file listing on page 1.",
- X"-s Sort table of contents by function name (in each file).",
- X"-S Like -s, but case-insensitive.",
- X"-x,-X Like -s, -S, but sorts across files (Xref-like function index).",
- X"-l n Page length. (Default = 66)",
- X"-w n Page width, at which to fold lines. (Default = don't fold lines)",
- X"-p n How many 16ths of a page can be used, and still start a new function",
- X" on this page? (-p0 puts a new function on each page. Default = 12)",
- X"-r n How many blank lines to leave after a '}'. (Default = 5)",
- X"-t n Width of a tab stop. (Default = 8)",
- X"-T title Print contents of file 'title' before table of contents.",
- X"-f argfile Take next few arguments from file 'argfile'.",
- X"- File name for the Standard Input.",
- X'\0'
- X};
- X
- X#define MAIN
- X#include "cpr.h"
- X
- X/* Some macros for parsing parameters from the argument list */
- X#define NEXPARM NexParm (&i,&parm, argc,argv)
- X#define NUMPARM NumParm (&i,&parm, argc,argv)
- X#define STRPARM StrParm (&i,&parm, argc,argv)
- X
- X#ifdef NOWILD
- Xint NextName=0; /* Use next_file function to expand wildcard */
- Xchar *first_file(), *next_file();
- X#endif
- X
- Xchar *GetProgName();
- Xchar *StrParm();
- X
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X int i;
- X char *ctime();
- X time_t thetime, time();
- X char *parm; /* points to next thing to do in an arg */
- X int num;
- X int FirstFile=1;
- X
- X ProgName = GetProgName (argv[0]);
- X thetime = time((time_t *)0);
- X strcpy(Today,ctime(&thetime));
- X
- X if (argc < 2) Synop();
- X
- X i = 0;
- X while ((i = NEXPARM) >0) /* get next argument if there is one */
- X {
- X if( arg[0] == '?'
- X && arg[1] == '\0' ) Synop();
- X
- X if( arg[0] != '-' || arg[1] == '\0' ) { /* file name */
- X parm--; /* back off to get whole name */
- X Name = STRPARM;
- X if (NULLSTR( Name )) Usage();
- X if (FirstFile) {
- X FirstFile=0;
- X StartTempFile();
- X }
- X DoFile (Name);
- X }
- X
- X else { /* this arg is options */
- X switch( *parm ) {
- X case '-':
- X break; /* skip. just leading - for options */
- X
- X case '\0': /* check for end of this argument */
- X case ' ': /* just for safety. */
- X case '\t':
- X case '\n':
- X case '\r':
- X break;
- X
- X case '?': Synop();
- X
- X case 'f': /* get next args from a file */
- X listn = STRPARM; /* get next string parameter */
- X if (NULLSTR( listn )) Usage();
- X if ((listf = fopen (listn, "r")) == NULL) {
- X fprintf(stderr,"%s: list file '%s' not found\n",
- X ProgName, listn);
- X exit (1);
- X }
- X InArgFile = 1;
- X break;
- X
- X case 't':
- X TabWidth = NUMPARM;
- X if( TabWidth == -1) TabWidth = 0;
- X if( TabWidth < 0 ) TabWidth = 0;
- X break;
- X
- X case 'T':
- X TitleFile = STRPARM;
- X if (NULLSTR( TitleFile )) Usage();
- X if ((Tfile = fopen (TitleFile, "r")) == NULL) {
- X fprintf(stderr,"%s: title file '%s' not found\n",
- X ProgName, TitleFile);
- X exit (1);
- X }
- X ++Title;
- X break;
- X
- X case 'l':
- X PageLength = NUMPARM;
- X if( PageLength == -1) Usage();
- X if( PageLength < 10) PageLength = 10;
- X PageEnd = PageLength - ((PageLength > 30) ? 7 : 1);
- X break;
- X
- X case 'w':
- X PageWidth = NUMPARM;
- X if( PageWidth == -1 ) Usage();
- X if( PageWidth < 0 ) PageWidth = 0;
- X break;
- X
- X case 'S':
- X ++CaseInsensitive;
- X case 's':
- X ++SortFlag;
- X break;
- X
- X case 'X':
- X ++CaseInsensitive;
- X case 'x':
- X ++SortFlag;
- X ++XrefFlag;
- X if (ResetPage) {
- X fprintf(stderr,"%s: options -X and -N are incompatible\n",
- X ProgName);
- X exit (1);
- X }
- X break;
- X
- X case 'C':
- X ++ContentsOnly;
- X break;
- X
- X case 'c':
- X ++OnlyCFiles;
- X break;
- X
- X case 'n':
- X ++NumberFlag;
- X FirstCol = FORMATWIDTH; /* leave room for line numbering */
- X break;
- X
- X case 'N':
- X ++ResetPage;
- X if (XrefFlag) {
- X fprintf(stderr,"%s: options -X and -N are incompatible\n",
- X ProgName);
- X exit (1);
- X }
- X break;
- X
- X case 'r':
- X Space_to_leave = NUMPARM;
- X if (Space_to_leave == -1) Space_to_leave = 0;
- X if (Space_to_leave < 0) Space_to_leave = 0;
- X break;
- X
- X case 'p':
- X PagePart = NUMPARM;
- X if ( PagePart == -1) Usage();
- X if ( PagePart < 0) PagePart = 0;
- X if ( PagePart > 16) PagePart = 16;
- X break;
- X
- X default:
- X Usage();
- X break;
- X } /* end 'switch' */
- X } /* end 'else' */
- X } /* end 'while' */
- X
- X /* All files processed. Print the listings. */
- X if( PageNumber > 1 || LineNumber > 0 )
- X putchar(BP);
- X EndTempFile();
- X
- X DumpTableOfContents();
- X DumpTempFiles();
- X Done();
- X}
- X
- XUsage()
- X{
- X fprintf(stderr, "%s: Problem with argument %s", ProgName, arg);
- X if (InArgFile) fprintf(stderr, " in argument file\n");
- X else fprintf(stderr, "\n"); /* yeah, I know ... */
- X fprintf(stderr, "Usage: %s [-?cCnNsSxX] [-t tabwidth] [-l pagelength] ",ProgName);
- X fprintf(stderr, "[-w pagewidth]\n\t[-p[num]] [-r[num]] [-T title] [[-f] file] ...");
- X exit(1);
- X}
- X
- XSynop()
- X{
- X int i;
- X
- X fprintf(stderr,"Synopsis:\n%s [options] [filenames]\n\n", ProgName);
- X for (i=0; *synopsis[i] != '\0'; i++)
- X fprintf (stderr,"%s\n",synopsis[i]);
- X exit(1);
- X}
- X
- Xchar *
- XGetProgName (s) /* We need to strip off path information, if there */
- Xchar *s;
- X{
- X char *p;
- X
- X for (p=s; *p!='\0'; p++); /* get end of string */
- X while (--p >= s) {
- X#ifdef MSDOS
- X if (*p == '.')
- X *p='\0'; /* strip off .EXE extension */
- X#endif
- X if ((*p=='/') || (*p=='\\'))
- X break;
- X }
- X return (++p);
- X}
- X
- X
- X/* Do the processing necessary to format one file */
- XDoFile (fname)
- X char *fname;
- X{
- X if (*fname=='-' && *(fname+1)=='\0') {
- X File = stdin;
- X Name = "Standard Input";
- X List();
- X return;
- X }
- X#ifndef NOWILD
- X if( (File = fopen( fname, "r" )) == NULL )
- X {
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",
- X ProgName, Name, sys_errlist[errno] );
- X }
- X List();
- X fclose(File);
- X
- X#else /* expand wildcards explicitly */
- X Name = first_file (fname);
- X while ((Name != NULL) && (*Name != '\0')) {
- X if( (File = fopen( Name, "r" )) == NULL )
- X {
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",
- X ProgName, Name, sys_errlist[errno] );
- X continue;
- X }
- X List();
- X fclose(File);
- X
- X Name = next_file ();
- X }
- X#endif
- X}
- X
- X
- Xint SaveOut;
- Xchar *TempName;
- Xchar *Temp2Name;
- X
- XStartTempFile()
- X{
- X int Done();
- X extern char *mktemp();
- X
- X CatchSignalsPlease(Done);
- X
- X SaveOut = dup(1);
- X#ifdef MSDOS
- X TempName = "cpr0001.tmp";
- X#else
- X TempName = mktemp("/tmp/cprXXXXXX");
- X#endif
- X if( freopen(TempName, "w", stdout) == NULL )
- X {
- X fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
- X TempName, sys_errlist[errno]);
- X exit(1);
- X }
- X}
- X
- XEndTempFile()
- X{
- X#ifdef MSDOS
- X Temp2Name = "cpr0002.tmp";
- X#else
- X Temp2Name = mktemp("/tmp/cprXXXXXX");
- X#endif
- X if( freopen(Temp2Name, "w", stdout) == NULL )
- X {
- X fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
- X Temp2Name, sys_errlist[errno]);
- X exit(1);
- X }
- X}
- X
- XDumpTempFiles()
- X{
- X FILE *f;
- X char b[256];
- X register int pid, w;
- X
- X fclose(stdout);
- X
- X#ifndef MSDOS
- X dup(SaveOut);
- X while( (pid = fork()) < 0 ) sleep(1);
- X if( pid )
- X while ((w = wait((int *)0)) != pid && w != -1);
- X else
- X {
- X CatchSignalsPlease(SIG_DFL);
- X
- X if( ContentsOnly )
- X execl( "/bin/cat", "cat", Temp2Name, (char *)0 );
- X else
- X execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
- X fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
- X sys_errlist[errno]);
- X exit(0);
- X }
- X#else
- X CatchSignalsPlease(SIG_DFL);
- X if( (f=fopen(Temp2Name,"r")) == NULL )
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",
- X ProgName, TitleFile, sys_errlist[errno] );
- X else
- X {
- X while( fgets(b, 256, f) != NULL )
- X write(SaveOut,b,strlen(b));
- X
- X fclose(f);
- X }
- X
- X if( !ContentsOnly )
- X if( (f=fopen(TempName,"r")) == NULL )
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",
- X ProgName, TitleFile, sys_errlist[errno] );
- X else
- X {
- X while( fgets(b, 256, f) != NULL )
- X write(SaveOut,b,strlen(b));
- X
- X fclose(f);
- X }
- X#endif
- X}
- X
- XDone()
- X{
- X CatchSignalsPlease(SIG_DFL);
- X
- X fclose( stdout );
- X if( TempName ) unlink( TempName );
- X if( Temp2Name ) unlink( Temp2Name );
- X
- X exit(0);
- X}
- X
- XCatchSignalsPlease(action)
- Xvoid (*action)();
- X{
- X#ifndef TURBOC
- X if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action);
- X#else /* TURBOC */
- X signal (SIGINT, action);
- X#endif
- X#ifndef MSDOS
- X if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
- X if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action);
- X#endif
- X}
- X
- !EOR!
- echo extracting - parsargs.c
- sed 's/^X//' > parsargs.c << '!EOR!'
- X/* PARSARGS
- X *
- X * Functions to get parameters from:
- X * - The command line.
- X * - The argument file (if -f option is used).
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "cpr.h"
- X
- X
- X/* Get the next parameter, and point to it with *pp.
- X * Return current index into argv[], or -1 if no more parameters.
- X * Put NEW argument into arg[], but just bump *pp if there's still
- X * more to do in arg[].
- X * Get NEW argument from argv[] or list file, depending on InArgFile.
- X */
- X
- Xint
- XNexParm (ip,pp, argc,argv)
- X int *ip; /* pointer to arg[] index */
- X char **pp; /* pointer to parm, which is (char *) */
- X int argc;
- X char *argv[];
- X{
- X int i = *ip;
- X char *p = *pp;
- X int c;
- X int InArg = 0; /* state variable */
- X int GotArg = 0;
- X
- X if (i==0) { /* need to initialize */
- X strcpy (arg, argv[1]);
- X *pp = arg;
- X *ip = 1;
- X return (1);
- X }
- X
- X p++; /* bump the parameter pointer */
- X
- X if (WHITESPACE( *p )) { /* need a new arg */
- X arg[0] = '\0'; /* blank the beginning of the arg[] array */
- X if (InArgFile) { /* get the new arg from listf */
- X p = arg;
- X while (!GotArg) {
- X c=getc (listf);
- X if (!InArg) {
- X if (c == EOF) { /* no more in listf */
- X InArgFile = 0;
- X GotArg++;
- X }
- X else if (!WHITESPACE( (char)c )) InArg++;
- X }
- X if (InArg) {
- X if (WHITESPACE( (char)c ) || c==EOF) {
- X *p = '\0';
- X GotArg++;
- X }
- X else if (!WHITESPACE( (char)c )) *p++ = c;
- X }
- X } /* end while (!GotArg) */
- X } /* end if (InArgFile) */
- X
- X if (arg[0]=='\0') { /* get the new arg from command line */
- X if (++i >= argc) return (-1);
- X strcpy (arg, argv[i]);
- X *ip = i;
- X GotArg++;
- X }
- X *pp = arg;
- X } /* end of "need new arg" */
- X
- X else if (!GotArg) /* not a new arg, just bump pointer */
- X *pp = p;
- X
- X return ( i );
- X}
- X
- Xint
- XNumParm (ip, pp, argc,argv) /* Returns next parameter as an integer if it
- X * is a number. Otherwise returns -1. */
- X int *ip; /* pointer to argument counter in main program */
- X char **pp; /* pointer to "parm" pointer in main program */
- X int argc;
- X char *argv[];
- X{
- X int num=0; /* number accumulator */
- X int i;
- X char *p;
- X
- X /* Bump to next parm, if there is one */
- X i = NexParm( ip, pp, argc, argv );
- X if (i <= 0) return (-1);
- X
- X p = *pp; /* use updated parm pointer */
- X
- X /* is there at least one digit? */
- X if (!isdigit( *p )) {
- X *pp = p-1; /* back off to previous position */
- X return (-1);
- X }
- X
- X /* accumulate a decimal number */
- X while (isdigit( *p ))
- X num = 10*num + (int)(*p++ - '0');
- X
- X /* fix up pointers before returning */
- X *pp = p-1; /* back off to end of number */
- X return (num);
- X}
- X
- X
- Xchar *
- XStrParm (ip, pp, argc,argv) /* Returns next string parameter if there
- X * is one. Otherwise returns -1. */
- X int *ip; /* pointer to argument counter in main program */
- X char **pp; /* pointer to "parm" pointer in main program */
- X int argc;
- X char *argv[];
- X{
- X int i;
- X char *p, *s;
- X
- X /* Bump to next parm, if there is one */
- X i = NexParm( ip, pp, argc, argv );
- X if (i <= 0) return (NULL);
- X
- X s = p = *pp; /* use updated parm pointer */
- X if (WHITESPACE( *p )) return (NULL);
- X
- X /* Find end of string and null it out */
- X while (! WHITESPACE( *p )) p++;
- X *p = '\0'; /* now null-terminate the string */
- X
- X /* fix up pointers before returning */
- X *pp = p-1; /* back off to end of string */
- X return (s);
- X}
- X
- !EOR!
- echo extracting - list.c
- sed 's/^X//' > list.c << '!EOR!'
- X/* LIST.C
- X *
- X * Functions that go through the .C files,
- X * parse them, and make entries in Table of Contents.
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X#include "cpr.h"
- X
- Xint SawFunction;
- Xint Braces;
- X
- X
- XList()
- X{
- X register int bp;
- X register char *bufp;
- X char buffer[256];
- X
- X NewFile();
- X bp = Braces = 0;
- X InString = InComment = 0; /* reset for new file -DV */
- X SawFunction = 0;
- X bufp = buffer;
- X while( fgets(bufp, sizeof(buffer), File) != NULL )
- X {
- X ++FileLineNumber;
- X if( bp ) NewFunction();
- X
- X if( ++LineNumber >= PageEnd ) NewPage();
- X
- X if( bufp[0] == '\f'
- X && bufp[1] == '\n'
- X && bufp[2] == '\0' )
- X {
- X NewPage(); /* was strcpy(bufp, "^L\n");*/
- X continue;
- X }
- X
- X if( NumberFlag )
- X {
- X if( *bufp == '\n' )
- X printf(BLANKFORMAT);
- X else
- X printf(NUMFORMAT, FileLineNumber);
- X }
- X if( (Braces == 0) && LooksLikeFunction(bufp) )
- X AddToTableOfContents(NEWFUNCTION);
- X
- X bp = ScanLine(buffer);
- X }
- X}
- X
- XScanLine(l)
- Xregister char *l;
- X{
- X extern char *EndComment();
- X extern char *EndString();
- X register char c;
- X int bp;
- X char *save;
- X
- X /* initialize line-checking variables */
- X bp = 0;
- X
- X /* Now scan the line */
- X for( save = l; c = *l; ++l )
- X if( InComment )
- X l = EndComment(l);
- X else if( InString )
- X l = EndString(l);
- X else
- X switch(c)
- X {
- X case '{':
- X ++Braces;
- X break;
- X
- X case '}':
- X if( --Braces == 0 )
- X bp = 1;
- X break;
- X
- X case '\'':
- X for( ++l; *l && *l != '\''; ++l )
- X if( *l == '\\' && *(l+1) ) ++l;
- X break;
- X
- X case '"':
- X InString = 1;
- X break;
- X
- X case '/':
- X if( *(l+1) == '*' )
- X {
- X InComment = 1;
- X ++l;
- X }
- X break;
- X }
- X if (PageWidth) FoldLine( save );
- X OutputLine( save );
- X return(bp);
- X}
- X
- Xchar *
- XEndComment(p)
- Xregister char *p;
- X{
- X register char c;
- X
- X /*
- X * Always return pointer to last non-null char looked at.
- X */
- X while( c = *p++ ) {
- X if( c == '*' && *p == '/' )
- X {
- X InComment = 0;
- X return(p);
- X }
- X }
- X return(p-2);
- X}
- X
- Xchar *
- XEndString(p)
- Xregister char *p;
- X{
- X register char c;
- X
- X /*
- X * Always return pointer to last non-null char looked at.
- X */
- X while( c = *p++ ) {
- X if( c == '\\' && *p )
- X {
- X ++p;
- X continue;
- X }
- X else if( c == '"' )
- X {
- X InString = 0;
- X return(p-1);
- X }
- X }
- X return(p-2);
- X}
- X
- XNewFunction()
- X{
- X register int i;
- X
- X if( Space_to_leave <= 0 || !SawFunction ) return;
- X if( LineNumber + Space_to_leave > (PageLength * PagePart /16) )
- X NewPage();
- X else
- X {
- X for( i=0; i < (Space_to_leave); ++i ) putchar('\n');
- X LineNumber += Space_to_leave;
- X }
- X
- X SawFunction = 0;
- X}
- X
- X#define isidchr(c) (isalnum(c) || (c == '_'))
- X
- X/* This used to incorrectly identify a declaration such as
- X * int (*name[])() = { initializers ... }
- X * as a function. It also picked up this in an assembler file:
- X * #define MACRO(x) stuff
- X * MACRO(x):
- X * Fixed both of these. -IAN!
- X */
- XLooksLikeFunction(s)
- Xregister char *s;
- X{
- X register char *p;
- X register int i;
- X char *save;
- X int t = TabWidth;
- X
- X if( InComment || InString ) return(0);
- X if( OnlyCFiles )
- X {
- X char *e = Name+strlen(Name)-1;
- X if(( *e != 'c'
- X#ifdef MSDOS
- X && *e != 'C'
- X#endif
- X ) || e[-1] != '.' ) return(0);
- X }
- X
- X if( !t ) t = 8;
- X save = s;
- X
- X i = 0;
- X do
- X {
- X p = FunctionName;
- X
- X while( *s && (*s == ' ') || (*s == '\t') ) ++s;
- X if( *s == '*' ) ++s;
- X if( *s && (*s == ' ') || (*s == '\t') ) continue;
- X if( !*s || ((*s != '_') && !isalpha(*s)) ) return(0);
- X
- X while( isidchr(*s) )
- X *p++ = *s++;
- X *p = '\0';
- X
- X while( *s && (*s == ' ') || (*s == '\t') ) ++s;
- X i++;
- X }
- X while ( *s && *s != '(' && i < 4 );
- X
- X if( *s != '(' || *(s+1) == '*' ) return(0);
- X
- X for (i = 0; *s; s++)
- X {
- X switch( *s )
- X {
- X case '(':
- X ++i;
- X continue;
- X
- X case ')':
- X --i;
- X break;
- X
- X default:
- X break;
- X }
- X if( i == 0 ) break;
- X }
- X if( !*s ) return(0);
- X
- X while( *s )
- X {
- X if( *s == '{') break;
- X if( *s == ';' || *s == ':' ) return(0);
- X ++s;
- X }
- X
- X /*
- X * This will cause the function name part of the line to
- X * be double striken. Note that this assumes the name and the opening
- X * parentheses are on the same line...
- X */
- X
- X if( p = strchr( save, '(' ) )
- X {
- X p--;
- X while( p != save && isidchr( *(p-1) ) ) p--;
- X for( i=0; save != p; save++ )
- X if( *save == '\t' )
- X {
- X putchar('\t');
- X i = ((i+t)/t)*t;
- X }
- X else
- X {
- X putchar(' ');
- X i++;
- X }
- X
- X for( ; *p != '('; p++ )
- X if( *p == '\t' )
- X {
- X putchar('\t');
- X i = ((i+t)/t)*t;
- X }
- X else
- X {
- X putchar(*p);
- X i++;
- X }
- X }
- X else
- X for( i=0; *save && (*save == '*' || isidchr(*save)); ++save)
- X if( *save == '*' )
- X {
- X putchar(' ');
- X i++;
- X }
- X else
- X {
- X if( *save == '\t' )
- X i = ((i+t)/t)*t;
- X else
- X i++;
- X putchar(*save);
- X }
- X
- X while( i --> 0 ) putchar('\b');
- X
- X SawFunction = 1;
- X return(1);
- X}
- !EOR!
- echo extracting - fold.c
- sed 's/^X//' > fold.c << '!EOR!'
- X/* FOLD
- X *
- X * Functions to fold an output line.
- X */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include "cpr.h"
- X
- X/* The criteria for folding a line are, in order of aethetic desirability: */
- X#define COMMENT 0 /* Comment starts here */
- X#define BRACKET 1 /* Curly open bracket */
- X#define SEMICOLON 2 /* First non-blank after semicolon */
- X#define BLANK 3 /* First non-blank after whitespace */
- X#define PAREN 4 /* Open parenthesis */
- X#define N_CRIT 5 /* Number of criteria for folding a line */
- X#define CLEAR_CRIT { int i; for(i=0;i<N_CRIT;i++) crit[i]=NULL; }
- X
- Xint NeedFold = 0; /* Number of folds needed for this line */
- Xint FoldCol = -1; /* Proposed left edge of folded line */
- Xchar *folds [64]; /* Places to fold the current line */
- X
- Xchar *FoldHeuristic ();
- X
- X
- XFoldLine (s) /* Put Fold Marks in the right place in the line */
- X char *s;
- X{
- X char *p;
- X int i;
- X int col = 0; /* Current column in output line */
- X char *NonBlank = NULL; /* First non-blank character */
- X int CantFold = 0; /* Set it if we have trouble folding */
- X
- X /* Set up array of pointers into the line of possible places to fold,
- X * in order of aesthetic desirability. */
- X char *crit [N_CRIT];
- X char *SemiWait = NULL, *BlankWait = NULL;
- X
- X CLEAR_CRIT;
- X FoldCol = -1;
- X NeedFold = 0; /* assume we won't need to fold line */
- X
- X if (! PageWidth) return; /* Don't bother folding lines */
- X
- X /* Step through line, looking for good places to fold */
- X for (p=s; *p; p++) {
- X switch (*p) {
- X case '\n': /* ignore */
- X break;
- X
- X case ' ': /* Whitespace is harmless */
- X col++;
- X BlankWait = p; /* remember we've seen a blank */
- X break;
- X
- X case '\t': /* Space out a tab's worth */
- X while ((++col) % TabWidth);
- X col++;
- X BlankWait = p; /* remember we've seen a blank */
- X break;
- X
- X case '/':
- X if (*(p+1) == '*') /* beginning of a comment */
- X crit [COMMENT] = p;
- X col++;
- X break;
- X
- X case '{':
- X if (*(p-1) != '\'')
- X crit [BRACKET] = p;
- X col++;
- X break;
- X
- X case ';': /* Remember we've seen a semicolon */
- X col++;
- X if (*(p-1) != '\'')
- X SemiWait = p;
- X break;
- X
- X case '(':
- X if (*(p-1) != '\'')
- X crit [PAREN] = p;
- X col++;
- X break;
- X
- X default:
- X col++;
- X break;
- X }
- X
- X /* If non-blank, do a few housekeeping things */
- X if (*p!=' ' && *p!='\t' && *p!='\n') {
- X if (FoldCol == -1) {
- X NonBlank = p;
- X FoldCol = col + 1;
- X }
- X if (BlankWait) { /* waiting after blank */
- X crit [BLANK] = p;
- X BlankWait = 0;
- X }
- X if (SemiWait && SemiWait!=p) {
- X crit [SEMICOLON] = p;
- X if (*p!=';') SemiWait = 0;
- X }
- X }
- X
- X /* Do we need to fold yet ? */
- X if (col+FirstCol >= PageWidth && *p!=' ' && *p!='\t') {
- X /* Can we fold? We can tell by checking our pointers
- X * in order of decreasing aesthetic result of fold.
- X */
- X char *FoldHere;
- X
- X FoldHere = FoldHeuristic (s, NonBlank, crit);
- X if (FoldHere)
- X folds [NeedFold++] = FoldHere;
- X else
- X CantFold++;
- X
- X /* Do some cleaning up after folding */
- X if (FoldHere) {
- X col = FoldCol;
- X p = FoldHere;
- X
- X CLEAR_CRIT;
- X BlankWait = SemiWait = NULL;
- X }
- X }
- X }
- X if (CantFold) /* complain, but print anyway and continue */
- X fprintf(stderr,"%s: trouble folding line %ld of file %s\n",
- X ProgName, FileLineNumber, Name);
- X}
- X
- X/* Output the line, folding where indicated in folds[] */
- X
- XOutputLine (p)
- X char *p;
- X{
- X int i = 0;
- X
- X if (! NeedFold) /* don't bother folding lines */
- X printf ("%s",p);
- X
- X else { /* gotta fold lines */
- X for (; *p; p++) {
- X if (p==folds[i] && i<NeedFold) { /* fold to a new line */
- X putchar ('\n');
- X if (++LineNumber >= PageEnd) NewPage();
- X if (NumberFlag)
- X printf (BLANKFORMAT);
- X GoToColumn (FirstCol, FoldCol+FirstCol);
- X i++;
- X }
- X putchar (*p);
- X }
- X }
- X}
- X
- X/* Heuristic for determining where to fold */
- X
- X#define MAX( x, y ) ((x) > (y)) ? x : y
- X#define MIN( x, y ) ((x) < (y)) ? x : y
- X#define MAXC( c, j ) for(i=j=0;i<N_CRIT;i++) if(c[i]>c[j]) j=i
- X
- Xchar *
- XFoldHeuristic (s, NonBlank, crit)
- X char *s; /* pointer to line */
- X char *NonBlank; /* pointer to first non-blank character */
- X char *crit[]; /* pointers to likely places to fold, based on
- X * aesthetic criteria */
- X{
- X int i,j;
- X int score [N_CRIT]; /* keep some "scores" here */
- X int credit; /* score value increments (in columns) */
- X char *lptr; /* points to start of partial line */
- X char *p;
- X
- X /* For each crit[] pointer, it's worthless as a folding point if it's
- X * the first non-blank in the line. */
- X for (i=0; i<N_CRIT; i++)
- X if (crit[i]==NonBlank) crit[i] = NULL;
- X
- X /* Fold on a comment, if we've got one */
- X if (crit [COMMENT]) return (crit [COMMENT]);
- X
- X /* For the rest, we'll compute some heuristic "scores".
- X * Start by seeing how much of the partial line each crit picks up. */
- X score [COMMENT] = 0;
- X if (NeedFold) /* line already folded */
- X lptr = folds [NeedFold-1];
- X else
- X lptr = NonBlank;
- X for (i=1; i<N_CRIT; i++)
- X if (crit [i])
- X score [i] = crit [i] - lptr;
- X else score [i] = 0;
- X
- X /* Adjust the scores according to some "feel for aesthetics".
- X * Start by giving each criterion credit for its order in the array;
- X * "credit" is measured by the number of columns it's worth.
- X * We'll estimate a unit of "credit" as a fraction of the line
- X * that we're trying to fill.
- X */
- X
- X credit = PageWidth - (lptr - s); /* width of current partial */
- X credit = credit / 10; /* "arbitrary" fraction of line */
- X for (i=1; i<N_CRIT; i++)
- X if (score [i])
- X score [i] += (N_CRIT - i - 1) * credit;
- X
- X /* Next, see how "valuable" a paren is from its context. */
- X if (p = crit [PAREN]) {
- X char *pp;
- X pp = p-1;
- X if (*pp==' ' || *pp=='\t')
- X score[PAREN] += 2 * credit;
- X else if (*pp=='(') {
- X /* Find the left edge of string of parens */
- X while (--pp) {
- X if (pp < lptr) {
- X /* Parens all the way left. Quit */
- X score[PAREN] -= credit;
- X break;
- X }
- X else if (*pp==' ' || *pp=='\t') {
- X /* Isolated! Point to it & give bonus */
- X crit [PAREN] = pp+1;
- X score[PAREN] = (pp - lptr) + 1 + 2*credit;
- X break;
- X }
- X else if (*pp!='(') {
- X /* Nothing special. Point & give small bonus */
- X crit [PAREN] = pp+1;
- X score[PAREN] = (pp - lptr) + credit;
- X break;
- X }
- X /* If we got here, keep searching */
- X }
- X }
- X else /* Nothing special. Small bonus */
- X score [PAREN] += credit - 1;
- X }
- X
- X /* Now, just return the highest score. */
- X MAXC( score, j );
- X return ( crit[j] );
- X}
- X
- !EOR!
- echo extracting - report.c
- sed 's/^X//' > report.c << '!EOR!'
- X/* REPORT.C
- X *
- X * Prints out the table of contents and listed .C files.
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X
- X#include "cpr.h"
- X
- X#define HEADER_SIZE 3
- X#define TOC_SIZE 4096
- X
- Xstatic char *Toc[TOC_SIZE]; /* array of pointers to malloc-ed TOC strings */
- Xstatic int TocPages[TOC_SIZE]; /* page on which the item occurs */
- Xstatic int TocCount; /* how many TOC lines so far */
- X
- Xchar FileDate[24]; /* Last modified time of file */
- X
- X
- XNewPage()
- X /* Note that PageNumber is -1 during TableOfCont processing */
- X{
- X static int CountNewPage=0; /* suppress blank pre-page */
- X
- X if( PageNumber >= 0 ) {
- X ++PageNumber;
- X putchar(BP);
- X }
- X else /* we're doing TOC */
- X if( CountNewPage++ ) putchar(BP); /* don't put first BP */
- X LineNumber = 0;
- X
- X PutHeader();
- X}
- X
- XPutHeader()
- X{
- X register int i, l, j;
- X
- X putchar('\n');
- X ++LineNumber;
- X l = strlen(Name);
- X for( j=0; j < l; ++j )
- X printf("%c\b%c\b%c", Name[j], Name[j], Name[j]);
- X
- X if( PageNumber > 0 )
- X {
- X printf(" %.17s", FileDate);
- X GoToColumn(l+19, 70);
- X printf("Page:%4d\n\n", PageNumber);
- X ++LineNumber;
- X ++LineNumber;
- X }
- X else
- X {
- X GoToColumn(l, 55);
- X printf("%s\n\n", Today);
- X ++LineNumber;
- X ++LineNumber;
- X }
- X}
- X
- XGoToColumn(from, to)
- Xregister int from, to;
- X{
- X if( from < to)
- X {
- X if( TabWidth > 0 ){
- X from &= ~(TabWidth-1);
- X for( ; (from + TabWidth) <= to; from += TabWidth )
- X putchar('\t');
- X }
- X for( ; from < to; from++ )
- X putchar(' ');
- X }
- X}
- X
- X
- XAddToTableOfContents(type)
- X{
- X if( TocCount > TOC_SIZE )
- X return;
- X if( TocCount == TOC_SIZE )
- X {
- X fprintf(stderr, "%s: More than %d Table of contents entries; others ignored.\n",
- X ProgName, TOC_SIZE);
- X ++TocCount;
- X return;
- X }
- X
- X if( type == NEWFILE )
- X AddFile();
- X else
- X AddFunction();
- X}
- X
- XAddFunction()
- X{
- X register int l;
- X register char *p;
- X
- X /* This heuristic stops multiple occurrences of a function,
- X * selected by #ifdefs, to all end up many times over in the
- X * Table of Contents. One only needs to see it once. -IAN!
- X */
- X if( TocCount > 0 && TocPages[TocCount-1] == PageNumber
- X && strcmp(Toc[TocCount-1],FunctionName) == 0 )
- X return;
- X l = strlen(FunctionName);
- X p = Toc[TocCount] = (char *)malloc(l+1);
- X strcpy(p, FunctionName);
- X TocPages[TocCount] = PageNumber;
- X ++TocCount;
- X}
- X
- XAddFile()
- X{
- X register int i, l;
- X register int len;
- X char temp[20];
- X
- X len = strlen(Name) + 20;
- X len = (len < 130) ? 130 : len;
- X Toc[TocCount] = (char *)malloc(len);
- X sprintf(Toc[TocCount], "\n File: %s ", Name);
- X l = strlen(Toc[TocCount]);
- X if( l < 64 )
- X {
- X if( TabWidth > 0 ){
- X i = ((64 - l) /TabWidth) + 1;
- X while( i-- > 0 )
- X Toc[TocCount][l++] = '\t';
- X }
- X else{
- X while( l < 64 )
- X Toc[TocCount][l++] = ' ';
- X }
- X Toc[TocCount][l++] = '\0';
- X }
- X sprintf(temp, " Page %4d\n", PageNumber);
- X strcat(Toc[TocCount], temp);
- X ++TocCount;
- X}
- X
- XNewFile()
- X{
- X GetFileTime();
- X if( ResetPage ) PageNumber=0;
- X NewPage();
- X AddToTableOfContents(NEWFILE);
- X FileLineNumber = 0;
- X}
- X
- XGetFileTime()
- X{
- X struct stat st;
- X extern char *ctime();
- X
- X if( File == stdin )
- X strncpy(FileDate, &Today[4], 20);
- X else
- X {
- X fstat(fileno(File), &st);
- X strncpy(FileDate, ctime((time_t *)&st.st_mtime) + 4, 20);
- X }
- X strncpy(&FileDate[12], &FileDate[15], 5);
- X FileDate[18] = '\0';
- X}
- X
- XDumpTableOfContents()
- X{
- X register int i, j;
- X int TocIncr = 0;
- X int index[TOC_SIZE];
- X int Files = 0; /* How many files reported so far */
- X int Functions = 0; /* How many functions reported so far? */
- X int EveryFourth;
- X
- X if( TocCount == 0 ) return;
- X
- X for (i = 0; i < TocCount; i++) index[i] = i;
- X
- X if( XrefFlag ) { /* XREF - put files as first entries.
- X * SortTable() will do the rest. */
- X FilesFirst ();
- X TocIncr = 1; /* start printing AFTER the \n */
- X }
- X
- X if( SortFlag )
- X SortTable(index);
- X
- X Name = "Table of Contents";
- X
- X PageNumber = -1;
- X LineNumber = 0;
- X
- X if( Title )
- X {
- X FILE *f;
- X int n;
- X char b[256];
- X
- X if( (f=fopen(TitleFile,"r")) == NULL )
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",
- X ProgName, TitleFile, sys_errlist[errno] );
- X else
- X {
- X while( fgets(b, 256, f) != NULL )
- X {
- X if( strlen(b) ) b[strlen(b)-1]=0;
- X puts(b);
- X LineNumber++;
- X if( ++LineNumber >= PageEnd ) NewPage();
- X }
- X
- X fclose(f);
- X }
- X }
- X else
- X NewPage();
- X
- X for( i=0; i < TocCount; ++i )
- X {
- X if( Toc[index[i]][0] == '\n' ) /* File entry */
- X {
- X if( (LineNumber + 5) >= PageEnd ) NewPage();
- X
- X /* Play with the leading \n in file entry */
- X EveryFourth = ( !(Files++ & 3) && XrefFlag );
- X printf("%s", Toc[index[i]]+TocIncr-EveryFourth);
- X LineNumber += 2 - TocIncr + EveryFourth;
- X continue;
- X }
- X else /* Function entry */
- X {
- X if (! Functions++ && XrefFlag) {
- X printf( "\nFunction Index:\n");
- X LineNumber += 2;
- X }
- X }
- X if( ++LineNumber >= PageEnd ) NewPage();
- X
- X printf(" %s ", Toc[index[i]]);
- X for( j=strlen(Toc[index[i]]); j < 48; ++j ) putchar('.');
- X printf(" %4d\n", TocPages[index[i]]);
- X }
- X
- X if( ContentsOnly ) NewPage();
- X}
- X
- XFilesFirst ()
- X{
- X int i;
- X int FirstNonFile = 0;
- X char *Ctemp;
- X int Itemp;
- X
- X for (i=0; i<TocCount; i++)
- X if (Toc [i][0] == '\n') { /* swap file entry down */
- X Ctemp = Toc [i];
- X Toc [i] = Toc [FirstNonFile];
- X Toc [FirstNonFile] = Ctemp;
- X
- X Itemp = TocPages [i];
- X TocPages [i] = TocPages [FirstNonFile];
- X TocPages [FirstNonFile] = Itemp;
- X
- X FirstNonFile++;
- X }
- X}
- X
- XSortTable(index)
- Xregister int *index;
- X{
- X register int i, temp, flag;
- X char name1[256];
- X char name2[256];
- X
- X do {
- X flag = 0;
- X for (i = 0; i < TocCount - 1; i++)
- X {
- X if( Toc[index[i]][0] == '\n' || Toc[index[i+1]][0] == '\n' )
- X continue; /* don't sort across file names */
- X strcpy( name1, Toc[index[i]] );
- X strcpy( name2, Toc[index[i+1]] );
- X
- X if( CaseInsensitive )
- X {
- X char *p;
- X char c;
- X for(p=name1; c=*p; p++ )
- X if( islower(c) ) *p=toupper(c);
- X for(p=name2; c=*p; p++ )
- X if( islower(c) ) *p=toupper(c);
- X }
- X
- X if( strcmp(name1, name2) > 0)
- X {
- X temp = index[i];
- X index[i] = index[i+1];
- X index[i+1] = temp;
- X flag = 1;
- X }
- X }
- X }
- X while( flag );
- X}
- X
- !EOR!
- echo extracting - wildfile.c
- sed 's/^X//' > wildfile.c << '!EOR!'
- X/* Expand wildcards (e.g., for MSDOS, which doesn't do it for you).
- X * Note that the MSDOS wildcard conventions are used, not the
- X * UNIX conventions.
- X *
- X * The following code is a prototype of the use of these functions,
- X * if 'fname' points to the [wildcarded] name of the file:
- X *
- X * #ifdef NOWILD
- X * strncpy (fname, first_file (fname), MAXNAME);
- X * while ((fname!=NULL) && (*fname!='\0')) {
- X * process_file (fname);
- X * strncpy (fname, next_file (fname), MAXNAME);
- X * }
- X * #else
- X * process_file (fname);
- X * #endif
- X *
- X * This file is an example of these functions for Turbo C.
- X * (It isn't needed for Turbo C 2.0, but may be for earlier ones.)
- X */
- X
- X#include <stdio.h>
- X
- X#ifdef NOWILD
- X#ifdef TURBOC
- X
- X#include <dos.h>
- X#include <dir.h>
- X
- Xstruct ffblk fb;
- Xchar fullname[MAXPATH];
- Xint dirlen;
- X
- X/* Find the first file meeting the wildcard spec, and return its name */
- Xchar *
- Xfirst_file (fn)
- X char *fn; /* filename (perhaps complete pathname */
- X{
- X int ffflag;
- X int splitflag;
- X char drive[MAXDRIVE], dir[MAXDIR],
- X name[MAXFILE], ext[MAXEXT];
- X
- X /* Get path part, if any */
- X splitflag = fnsplit (fn, drive, dir, name, ext);
- X strcpy (fullname, drive);
- X strcat (fullname, dir);
- X dirlen = strlen (fullname);
- X
- X ffflag = findfirst (fn, &fb, FA_RDONLY+FA_ARCH);
- X if (ffflag) { /* No files match */
- X if (splitflag & WILDCARDS) /* done if wildcard */
- X return (NULL);
- X else /* complain if not wild */
- X return (fn);
- X }
- X else {
- X if (dirlen) {
- X strcpy (fullname+dirlen, fb.ff_name);
- X return (fullname);
- X }
- X else
- X return (fb.ff_name);
- X }
- X}
- X
- X/* Find the next file meeting the wildcard spec, and return its name */
- Xchar *
- Xnext_file ()
- X{
- X int ffflag;
- X
- X ffflag = findnext (&fb);
- X if (ffflag) /* No more matching files */
- X return (NULL);
- X else {
- X if (dirlen) {
- X strcpy (fullname+dirlen, fb.ff_name);
- X return (fullname);
- X }
- X else
- X return (fb.ff_name);
- X }
- X}
- X
- X#endif
- X#endif
- !EOR!
- echo extracting - cpr.h
- sed 's/^X//' > cpr.h << '!EOR!'
- X/************** Header File For CPR ************************/
- X
- X#ifdef MAIN
- X# define EXTERN
- X# define INIT(x) =x
- X#else
- X# define EXTERN extern
- X# define INIT(x)
- X#endif
- X
- Xextern int errno; /* system error number */
- Xextern char *sys_errlist[]; /* error message */
- Xextern char *malloc() ; /* important for 8086-like systems */
- X
- X#define BP 0xC /* Form feed */
- X
- X#define NEWFILE 1
- X#define NEWFUNCTION 2
- X
- X/* Define formats for beginning of line */
- X#define NUMFORMAT "%6ld "
- X#define BLANKFORMAT " "
- X#define FORMATWIDTH 8
- X
- X#define NULLSTR( x ) ((x == NULL) || (*x == '\0'))
- X#define WHITESPACE(x) (strchr (" \n\r\t", x))
- X
- X/* Option flag variables */
- XEXTERN int PageLength INIT( 66 ); /* -l, <len> Page length */
- XEXTERN int PageWidth INIT( 0 ); /* -w, page width for line folding */
- XEXTERN int PagePart INIT( 12 ); /* -p, Decision on paging for new fn*/
- XEXTERN int PageEnd INIT( 59 ); /* Accounts for space at bottom (7 lines) */
- XEXTERN int Title INIT( 0 ); /* -T, print a title file */
- XEXTERN int ResetPage INIT( 0 ); /* -N, each file resets page # */
- XEXTERN int ContentsOnly INIT( 0 ); /* -C, only ToC, no listings */
- XEXTERN int SortFlag INIT( 0 ); /* -s, sort table of contents */
- XEXTERN int CaseInsensitive INIT( 0 ); /* -S, case-insens sort */
- XEXTERN int XrefFlag INIT( 0 ); /* -x, cross-reference */
- XEXTERN int NumberFlag INIT( 0 ); /* -n, line numbers in output */
- XEXTERN int FirstCol INIT( 0 ); /* starting column for listing (-n) */
- XEXTERN int Space_to_leave INIT( 5 ); /* -r<number> space to leave */
- XEXTERN int TabWidth INIT( 8 ); /* -t <number> width of tabs */
- XEXTERN int OnlyCFiles INIT( 0 ); /* -c, only look in C files */
- X
- X/* State variables for the program */
- XEXTERN long FileLineNumber; /* Input file line number */
- XEXTERN int LineNumber; /* Output line on this page */
- XEXTERN int PageNumber INIT( 0 ); /* You figure this one out */
- XEXTERN int InComment;
- XEXTERN int InString;
- X
- XEXTERN char *TitleFile;
- XEXTERN char *ProgName;
- XEXTERN char Today[30];
- XEXTERN char *Name; /* Current file name */
- XEXTERN char FunctionName[80];
- X
- X/* Help with parsing the command line and argument file */
- XEXTERN int InArgFile INIT( 0 );
- XEXTERN char arg[1024]; /* buffer for current argument */
- XEXTERN char *listn; /* argument file name */
- XEXTERN FILE *listf; /* argument file */
- XEXTERN FILE *File;
- XEXTERN FILE *Tfile; /* title file */
- X
- !EOR!
- echo extracting - makefile
- sed 's/^X//' > makefile << '!EOR!'
- X# MAKEFILES FOR CPR:
- X# Pick out your system, extract the sub-makefile, and go.
- X# Note: this makefile is untested, and probably won't work as is;
- X# use it as a guide.
- X
- X# For UNIX System V.
- XSRC=cpr.c parsargs.c list.c fold.c report.c
- XOBJ=cpr.o parsargs.o list.o fold.o report.o
- XHDR=cpr.h
- XTARGET=cpr
- XCC=cc -c -O
- XLINK=cc -o cpr
- X
- X# For MSDOS using Turbo C 2.0 or later
- XSRC=cpr.c parsargs.c list.c fold.c report.c
- XOBJ=cpr.obj parsargs.obj list.obj fold.obj report.obj \tc\lib\wildargs.obj
- XHDR=cpr.h
- XTARGET=cpr.exe
- XCC=tcc -O -DMSDOS -DTURBOC
- XLINK=tcc
- X
- X# For MSDOS using Microsoft C 5.0 or later
- X# (Note: in the "rules" section, end each command line with ';')
- XSRC=cpr.c parsargs.c list.c fold.c report.c
- XOBJ=cpr.obj parsargs.obj list.obj fold.obj report.obj \msc\lib\setargv.obj
- XHDR=cpr.h
- XTARGET=CPR.EXE
- XCC=msc -O -DMSDOS
- XLINK=link
- X
- X# For systems that don't expand wildcards on command line
- X# (including earlier MS C and Turbo C),
- X# replace the "special" .obj with "wildfile.obj", which you will write
- X# yourself. A sample wildfile.c is given for early Turbo C.
- X# Also, compile with the additional flag NOWILD.
- X
- X# Generic Makefile section
- X
- X.c.o:
- X $(CC) $*.c
- X
- X$(TARGET) : $(OBJ)
- X $(LINK) $(OBJ)
- X
- X$(OBJ) : $(HDR)
- X
- X# Make a listing using cpr. This "bootstraps" from a good cpr.
- Xlisting : cpr.cpr
- Xcpr.cpr : $(SRC) $(HDR)
- X cpr -Xp9w83 $(SRC) $(HDR) > cpr.cpr
- X
- !EOR!
-
-