home *** CD-ROM | disk | FTP | other *** search
- /*
- CPR.C " Prints 'C' Files with Table of Contents "
- " AND LOTS MORE "
-
- Turbo C Version 1.0 or 1.5
-
- Originally Written by :
- Paul Breslin
- Human Computing Resources Corp.
- 10 South Mary Street
- Toronto, Ontario
- Canada, M4Y 1P9
-
- Modified by :
- Lance E. Shepard Rick Wise Blake McBride
- CCI & RIT CALCULON Corp. 3900 SW 52nd Ave. #803
- Rochester, NY Rockville, MD 20850 Pembroke Park, FL 33023
-
- John Stidd Dale Loftis
- 1570 Neston Way 3020 Yorba Linda #F-16
- Los Altos, CA 94022 Fullerton, CA 92631
-
- Special Notes:
- A.) Table of Contents is held in Local Data Segment
- So Compile This Program as SMALL (at Minimum).
- */
- /* *************************************************************************
- ** Program Revision History
- **
- ** By Dale Loftis
- ** 10-3-87 Changed WIDTH to 132, Tabs are now every 4, modified so
- ** that temporary file is deleted if control - break is hit,
- ** Improved the clarity of the instructions if no parmeters
- ** are given.
- **
- ** 10-17-87 Changed so that no blank lines are printed in between structures.
- **
- ** 11-06-87 Added -@ RESPONSE FILE feature since you couldn't fit all the
- ** filenames onto the command line, upto 400 files can be printed.
- **
- ** Also adding the "Reading file # x of y" string and made program
- ** check the amount of free disk space before writing the files
- ** as the program would write the output file and run out of disk
- ** space and just put alot of junk on the disk.
- **
- ** 11-08-87 Ver 1.0 Added -h HEADER FILE, -* "Print All 'C' Files,
- ** -x Extra Lines and Program Version Number
- **
- ** 01-10-88 Ver 1.1 Added call to setvbuf() to speed up file access.
- **
- ** 01-25-88 Ver 1.2 Added -t for option of just table of contents list
- **
- ** 01-29-88 Ver 1.3 Fixed Bug. funcname () would not be put in Table of
- ** Contents because of space between funcname and ().
- **
- ** 04-26-88 Ver 1.4 Added -p* option for starting page number and changed
- ** Table of Contents so File Date and Time Shown.
- **
- ** 05-12-88 Ver 3.0 Added -q* option to print files by section number
- ** rather than by page number.
- ** Added -t- option to suppress the Table of Contents
- **
- ** 07-18-88 Ver 3.1 Fixed bug in printing by section where form feed was
- ** not being output at the top of the file.
- */
- /* --------------------------------------------------------------------- */
- /*
- Include Files for Library Function Prototypes
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <alloc.h>
- #include <dos.h>
- #include <dir.h>
- #include <conio.h>
- #include <ctype.h>
- #include <time.h>
- #include <string.h>
- /* --------------------------------------------------------------------- */
- /*
- Some Valuable Definitions
- */
- #define O_RAW O_BINARY /* Handle File as Binary */
-
- #define TEMPORARY_FILENAME "CPR$.TMP" /* temporary file name (always)*/
-
- #define MAJOR_VERSION 3 /* Current Software Version # */
- #define MINOR_VERSION 1
-
- #define BP 0x0C /* Form feed */
- #define COMPRESSED 0x0F /* Compressed Print */
- #define MAX_S 256 /* Maximum string length */
- #define LENGTH 66 /* Default Page Length */
- #define WIDTH 132 /* Default page width */
- #define N_FILES 400 /* Maximum number of files */
- #define TOC_LEN 1024 /* Max Table of Contents entries*/
- #define MAX_FNAME_SIZE 25 /* Max filename length in response file */
- #define MAX_HDR_BYTES 500 /* Max bytes in header file */
- #define HEADER_SIZE 3 /* Header is 3 lines big */
- /* -------------------------------------------------------------------------
- /* These Macros are used to determine valid characters for Table of Contents
- */
-
- /* returns true if letter, digit, '_' or ' '*/
-
- #define isidchr(c) (isalnum(c) || (c == '_') || (c == ' '))
-
- /* returns true if letter, digit, '_', '*', '\t' or '\n' */
-
- #define isiechr(c) (isidchr(c) || c=='*' || c=='\t' || c=='\n')
- /* --------------------------------------------------------------------- */
- /*
- Internal Program Function Prototypes
- */
- int c_break(void); /* Called when BREAK is hit */
- int file_stats(char *); /* File Statistics function */
- char *Rs(); /* Strips trailing blanks from string */
- char *EndComment(); /* Process string until end of comment */
- char *EndString(); /* Process string until end of quoted string */
- char *expand(); /* Process string expanding TABS to Spaces */
- char *substr1();
- /* -------------------------------------------------------------------- */
- /*
- Global Variables
- */
- FILE *TempFile; /* Program Temporary File */
- FILE *File; /* Current File being worked on */
- FILE *Rfile; /* Response File handle */
- FILE *Hfile; /* Header File handle */
-
- struct ffblk fblock; /* struct used for calculating file size */
- struct dfree disk_space; /* struct used for finding free disk space */
-
- char file_time_buff[20]; /* file time is placed here */
- char file_date_buff[20]; /* file date is placed here */
-
- int Braces; /* Keeps track of brace depth */
- int LineNumber; /* Count output lines */
- int PageNumber = 1; /* You figure this one out */
- int SectionNumber = 1; /* and this one to */
- int PageLength = LENGTH; /* Normal paper length */
- int PageWidth = WIDTH; /* normal page width */
- int OnePerPage = 0; /* non-zero puts 1 function/page */
- int NumLines = 0; /* non-zero puts line # in file */
- int Number = 1;
- int WantSorted = 1; /* Sort the table of contents */
- int PageEnd; /* Accounts for space at bottom */
- int InComment; /* Indicates if inside Comment */
- int InString; /* Indicates if inside String */
- int double_strike; /* # of times + 1 to write filename */
- int header_flag; /* non-zero enables print codes/Dates/Page #'s */
- int header_lines; /* number of extra lines from header file */
- int extra_lines; /* non-zero enables extra lines after functions */
- int table_contents; /* non-zero indicates Table of Contents Only */
- int sectionflg; /* non-zero indicates print by section */
-
- unsigned long memfree; /* amount of local memory left for file buffer */
-
- char *TempName; /* pointer to temporary filename */
- char *fname[N_FILES]; /* file names to be worked on */
- char *STDIN = "\n"; /* special string pointer value to */
- /* flag a file as being stdin */
- char *Name; /* Current file name */
- char *ProgName; /* This programs Path and Name */
-
- char *Toc[TOC_LEN]; /* pointers to files in TOC */
- int TocPages[TOC_LEN]; /* page numbers */
- int TocCount; /* index into TOC arrays */
-
- char header_buffer[MAX_HDR_BYTES];/* 500 byte buffer for user defined Page Headers */
- char FunctionName[100]; /* Work area for parsing Func names */
- char Todayv[45]; /* Today's Time and Date */
-
- /* --------------------------------------------------------------------- */
- /*
- The filenames[N_FILES][25] array allocates an array capable of holding
- N_FILES filenames that are up to 25 characters long.
-
- Each filename in DOS can be 12 characters long and the response file
- has a CRLF with each line and we also need a terminating zero byte
- bringing the count up to 15. MAX_FNAME_SIZE bytes are provided for a
- possible path
- */
- /* --------------------------------------------------------------------- */
- char filenames[N_FILES][MAX_FNAME_SIZE]; /* files read from response file */
-
- /* --------------------------------------------------------------------- */
- /*
- ** The following string is the definition of tab stops. Every 'T' is a
- ** tab, any other character is not. It is currently defined as a tab
- ** every 4 spaces. The comment below helps if you want to modify this,
- ** each row being 0+n, 50+n, 100+n, and 150+n, where n is the number
- ** above the declaration. Don't try to number each row with a comment,
- ** because you'll notice that the '\'s make it one big string.
- */
- char *TabDef = "\
- ---T---T---T---T---T---T---T---T---T---T---T---T--\
- -T---T---T---T---T---T---T---T---T---T---T---T--T-\
- ---T---T---T---T---T---T---T---T---T---T---T---T--\
- -T---T---T---T---T---T---T---T---T---T---T---T---T";
- /* ------------------------------------------------------------------------ */
- /*
- /* Program Instructions (Note the %??? arguments)
- /*
- */
- char option_list[] = "\n\
- ----------------------------- VERSION %d.%d SWITCHES ------------------------\n\
- -@* Replace * with Response Filename (1 filename per line )\n\
- -a* Replace * with Drive Wildcard\n\
- -c Printer Codes/Dates/Page #'s off (default is Enabled )\n\
- -d Double Strike Printing Enabled (default is Disabled )\n\
- -h* Replace * with Header Filename\n\
- -l## Replace ## with PageLength (default = %3d )\n\
- -n Numbers Source Lines (Resets to 1 w/each file)\n\
- -o Places 1 function on a Page (default is multiple )\n\
- -p* Replace * with starting Page Number\n\
- -q* Replace * with starting Section Number\n\
- -s Sort Table of Contents by Page # (default is Func. Name )\n\
- -t Print Table of Contents Only (-t- suppress's Table )\n\
- -w## Replace ## with Width (default = %3d )\n\
- -x Enables Extra Lines after Functions (default is Disabled )\n\
- [...] Means multiple filenames may be listed\n\n\
- Response Files should have 1 filename per line up to %d \n\
- characters followed by 1 CRLF and may contain up to %d filenames. \n\n\
- Header Files contain the Strings to Print at the top of \n\
- every page of the listing, entire file can be up to %d bytes.";
-
- /* -------------------------------------------------------------------- */
- /*
- It all Starts With MAIN
- */
- main(argc, argv)
- int argc;
- char **argv;
- {
- unsigned long int total_disk_free = 0;
- unsigned char ch;
- register int i;
- int nextf = 0; /* index into fname[] */
- long thetime;
-
- ctrlbrk(c_break); /* set control-break handler */
- double_strike = 1; /* default to no double strike */
- header_flag = 1; /* default to codes and headers */
- header_lines = 0; /* no extra lines from header file */
- extra_lines = 0; /* no extra lines after functions */
-
- ProgName = argv[0]; /* grab pointer to the programs name */
-
- time(&thetime); /* grab the DOS time and date */
- strcpy(Todayv,ctime(&thetime)); /* convert to ascii (LF at END OF STRING) */
- strtok(Todayv,"\n"); /* strip the annoying LF off */
-
- if (argc == 1) /*if only the program name given */
- Usage(); /* if no args, show instructions */
-
- for (i = 1; i < argc; i++) { /* other parse command line */
- if (argv[i][0] == '-') { /* check for switch flag "-" */
- switch (toupper(argv[i][1])) { /* and go thru the switches */
-
- case '@': /* Response file */
- nextf = ReadResponseFile(argv[i]);
- break;
-
- case 'A': /* "*.???" Print all specified files */
- nextf = StarDot(argv[i]);
- break;
-
- case 'C': /* Print codes/Dates/Time and page # */
- header_flag = 0;
- break;
-
- case 'D': /* Double Strike function names */
- double_strike = 3;
- break;
-
- case 'H': /* Header file */
- ReadHeaderFile(argv[i]);
- break;
-
- case 'L': /* Number of lines per page */
- if ( ! argv[i][2]) { /* if -L ?? (ie.. a space) */
- if (++i >= argc) /* see if another argument */
- Usage(); /* if no then print Help */
-
- if ( ! isdigit (argv[i][0])) /* is it a number? */
- Usage(); /* No! Print Help */
-
- PageLength = atoi (argv[i]); /* assign number */
- }
- else { /* Switch came as -L?? form (with no space) */
- if (!isdigit(argv[i][2])) /* is it a number? */
- Usage(); /* No! Print Help */
-
- PageLength = atoi(&argv[i][2]); /* assign number */
- }
- break;
-
- case 'N': /* Number Source Lines */
- NumLines = 1;
- break;
-
- case 'O': /* 1 function per page */
- OnePerPage = 1;
- break;
-
- case 'P': /* Starting Page Number */
- if ( ! argv[i][2]) { /* if -P ?? (ie.. a space) */
- if (++i >= argc) /* see if another argument */
- Usage(); /* if no then print Help */
- if ( ! isdigit (argv[i][0])) /* is it a number? */
- Usage(); /* No! Print Help */
- PageNumber = atoi (argv[i]); /* assign number */
- }
- else { /* Switch came as -P?? form (with no space) */
- if (!isdigit(argv[i][2])) /* is it a number? */
- Usage(); /* No! Print Help */
- PageNumber = atoi(&argv[i][2]); /* assign number */
- }
- break;
-
- case 'Q': /* Print by Section */
- if ( ! argv[i][2]) { /* if -Q ?? (ie.. a space) */
- if (++i >= argc) /* see if another argument */
- Usage(); /* if no then print Help */
- if ( ! isdigit (argv[i][0])) /* is it a number? */
- Usage(); /* No! Print Help */
- SectionNumber = atoi (argv[i]); /* assign number */
- }
- else { /* Switch came as -Q?? form (with no space) */
- if (!isdigit(argv[i][2])) /* is it a number? */
- Usage(); /* No! Print Help */
- SectionNumber=atoi(&argv[i][2]);/* assign number */
- }
- sectionflg = 1;
- break;
-
- case 'S': /* Sorted Table of Contents */
- WantSorted = 0;
- break;
-
- case 'T': /* Print Table of Contents Only */
- table_contents = 1; /* enable flag */
- if( argv[i][2] == '-') /* if disabling TOC */
- table_contents = -1;/* disable it */
- break;
-
- case 'W': /* Page Width */
- if ( ! argv[i][2]) { /* if -W ?? (ie.. a space) */
- if (++i >= argc) /* see if another argument */
- Usage(); /* if no then print Help */
- if ( ! isdigit (argv[i][0])) /* is it a number? */
- Usage(); /* No! Print Help */
- PageWidth = atoi (argv[i]); /* assign number */
- }
- else { /* Switch came as -W?? form (with no space) */
- if (!isdigit(argv[i][2])) /* is it a number? */
- Usage(); /* No! Print Help */
- PageWidth = atoi(&argv[i][2]); /* assign number */
- }
- break;
-
- case 'X': /* Extra Lines after Functions */
- extra_lines = 1;
- break;
-
- case '\0': /* End of string?(out of enviroment) */
- if (nextf >= N_FILES) {
- fprintf (stderr, "%s: too many files\n", argv[0]);
- exit (1);
- }
- fname[nextf++] = STDIN; /* any in excess goes to STDIN */
- break;
-
- default: /* No arguments given */
- Usage(); /* show program instructions */
- break;
- }
- }
- else { /* Argument (argv[i]) wasn't a switch parmeter */
- if (nextf >= N_FILES) {
- fprintf (stderr, "%s: too many files\n", argv[0]);
- exit (1);
- }
- fname[nextf++] = argv[i]; /* copy pointer to filename */
- }
- }
-
- if ( ! nextf) /* No files were specified */
- fname[nextf++] = STDIN; /* so use STDIN as the input file */
-
- PageEnd = PageLength - (1 + PageLength / 20);
-
- StartTempFile(); /* open temporary file */
-
- for (i = 0; i < nextf; i++) { /* walk thru file list */
- if (fname[i] == STDIN) { /* if no files */
- File = stdin; /* assign stdin as input */
- Name = "Standard Input"; /* assign name for printout */
- fprintf(stderr,"Accepting Input from STDIN, ^Z to END\n");
- }
- else { /* there was a filename */
- if( (File = fopen( Name = fname[i], "r" )) == NULL ) {
- fprintf (stderr, "%s: Can't open file \"%s\"\n",
- ProgName, Name );
- continue; /* keep going if not found */
- }
- else { /* file opened OK so read */
- fprintf(stderr, "\nReading File #%3d of %3d: \" %s \"",
- i+1, nextf, fname[i]);
-
- memfree = coreleft(); /* compute amount of free memory */
- memfree = ( (memfree > 32767L) ?/* if to much memory then */
- 32767L : /* set max for setvbuf */
- memfree ); /* else take as much as u can*/
-
- if( setvbuf(File, NULL, _IOFBF, (int) memfree) != 0) {
- fprintf(stderr,"Input Buffer failed to allocate.\n");
- }
- }
- }
- List(); /* Read File in and process data */
-
- if (File != stdin) { /* if it's not STDIN */
- fclose(File); /* close file & deallocate buffer */
- }
- }
-
- if( PageNumber > 1 || LineNumber > 0 )
- BreakPage();
-
- EndTempFile(); /* Close Temporary File */
-
- fprintf(stderr,"\n\n");
-
- getdfree(0, &disk_space);/* find out free disk space after cpr$.tmp created */
-
- total_disk_free = ( ( (long)disk_space.df_bsec * /* bytes per sector */
- (long)disk_space.df_sclus) * /* sectors per cluster */
- (long)disk_space.df_avail); /* clusters available */
-
- findfirst(TEMPORARY_FILENAME,&fblock,0); /* read temp file size in */
-
- if(fblock.ff_fsize >= total_disk_free) { /* see if copy can be output */
- fprintf(stderr,"Insufficient Disk Space!\n\
- \nMinimum of %lu bytes needed.\
- \n%lu bytes are available\n\
- \nDo You wish to continue? (Y/N)",
- fblock.ff_fsize, total_disk_free);
- do {
- ch = (toupper(getche()) );
- }
- while((ch != 'Y') && (ch != 'N'));
-
- if(ch != 'Y')
- Done(); /* Delete Temporary File */
-
- fprintf(stderr,"\n\n");
- }
-
- if((!table_contents) || /* if TOC and file enabled */
- (table_contents == 1)) /* or TOC only enabled */
- DumpTableOfContents(); /* Print Table of Contents */
-
- if((!table_contents) || /* if TOC and file enabled */
- (table_contents == -1)) /* or no TOC */
- DumpTempFile(); /* then dump the file */
-
- Done(); /* Clean things up and leave */
- }
- /*****************************************************************************/
- Usage()
- {
- fprintf (stderr,"Usage: %s SWITCHES filename [...]",ProgName);
- fprintf (stderr,option_list ,
- MAJOR_VERSION, MINOR_VERSION, LENGTH, WIDTH,
- MAX_FNAME_SIZE-1, N_FILES, MAX_HDR_BYTES);
- exit(1);
- }
- /*****************************************************************************/
- StartTempFile()
- {
- TempName = TEMPORARY_FILENAME; /* Temporary Filename */
-
- if( (TempFile = fopen(TempName, "w")) == NULL ) {
- fprintf (stderr, "%s: Can't open temp file!\n", ProgName);
- exit(1);
- }
- }
- /*****************************************************************************/
- EndTempFile()
- {
- fclose (TempFile);
- }
- /*****************************************************************************/
- DumpTempFile()
- {
- int fd,n;
- char buff[1025];
-
- if ((fd = open (TempName, O_RDONLY | O_RAW)) == -1) {
- fprintf (stderr, "%s: can't open temp file\n", ProgName);
- exit (1);
- }
-
- while ((n = read (fd, buff, 1024)) != 0) {
- if (write (1, buff, n) == -1) {
- fprintf (stderr, "%s: write error (1)\n", ProgName);
- exit (1);
- }
- }
- }
- /*****************************************************************************/
- Done()
- {
- if( TempName ) /* if you created a file */
- unlink( TempName ); /* Delete temporary file */
- exit(0); /* and leave the hard way */
- }
- /*****************************************************************************/
- List() /* Process Incoming File */
- {
- register int bp;
- char buffer[257];
-
- if( sectionflg ) { /* if by section */
- PageNumber = 1; /* Pages start at 1 */
- LineNumber = 0; /* Lines reset each time */
-
- BreakPage(); /* form feed if allowed */
- }
-
- NewPage(); /* bump page & output header */
- NewFile();
-
- bp = Braces = 0; /* no begin page and braces */
-
- while( fgets(buffer, 256, File) != NULL ) { /* read a line upto 256 bytes*/
- Rs(buffer); /* Remove Trailing Spaces */
-
- if( bp ) /* if beginning page */
- NewFunction(); /* setup for new function */
-
- if( (LineNumber + 1) > PageEnd ) /* if going past page end */
- NewPage(); /* start a new page */
-
- if(!Braces && LooksLikeFunction(buffer)) /* no braces and a function */
- AddToTableOfContents(); /* then add to TOC */
-
- bp = PutLine(buffer);
- LineNumber++;
- }
- if( sectionflg ) /* if by sections */
- SectionNumber ++; /* Bump to next Section */
- }
- /*****************************************************************************/
- NewPage() /* Process New Page */
- {
- if( LineNumber > HEADER_SIZE ) {
- if( PageNumber >= 0 ) {
- PageNumber ++; /* bump Page Number */
- }
- BreakPage(); /* form feed if allowed */
- LineNumber = 0; /* set flag for a header */
- }
- if( LineNumber == 0 ) /* Each new page */
- PutHeader(); /* Outputs a Header */
- }
- /*****************************************************************************/
- NewFile()
- {
- register int i, l;
- char temp[80];
-
- if (TocCount >= TOC_LEN) {
- fprintf (stderr, "%s: too many table of contents entries\n", ProgName);
- exit (1);
- }
-
- if( (Toc[TocCount] = (char *) malloc(130)) == NULL) /* allocate some memory */
- ReportMemoryError();
-
- sprintf (Toc[TocCount], "\n\tFile: %s ", Name); /* to put filename into */
- l = strlen(Toc[TocCount]) - 1; /* and findout how long it is */
-
- if( l < 64 ) { /* if not to long */
- i = (64 - l) / 8; /* calc. TAB increment */
- for( l=0; l < i; ++l ) /* keep within 64 columns */
- strcat(Toc[TocCount],"\t"); /* and put some TAB's out */
- }
-
- file_stats(Name); /* findout file stats */
-
- if(! sectionflg ) {
- sprintf (temp, " Page %4d (%s %s)\n", /* Page #, Time & date */
- PageNumber, file_date_buff, file_time_buff);
- }
- else {
- sprintf (temp, " Section %4d (%s %s)\n", /* Section, Time & Date*/
- SectionNumber, file_date_buff, file_time_buff);
- }
-
- strcat(Toc[TocCount], temp); /* copy to main buffer */
- ++ TocCount; /* bump the entries */
-
- if (NumLines) /* if numbering lines */
- Number = 1; /* reset linenumber */
-
- InComment = InString = 0; /* not in comment or string */
- }
- /****************************************************************************/
- PutLine(l)
- register char *l;
- {
- register char c;
- int bp;
- char *save;
- char *section, *p;
- int offset;
- char Digits[15];
- int Size;
- int pos;
-
- bp = 0;
- for( save = expand(l);
- ( (c = *l) != 0);
- ++l ) { /* bump thru the string */
-
- if( InComment ) /* if your in a comment */
- l = EndComment(l); /* process till your out */
- else
- if( InString ) /* if your in a string */
- l = EndString(l); /* process till your out */
- else
- switch(c) { /* it must be something */
- case '{': /* curly brace IN */
- ++Braces; /* increment brace count */
- break;
-
- case '}': /* curly brace OUT */
- if( --Braces == 0) /* coming out yet? */
- if (*(l+1) == ';') /* is it structure? */
- ++l; /* continue thru string */
- else
- if(extra_lines) /* if option enabled */
- bp = 1; /* flag for extra lines */
- break;
-
- case '\'': /* Forward Slash */
- ++l; /* continue thru string */
- break;
-
- case '"': /* Quotation Mark */
- InString = 1; /* must be in a string */
- break;
-
- case '/': /* Start of Comment */
- if( *(l+1) == '*' ) { /* is next character * ? */
- InComment = 1; /* must be in a comment */
- ++l; /* continue thru string */
- }
- break;
- }
- }
-
- if (NumLines) { /* if line numbering enabled */
- sprintf (Digits,"[%d] ", Number); /* make a string */
- Size = strlen(Digits); /* calc. its size */
- }
- else {
- Size = 0; /* else it's size is 0 */
- }
-
- if (strlen(save) + /* if original strings size */
- Size > /* and the size of numbers */
- PageWidth) { /* are bigger than the width */
- section = substr1(save, 0, PageWidth - Size);
-
- if (section[strlen(section) - 1] != ' ')
- if (NULL == (p = strrchr(section, ' ')))
- offset = strlen(section);
- else
- offset = p - section;
- else
- offset = strlen(section) - 1;
-
- section[offset] = NULL;
-
- if (NumLines) { /* if line numbering is enabled */
- fprintf (TempFile, "[%d] %s\n", Number++, section);
- }
- else {
- fprintf (TempFile, "%s\n", section);
- }
-
- pos = offset + 1;
- do {
- section = substr1(save, pos, pos + PageWidth - 8);
- if (strlen(save) - pos + 8 > PageWidth)
- if (section[strlen(section) - 1] != ' ')
- if (NULL == (p = strrchr(section, ' ')))
- offset = strlen(section);
- else
- offset = p - section;
- else
- offset = strlen (section) - 1;
- else
- offset = strlen(section);
-
- section[offset] = NULL;
-
- /** ----------------------------------------------------------------- **/
- /* Removed this for some reason
- /*
- /* if (section[strlen(section) - 1] == '\n')
- /* section[strlen(section) - 1] = NULL;
- */
-
- /* Line is to long for pagewidth so continue on next line */
-
- fprintf (TempFile, "C %s\n", section);
- if (++LineNumber > PageEnd)
- NewPage();
- }
- while ((pos += offset + 1) < strlen(save));
- }
- else {
- if (NumLines) /* if line numbering enabled */
- fprintf (TempFile, "[%d] %s\n", Number++, save);
- else
- fprintf (TempFile, "%s\n", save);
- }
- return(bp);
- }
- /*****************************************************************************/
- NewFunction() /* Process New Function */
- {
- register int i;
-
- if( LineNumber > (PageLength * 3 / 4) ) /* 49.5 lines */
- NewPage();
- else {
- if (!OnePerPage) { /* if mult. functions per page */
- for( i=0; i < (PageLength/7); ++i )
- putc ('\n', TempFile); /* add extra lines */
- LineNumber += PageLength/7; /* set line counter also */
- }
- else
- NewPage(); /* otherwise its 1 func. per page*/
- }
- }
- /*****************************************************************************/
- BreakPage() /* Process Page Break */
- {
- if(header_flag) /* if its allowed send a FORM FEED */
- putc (BP, TempFile);
- }
- /*****************************************************************************/
- PutHeader()
- {
- register int i, l, j;
-
- if(header_flag) /* if its allowed send a COMPRESSED Code */
- putc (COMPRESSED, TempFile);
-
- putc ('\n', TempFile);
-
- if(header_flag ) { /* if its allowed send out the HEADER */
-
- l = strlen(Name); /* Filename or Table of Contents label length */
-
- for( j=0; j < double_strike; ++j) {
- fprintf (TempFile, "%s", Name); /* Write out Filename or TOC */
- if( (j < 2) && (double_strike == 3) )
- putc('\r', TempFile); /* Provide for Double Strike CR */
- }
- if( PageNumber > 0 ) { /* if your not on the TOC pages */
- for( i = (l+7)/8; i < 6; ++i )
- putc ('\t', TempFile); /* Tab out for position */
-
- if(! sectionflg ) {
- fprintf (TempFile, "%s\tPage: %d\n\n\n", Todayv,PageNumber);
- }
- else {
- fprintf (TempFile, "%s\tSection %3d - %d\n\n\n",
- Todayv,SectionNumber,PageNumber);
- }
-
- if(header_lines) /* Header for TOP OF PAGE */
- fprintf (TempFile, "%s", header_buffer);
- }
- else { /* 1st line of Table of Contents page gets the time and date */
-
- for( i = (l+7)/8; i < 6; ++i ) /* Tab out for time/date */
- putc ('\t', TempFile);
-
- fprintf (TempFile, "%s\n\n", Todayv); /* Todays Time and Date */
-
- if(header_lines) /* Header for TOP OF PAGE */
- fprintf (TempFile, "%s", header_buffer);
- }
- }
- LineNumber += (HEADER_SIZE + header_lines); /* bump line number counter */
- }
- /*****************************************************************************/
- LooksLikeFunction(s)
- register char *s;
- {
- register char *p;
- char *save;
- int Cnt, nosl,nolp,norp,flg;
- char Digits[15];
- int AddOne = 0;
-
- if( InComment || InString) /* if your in a comment or in a string */
- return(0); /* just leave and return 0 */
-
- p = FunctionName; /* assign pointer to function name string */
- save = s; /* save address of string */
-
- nosl = nolp = norp = 0; /* no left or right paren or no slash */
-
- flg = 1;
-
- for(; *s && flg ; s++) { /* go until end of string or flag is set */
- switch (*s) { /* switch on each character in string */
- case '(': /* is it a left paren? */
- if (!nolp) { /* if no left paren already */
- nolp = 1; /* flag that you've got one */
-
- /* 3/4/87 added following line to include ARGS in TOC */
-
- *p++ = *s; /* move byte of ARG into function buffer */
- }
- else
- return(0); /* or return if you've already had one */
- break;
-
- case ')': /* is it a right paren? */
- if (nolp && !norp) {/* if already a left paren and no right yet */
- norp = 1; /* flag that you've got a right paren */
-
- /* 3/4/87 added following line to include ARGS in TOC */
- *p++ = *s; /* move byte of ARG into function buffer */
- }
- else
- return(0); /* or return if conditions were'nt right */
- break;
-
- default: /* everything comes thru here */
- if (!nolp) { /* if no left paren yet */
- if (isiechr(*s)) { /* is it alpha,digit,'_*\t\n'? */
- if (isidchr(*s))/* is it alpha,digit,'_' or ' '? */
- *p++ = *s; /* if it is store the byte for TOC */
- else
- p = FunctionName; /* start over if '*\t\n' & nolp */
- break;
- }
- else
- return(0); /* return if conditions weren't right */
- }
-
- if (!norp) { /* if no right paren yet */
- if (isiechr(*s) || *s == ',') { /* is it alpha,digit,'_ *\t\n'?*/
-
- /* 3/4/87 added following line to include ARGS in TOC */
- *p++ = *s; /* move byte of ARG in function buffer */
- break;
- }
- else
- return(0); /* return if conditions weren't right */
- }
-
- if (Cmemb(*s," \t\n\r") && !nosl) /* is it ' \t\n\r' or no slash yet */
- break;
-
- if (*s == '/' && !nosl) { /* is it a '/' and no slash yet */
- nosl = 1; /* flag that you've got one */
- break;
- }
-
- if (*s == '*' && nosl) { /* if its '*' & you got a slash already */
- flg = 0; /* set flag to abort loop */
- break;
- }
- return(0); /* return if conditions not right */
- } /* end of switch */
- } /* end of for loop */
-
- if (nolp != 1) /* return if no left paren found */
- return(0);
-
- *p = '\0'; /* else terminate function buffer */
-
- if (NumLines) { /* if line numbering enabled */
- sprintf (Digits,"[%d] ", Number); /* format number into string */
- Cnt = strlen(Digits) + AddOne;
- while (Cnt-- > 0)
- putc (' ', TempFile);
- AddOne = 0;
- }
- /*
- * This will cause the function name part of the line to
- * be double striken.
- */
- if( double_strike == 3) {
- while (*save && *save != '(') /* double strike up to func name */
- putc (*save++, TempFile);
- putc ('\r', TempFile); /* use CR for doublestrike */
- }
- return(1);
- }
- /****************************************************************************/
- AddToTableOfContents()
- {
- register int l;
- register char *p;
-
- if (TocCount >= TOC_LEN) {
- fprintf (stderr, "%s: too many table of contents entries\n", ProgName);
- exit (1);
- }
- l = strlen(FunctionName); /* find how long name is */
- p = Toc[TocCount] = (char *) malloc(l+1); /* allocate just enough memory */
-
- if( p == NULL) /* did it really allocate */
- ReportMemoryError(); /* No! then report error */
-
- strcpy(p, FunctionName); /* copy the name to new space */
- TocPages[TocCount] = PageNumber; /* plug the page number in */
- ++TocCount; /* bump the count */
- }
- /****************************************************************************/
- DumpTableOfContents()
- {
- register int i, j, l;
-
- if( TocCount == 0 ) /* if there nothing to print */
- return; /* then just return */
-
- if (WantSorted) /* if you wanted it sorted by page number */
- SortTableOfContents(); /* then we must sort it first */
-
- Name = "Table of Contents"; /* give me a title for the page */
-
- PageNumber = -1; /* Table of Contents pages are not numbered */
- LineNumber = 0; /* and neither are the lines */
- TempFile = stdout; /* default output to standard out */
-
- NewPage(); /* start out creating a new page */
-
- for( i=0; i < TocCount; ++i ) {
- if( Toc[i][0] == '\n' ) {
- if( (LineNumber + 5) > PageEnd )
- NewPage();
- printf("%s", Toc[i]);
- LineNumber += 2;
- continue;
- }
-
- if( ++LineNumber > PageEnd )/* if going off end of page */
- NewPage(); /* start a new page */
-
- printf("\t\t%s ", Toc[i]); /* print func. name in TOC */
- l = strlen(Toc[i]); /* length if function name with parms */
-
- for( j=l; j < 48; ++j ) /* put dots out to column 48 */
- putchar('.'); /* put dots out to page num. in TOC */
-
- printf(" %d\n", TocPages[i]); /* print page number for function */
- }
-
- if( ! sectionflg ) { /* if not printing by sections */
- if(header_flag) /* if control codes are allowed */
- putchar(BP); /* print a Form Feed */
- else
- putchar('\n'); /* otherwise its a New Line */
- }
- fflush(stdout); /* make sure everything is written out*/
- }
- /****************************************************************************/
- /*
- Sort Table of Contents by Page number rather than function name
- */
- SortTableOfContents()
- {
- register int i, tempint;
- char *tempchar;
- int flag;
-
- do {
- flag = 0; /* default to already sorted */
-
- for (i = 0; i < TocCount - 1; i++) { /* look at them all */
- if (Toc[i][0] == '\n' || Toc[i+1][0] == '\n')
- continue; /* don't sort across file names */
-
- if (strcmp (Toc[i], Toc[i+1]) > 0) {/* compare the strings */
- tempchar = Toc[i]; /* copy to temp pointer */
- Toc[i] = Toc[i+1]; /* swap the pointers in array */
- Toc[i+1] = tempchar; /* put the temp pointer back */
- tempint = TocPages[i]; /* grab the page number */
- TocPages[i] = TocPages[i+1]; /* swap page numbers */
- TocPages[i+1] = tempint; /* put the temp page number back */
- flag = 1; /* indicate you've swapped */
- }
- }
- }
- while (flag); /* go until no more swaps can be made */
- }
- /****************************************************************************/
- char *EndComment(p) /* Process string until you come out of COMMENT */
- register char *p;
- {
- register char c;
-
- while( (c = *p++) != 0 ) /* while there are chars to look at */
- if( c == '*' && *p == '/' ) { /* and there a splat or a slash */
- InComment = 0; /* say your not in the comment */
- break; /* and leave the loop */
- }
- return(p-1); /* returning the new pointer addr. */
- }
- /*****************************************************************************/
- char *EndString(p) /* Process string until you come out of STRING */
- register char *p;
- {
- register char c;
-
- while( (c = *p++) != 0 ) /* while there are chars to look at */
- if( c == '\\' ) { /* and forward slashs for next line */
- continue; /* means "Just read on McDuck" */
- }
- else if( c == '"' ) { /* if you found the ending quote */
- InString = 0; /* say your not in a string anymore */
- break; /* and leave the loop */
- }
- return(p-1); /* returning the new pointer addr. */
- }
- /****************************************************************************/
- /*
- * This is the function substr1(). The calling sequence is:
- *
- * substr1(string, startpos, endpos).
- *
- * The function returns a pointer to a static string (written over -
- * on subsequent calls) which is a substring of the string `string'
- * starting at `startpos' (the first position is 0 (zero)) and ending
- * at `endpos' (non-inclusive). All arguments must be present or
- * strange things happen with the system stack.
- *
- * An example of the use is:
- *
- * x = substr1(string, 2, 5);
- * (where string == "This is a test.")
- *
- * This call returns a pointer to:
- * "is "
- * An error code of -1 is returned is the `endpos' is greater than
- * `startpos'
- *
- * Lance E. Shepard
- */
- char *substr1(string, start, end)
- char *string;
- int start;
- int end;
- {
- static char retstr[MAX_S];
- int loop1;
- int loop2;
-
- if (end < start) {
- exit(-1);
- }
-
- for (loop2 = 0; loop2 < MAX_S; loop2++)
- retstr[loop2] = NULL;
-
- for (loop1 = start, loop2 = 0; string[loop1] != NULL &&
- loop1 < end && loop2 <= MAX_S; loop1++, loop2++)
- retstr[loop2] = string[loop1];
-
- retstr[++loop2] = NULL;
- return(retstr);
- }
- /****************************************************************************/
- /*
- * This is the function `char *expand().' This function takes as
- * an argument a NULL terminated string and replaces all occurances
- * of the tab character with 8 (eight) spaces. The function returns
- * a pointer to a static string which is overwritten on subsequent
- * calls.
- */
- /****************************************************************************/
- char *expand(string)
- char *string;
- {
- int count;
- static char retstr[MAX_S];
-
- for (count = 0; count < MAX_S; retstr[count++] = NULL)
- ;
-
- for (count = 0; *string != NULL; count++, string++) {
- if (*string == '\t') {
- retstr[count] = ' ';
- /* while (((count + 1) % 8) != 0) */
- while (TabDef[count] != 'T')
- retstr[++count] = ' ';
- }
- else
- retstr[count] = *string;
- }
- retstr[count] = NULL;
- return(retstr);
- }
- /****************************************************************************/
- char *Rs(s) /* strip trailing blanks from string */
- char s[];
- {
- int n;
- for (n=strlen(s)-1 ; n >= 0 && isspace(s[n]) ; n--)
- ; /* find the last space in the string */
- s[n+1] = '\0'; /* plop a null char on top of it */
- return(s); /* return pointer to string */
- }
- /****************************************************************************/
- int Cmemb(a,b) /* is character "a" a member of string "b" */
- char a, *b;
- {
- while (*b) /* go until the null character */
- if (a == *b++) /* looking for the character and bumping the pointer */
- return(1); /* returning 1 if its found */
- return( (!a) ? 1 : 0 ); /* return 0 if "a" was a non-zero character */
- }
- /****************************************************************************/
- StarDot(file_string)
- char * file_string;
- {
- extern char filenames[N_FILES][MAX_FNAME_SIZE];
- extern char fnames[N_FILES];
- extern struct ffblk fblock;
- extern struct dfree disk_space;
-
- unsigned long int total_file_size = 0;
- unsigned long int total_disk_free = 0;
- int done;
- int i = 0;
- file_string += 2; /* bump past -A switch */
-
- if( (done = findfirst(file_string,&fblock,0)) != 0) {/* Attempt 1st file read */
- fprintf(stderr,"No Files Found\n");
- exit(1);
- }
- while(!done && i < N_FILES) { /* go until done or to many files */
- strcpy(&filenames[i][0],fblock.ff_name);/* copy names into array */
- fname[i] = &filenames[i++][0]; /* copy pointer to name */
-
- total_file_size += fblock.ff_fsize; /* keep running total of filesizes */
-
- done = findnext(&fblock); /* read next availables file info */
- }
- if( i == N_FILES)
- fprintf(stderr,"Printing ONLY 1st %d Files\n", N_FILES);
-
- getdfree(0, &disk_space); /* find free disk space */
- total_disk_free = ( ((long)disk_space.df_bsec * /* convert to bytes */
- (long)disk_space.df_sclus) *
- (long)disk_space.df_avail);
-
- if((total_file_size * 2) >= total_disk_free) {
- fprintf(stderr,"Insufficient Disk Space!\nMinimum of %lu bytes needed.\
- \nYou Have %lu bytes free\n",
- total_file_size * 2, total_disk_free);
- exit(1);
- }
- return(i); /* return new number of files */
- }
- /*****************************************************************************/
- ReportMemoryError()
- {
- fprintf(stderr,"Memory Allocation Error\n");
-
- if( TempName ) { /* if there is a file to work on */
- EndTempFile(); /* Make sure file is closed */
- unlink( TempName ); /* Delete temporary file */
- }
-
- exit(1);
- }
- /*****************************************************************************/
- ReadHeaderFile(header_file)
- char *header_file;
- {
- extern char header_buffer[MAX_HDR_BYTES];
- extern int header_lines;
- int ch;
- int i = 0;
- int x = 0;
- char *string;
-
- header_file += 2; /* strip the "-h" from the string */
- if(( Hfile = fopen(header_file, "r")) == NULL) {
- fprintf(stderr,"Can't Open Header File %s\n",header_file);
- exit(1); /* terminate abruptly */
- }
- else {
- /* read entire file that is up to MAX_HDR_BYTES characters long */
- while( (ch = fgetc(Hfile)) != EOF) {
- header_buffer[i++] = (unsigned char) ch;
- if(i < MAX_HDR_BYTES)
- continue;
- else
- break;
- }
- header_buffer[i] = '\0'; /* terminate buffer */
-
- fclose(Hfile); /* and close the file */
-
- for(x = 0, string = header_buffer; x <= i; x++) {
- if(*string++ == '\n') /* count number of line feeds */
- header_lines++; /* tell the NewPage Function */
- }
- }
- }
- /*****************************************************************************/
- ReadResponseFile(response_file)
- char *response_file;
- {
- char fpntr[80]; /* area for string to be read into */
- extern char filenames[N_FILES][MAX_FNAME_SIZE];
- extern char fnames[N_FILES];
- extern struct ffblk fblock;
- extern struct dfree disk_space;
-
- unsigned long int total_file_size = 0;
- unsigned long int total_disk_free = 0;
-
- int i = 0;
-
- response_file += 2; /* strip the "-@" from the string */
- if(( Rfile = fopen(response_file, "r")) == NULL) {
- fprintf(stderr,"Can't Open Response File %s\n",response_file);
- exit(1); /* terminate abruptly */
- }
- else {
- /* read a entire line from the Rfile that is up to 80 characters long */
- while(fgets(fpntr,80,Rfile) != NULL && i < N_FILES) {
- strtok(fpntr," \n"); /* strip to LF or space */
- strcpy(&filenames[i][0],fpntr); /* copy names into array */
- fname[i] = &filenames[i++][0]; /* copy pointer to name */
-
- findfirst(fpntr,&fblock,0); /* read file size in */
-
- total_file_size += fblock.ff_fsize; /* keep running total of filesizes */
- }
- fclose(Rfile); /* and close the file */
-
- getdfree(0, &disk_space); /* find free disk space */
- total_disk_free = ( ((long)disk_space.df_bsec * (long)disk_space.df_sclus) *
- (long)disk_space.df_avail);
-
- if((total_file_size * 2) >= total_disk_free) {
- fprintf(stderr,"Insufficient Disk Space!\nMinimum of %lu bytes needed.\
- \nYou Have %lu bytes free\n",
- total_file_size * 2, total_disk_free);
- exit(1);
- }
- return(i); /* return new number of files */
- }
- return(0);
- }
- /*****************************************************************************
- This routine is executed when the CONTROL-BREAK key combination is hit
- *****************************************************************************/
- c_break()
- {
- fprintf(stderr,"Control-Break hit. Program aborting ...\n");
-
- if( TempName ) { /* if you created a file */
- EndTempFile(); /* Make sure file is closed */
- unlink( TempName ); /* Delete temporary file */
- }
- return(0); /* ABORT sequence */
- }
- /*****************************************************************************/
- file_stats(filename)
- char *filename;
- {
- extern struct ffblk fblock;
-
- findfirst(filename,&fblock,0); /* read data into structure */
-
- /* ------------------- Show date in standard format --------------------*/
-
- sprintf(file_date_buff,"%02d-%02d-%02d",
- ((fblock.ff_fdate >> 5) & 0x0f), /* month */
- (fblock.ff_fdate & 0x1f) , /* day */
- ((fblock.ff_fdate >> 9) + 80 )); /* year */
-
- /* ----------------- Show time in 12 Hour Format ------------------- */
- if ( (fblock.ff_ftime >> 0x0b) <= 12)
- {
- sprintf(file_time_buff,"%02d:%02d",
- (fblock.ff_ftime >> 0x0b),
- ((fblock.ff_ftime >> 5 ) & 0x3f )); /* minutes */
- }
- else
- {
- sprintf(file_time_buff,"%02d:%02d",
- ((fblock.ff_ftime >> 0x0b) - 12),
- ((fblock.ff_ftime >> 5 ) & 0x3f )); /* minutes */
- }
- /* ------------------ Decipher whether its AM or PM ---------------- */
- if ( (fblock.ff_ftime >> 0x0b) < 12)
- strcat(file_time_buff," am"); /* for AM */
- else
- strcat(file_time_buff," pm"); /* for PM */
- }
- /*************************************************************************/