PF.C ·
C ·
14.6 KB ·
1986-02-10 ·
from CompuLink-User-Group_Magazette_Vol-2-Issue-2_1986
/* Program : PF */
/* Function: Print text files */
/* Written : December 1984 */
/* Author : George Perfect */
/* Version : 1.04, 11 September 1985 */
/* Amended : 26/6/85, GMP, V1.01, file pathname handling*/
/* : 28/6/85, GMP, V1.02, comment subtitles and */
/* : tab character processing (-c and -t opts) */
/* : 3/8/85, GMP, V1.03, Skip and Reprint */
/* : options added to pause. */
/* : 11/9/85, GMP, V1.04 process form-feeds as */
/* : start of page with headings */
/* Copyright (C) George Perfect 1984,1985 */
/********************************************************/
#include "stdio.h"
#include "ctype.h"
#define TRUE 1
#define FALSE 0
#define ON 1
#define OFF 0
#define ABORT -1
#define SUCCESS 0
#define SKIPFILE 1
#define REPRINT 2
#define LF 10
#define FF 12
#define CR 13
#define SPACE 32
#define TAB 9
#define SW_CHAR '-'
/* File name list structure */
/****************************/
struct listel
{
struct listel *next;
char *name;
} *listhead = NULL;
/* Parameters used in the formatting process */
/*********************************************/
int findfile(char *, long *);
char *calloc();
int margin, linewidth, pagedepth;
int tabsep;
int lnum, col;
int numbers = OFF, heading = ON;
int group = OFF;
int page;
char *comment;
char path[128], fname[128];
/* main() */
/* Print sign-on message, parse the command line */
/* and print individual files */
/******************************************************/
main(argc,argv)
int argc;
char *argv[];
{
char *version = "1.05, February 1985 ";
FILE *fopen();
char filename[65];
char c;
long fsize;
margin = 0;
linewidth = 80;
pagedepth = 60;
tabsep = 8;
comment = NULL;
printf("\nPF: Print File utility ");
printf(" Copyright (C) 1985, George Perfect\n");
printf("Version: V%s\n", version);
if (argc == 1) /* no arguments - show usage */
{
help();
exit(0);
}
else while (--argc > 0)
{
c = (*++argv)[0]; /* get first character */
if (c == SW_CHAR)
{
c = (*argv)[1]; /* get command character */
c = tolower(c); /* allow options in either case */
switch (c)
{
case 'n':
numbers = !numbers;
break;
case 'g':
group = !group;
break;
case 'h':
heading = !heading;
break;
case 'm':
margin = atoi(*argv+2);
break;
case 'w':
linewidth = atoi(*argv+2);
break;
case 'p':
pagedepth = atoi(*argv+2);
break;
case 't':
tabsep = atoi(*argv+2);
break;
case 'c':
comment = *++argv;
break;
default:
printf("\nInvalid option '%s'", *argv);
help();
exit(1);
}
}
else
/* Must be a file spec */
/***********************/
{
strcpy(filename, *argv);
fsplit(filename, path, fname); /* parse filename */
/* Obtain dummy entry for start of list */
/****************************************/
if (listhead == NULL)
{
if ((listhead = (struct listel *) calloc(1, sizeof(struct listel))) == NULL)
{
printf("No memory for file list - unable to continue\n");
exit(1);
}
listhead->name = NULL;
listhead->next = NULL;
}
while (findfile(filename, &fsize))
{
fcomb(fname, path, filename);
addname(fname);
}
if (! group) /* Print individual groups */
printlist();
}
}
/* Print files if "grouped" */
/****************************/
if (group)
printlist();
putch(CR);
putch(LF);
fcloseall();
}
/* printlist() */
/* Print all files in list */
/************************************************/
printlist()
{
struct listel *nextfile, *nd;
nextfile = listhead;
while (nextfile->name)
{
if (printfile(nextfile->name) == ABORT)
exit(2);
putc(CR, stdprn);
putc(FF, stdprn);
nd = nextfile;
nextfile = nextfile->next;
free(nd->name);
free(nd);
}
listhead = NULL; /* Reset list for next group */
}
/* addname(filename) */
/* Insert 'filename' in list of file names in */
/* alphabetic order */
/******************************************************/
addname(filename)
char *filename;
{
char *strsave();
char *p;
struct listel *nl, *new;
int c;
if ((p = strsave(filename)) == NULL)
{
printf("No memory for file list - please select fewer files\n");
exit(1);
}
if ((new = (struct listel *) calloc(1, sizeof(struct listel))) == NULL)
{
printf("No memory for file list - please select fewer files\n");
exit(1);
}
nl = listhead; /* start at head of list */
while (nl->next && ((c = strcmp(nl->name, p)) < 0))
nl = nl->next; /* next list entry */
new->next = nl->next;
new->name = nl->name;
nl->next = new;
nl->name = p;
}
/* printfile(filename) */
/* Print the ASCII file specified by 'filename' */
/* which must contain the full path */
/******************************************************/
printfile(filename)
char *filename;
{
int c, i;
int lm, line;
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL)
{
printf("\nCan't open file '%s' ... exitting\n", filename);
exit(1);
}
else
printf("\n%s", filename);
lnum = 0; /* init line counter */
col = page = 0;
line = 1;
if (numbers)
lm = margin-7;
else
lm = margin;
if (lm < 0)
lm = 0;
if (heading)
newpage(filename, lm);
/* Print the file */
/******************/
while ((c = getc(fp)) != EOF)
{
/* Check for operator pause */
/****************************/
if (kbhit())
{
switch(pause())
{
case ABORT:
fclose(fp);
return ABORT;
case SKIPFILE:
fclose(fp);
return SUCCESS; /* flag print OK */
case REPRINT:
fclose(fp);
putc(CR, stdprn);
putc(FF, stdprn);
return(printfile(filename));
case SUCCESS:
break;
default:
printf("Invalid option!\n");
putch(7);
return ABORT;
}
}
/* Start of new line? */
/**********************/
if (! col)
{
domargin(lm);
if (numbers)
{
fprintf(stdprn, "%5d: ", line);
col = 7;
}
}
if (c == TAB)
{
do
{
putc(SPACE, stdprn);
++col;
}
while ((col % tabsep) && (col < linewidth));
}
else if (c == FF)
{
putc(CR, stdprn);
newpage(filename, lm);
}
else
{
++col; /* increment column count */
putc(c, stdprn);
}
/* Need to wrap line? */
/**********************/
if (c != LF && col >= linewidth)
{
putc(CR, stdprn);
putc(LF, stdprn);
if (++lnum > pagedepth)
newpage(filename, lm);
if (numbers)
{
fprintf(stdprn, " : ");
col = 7;
}
else
col = 0;
}
/* End of line */
/***************/
if (c == LF)
{
putc(CR, stdprn);
col = 0; /* reset column count */
line++; /* increment line number */
if (++lnum > pagedepth)
newpage(filename, lm);
}
}
fclose(fp);
return SUCCESS;
}
newpage(filename, lm)
char *filename;
int lm;
{
char date[13], time[9];
long systime();
if (lnum)
putc(FF, stdprn);
if (heading)
{
sysdate(date);
systime(time);
domargin(lm);
fprintf(stdprn, "File: %s %s %s Page:%4d\n", filename, time, date, ++page);
putc(CR, stdprn);
lnum = 2;
/* Print comment if present */
/****************************/
if (comment)
{
domargin(lm);
fprintf(stdprn, "Comment: %s\n", comment);
putc(CR, stdprn);
++lnum;
}
fprintf(stdprn, "%\n");
putc(CR, stdprn);
++lnum;
}
else
lnum = 0;
}
domargin(n)
int n;
{
int i;
for (i = 0; i < n; i++)
putc(SPACE, stdprn);
}
pause()
{
int key;
purgekey(); /* Purge keyboard buffer */
pause_msg();
key = NULL;
while (TRUE)
{
key = getch();
key = toupper(key);
switch (key)
{
case 'A':
printf("%c\n\nJob aborted!\n", key);
return ABORT;
case 'S':
printf("%c\n", key);
return SKIPFILE;
case 'R':
printf("%c\n", key);
return REPRINT;
case 'C':
printf("%c\n", key);
return SUCCESS;
default:
putch(7);
}
}
}
pause_msg()
{
printf("\nPrinting temporarily suspended ...\n\n");
printf("\tPress :\tA to abort job\n");
printf("\t\tS to skip to next file\n");
printf("\t\tR to re-print the current file\n");
printf("\t\tC to continue print run ..:");
}
help()
{
printf("\nUsage :\n\n");
printf("\tpf {option {option {...}}} filespec {{option ...} filespec {...}}");
printf("\n\n\t Options :\n");
printf("\t\t-n\t\tToggles line numbering (default OFF)\n");
printf("\t\t-g\t\tToggles file grouping (default OFF)\n");
printf("\t\t-h\t\tToggles page headings (default ON)\n");
printf("\t\t-mN\t\tSets margin to 'N' spaces\n");
printf("\t\t-wN\t\tSets page width to 'N' columns\n");
printf("\t\t-pN\t\tSets page depth to 'N' lines\n");
printf("\t\t-tN\t\tSets tab stops to 'N' spaces\n");
printf("\t\t-c \"text\"\tPrint comment \"text\" as sub-title\n");
if (! more())
return;
printf("\n\n\tExample:-\n\n");
printf("\t\t pf -m40 -n -c \"Release 2.03\" *.c -n pdef.h\n");
printf("\n\tSets the left-hand margin to 40 spaces, turns line\n");
printf("\tnumbering ON and prints all files with an extention of\n");
printf("\t'.C' in the current directory.\n\n");
printf("\tThe text 'Release 2.03' will appear at the top of each page\n");
printf("\n\tLine numbering is then turned OFF again before file\n");
printf("\t'PDEF.H' is printed.\n");
if (! more())
return;
printf("\n\n\tPressing any key while printing causes the program to\n");
printf("\tpause with the message :-\n");
pause_msg();
printf("\n\n\tResponses should be obvious\n");
}
more()
{
char c;
printf("\nMore? (Y/N) ..:");
purgekey();
do
{
c = getch();
c = toupper(c);
switch (c)
{
case 'Y':
putch(c);
return 1;
case 'N':
putch(c);
return 0;
default:
putch(7);
}
}
while (1);
}
purgekey()
{
while (kbhit())
getch();
}