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();
}