Created
February 13, 2012 01:51
-
-
Save tig/1812623 to your computer and use it in GitHub Desktop.
Blast from the past: SPIT - A print formatting utility from 1987
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
spit.c (C) KindelCo Software Systems, 1987, 1988 | |
SPIT - A print formatter for the PC | |
Author: Charles E. Kindel, Jr. (tigger) | |
Started: July 18, 1987 | |
Version: 1.53 | |
SYNOPIS | |
spit [/ln /pn /w /cn /in /hs /fs /o<file> /s] <filename.ext> | |
/ln : where n is the number of lines to be printed on each page. | |
Must be < (PageLen - 4). Default is 56 lines. | |
/pn : where n is the page length in lines. Default is 66 lines. | |
/w : sets compressed mode on IBM/EPSON dot matrix printers. Sets the | |
number of columns to 132. Should come before the /c option on | |
the command line. | |
/cn : where n is the number of columns. Lines read in longer than | |
n will be truncated. The /i option reduces n by the number | |
of columns to indent. Lines longer than n will be truncated. | |
Default for column is 80. Use /w for 132 columns on IBM/EPSON | |
dot matrix printers. | |
/in : where n is the number of columns to indent from the left margin. | |
This option reduces the total number of columns specified with | |
the /c and /w options. | |
/s : Single sheet option. Pauses before printing each page. | |
/o<file> : Where <file> is an output filename. Default is the standard | |
print device (PRN). | |
DESCRIPTION | |
"spit" spits a file with page breaks, headers, footers, page numbers, | |
and indentation out on the printer. It supports the IBM/EPSON dot matrix | |
printers, and uses compressed and double strike characters. | |
In a nutshell spit just echo's characters to the output device (the | |
printer or a file). But it counts lines and sends headers, footers, | |
and page breaks. If a line is longer than the number of columns | |
specified (default is 80) that line is truncated. | |
The headers and footers mentioned above are printed in double strike. | |
The last page of the printout will have the string "end of file" in the | |
footer. | |
LIMITATIONS | |
The program will work on IBM/EPSON compatible dot matrix printers only. | |
It is possible to change the #defines below to match your printer. | |
Does not support color on 43line EGAs. Until Borland supplies a CONIO | |
library that supports 43line egas this program will be monochrome. | |
REVISIONS | |
DATE VER NAME CHANGE | |
July 18, 1987 1.00 Kindel Original | |
July 20, 1987 1.20 Kindel Fixed bugs, Incuded "revised on" | |
Added several features. | |
July 26, 1987 1.21 Kindel Fixed footer on last page. | |
Aug 31, 1987 1.40 Kindel Added Formfeed support, fixed footers | |
again. | |
Oct 11, 1987 1.41 Kindel Lines that were longer than MaxCols | |
previously were thought to be truncated | |
But were really being treated as new | |
lines. Fixed line counting to account | |
for this. Made messages go to STDOUT | |
instead of STDERR. | |
June 1, 1988 1.42 Kindel Added color. | |
June 1, 1988 1.50 Kindel Set up for wildcard support. As soon | |
as TC is modified to automatically | |
expand wildcards, the code I've added | |
will handle multiple files. For now, the | |
user can type more than one file on the | |
command line. | |
Made the filename formatting in | |
the header more robust. | |
Commented out color until CONIO supports | |
43 line EGA. | |
Implemented single sheet option. | |
Fixed problem with Compressed not | |
turning off. | |
June 2, 1988 1.51 Kindel Added "expand wild" to the TC libraries | |
thus this program will automatically | |
expand wildcards. | |
Fixed problem with options: before, | |
only lower case options were recongized | |
now it will recognize both upper and | |
lower case. | |
July 17, 1988 1.52 Kindel After using CLIBFIX to update the libraries | |
to handle 43 and 50 lines, fixed spit to use | |
these features. | |
Nov 15, 1988 1.53 Kindel Update to TC 2.0 | |
*/ | |
/* -------- IMPORTS --------- */ | |
#include <conio.h> | |
#include <stdio.h> | |
#include <process.h> /* exit () */ | |
#include <alloc.h> | |
#include <string.h> /* strtol (string to long) */ | |
#include <dos.h> /* getdate */ | |
#include <time.h> | |
#include <stat.h> | |
/* -------- #defines --------- */ | |
/* Printer specific definitions: */ | |
#define ESC 0x1B /* ASCII code for Escape is 0x1b */ | |
#define INIT 0x00 /* Initialize the Printer */ | |
#define COMPON 0x0F /* Epson code for compressed text is ESC,0x0e */ | |
#define COMPOFF 0x12 /* Code for compressed off is 0x12 */ | |
#define FF 0x0C /* Form Feed */ | |
#define LF 0x0A /* Line Feed */ | |
#define CR 0x0D /* Carraige Return */ | |
#define BOLDON 0x45 /* Bold Print on */ | |
#define BOLDOFF 0x46 /* Bold Print off */ | |
/* Default definitions */ | |
#define DEFLINES 56 /* default number of printed lines */ | |
#define DEFPAGE 66 /* default page length */ | |
#define DEFCOL 80 /* default number of columns */ | |
#define DEFINDENT 0 /* default indentation */ | |
#define DEFOUT "PRN" /* defalut output file name */ | |
/* Other definitions */ | |
#define OPTSTRING "l:L:p:P:wWc:C:i:I:o:O:sSeE" /* option string for getopt (":" means that getopt expects an argument) */ | |
#define LINE_OPT 'L' /* line number option */ | |
#define PAGE_OPT 'P' /* page length option */ | |
#define WIDE_OPT 'W' /* wide option (compressed 132 columns) */ | |
#define COL_OPT 'C' /* column number option */ | |
#define INDENT_OPT 'I' /* indent option */ | |
#define HEAD_OPT 'H' /* header option */ | |
#define FOOT_OPT 'F' /* footer option */ | |
#define OUT_OPT 'O' /* output file option */ | |
#define SINGLE_OPT 'S' /* single sheet option */ | |
#define UNKNOWN_OPT'?' /* getopt returns this if it cant find the option */ | |
#define FF_OPT 'E' /* output an extra formfeed at the end */ | |
#define READ "rt" /* for fopen () */ | |
#define WRITE "wt" /* for fopen () */ | |
#define TRUE 1 | |
#define FALSE 0 | |
#define NOERR 1 | |
#define ERROR -1 /* error to return on exit */ | |
#define OUTFILEERR -2 | |
#define INFILEERR -3 | |
#define CMNDERR -4 | |
#define OPTERR -5 | |
#define VERSION "1.53" | |
/* -------- DATA DEFINITONS ---------- */ | |
long NumLines, | |
PageLen, | |
NumCols, | |
NumIndent; | |
char header [81], | |
footer [81]; | |
short wideflg = FALSE, | |
formflg = FALSE, | |
singleflg = FALSE; | |
/* -------- FUNCTION PROTOTYPES --------- */ | |
void sp_abort (short); | |
void sp_io (FILE *, FILE *); | |
/*==========================================================================*/ | |
/* main */ | |
/* */ | |
/* */ | |
/*--------------------------------------------------------------------------*/ | |
main (int argc, char *argv[]) | |
{ char option; /* command line option */ | |
char *infile, | |
*outfile, | |
*cur; | |
FILE *fopen (), *in_f, *out_f; | |
extern int getopt (int argc, char *argv[], char *optionS); | |
extern int optind, /* the argv index of the next argument */ | |
opterr; /* set this to zero so that getopt dont print its own error */ | |
extern char *optarg; /* points to the option argument */ | |
struct stat f_info; /* structure for stat */ | |
long secs_now; | |
NumLines = DEFLINES; | |
PageLen = DEFPAGE; | |
NumCols = DEFCOL; | |
NumIndent = DEFINDENT; | |
outfile = NULL; | |
opterr = 0; | |
out_f = stdout; | |
textcolor (YELLOW); | |
/* clrscr ();*/ | |
cprintf ("\r SPIT V%s", VERSION); | |
cprintf (" -file printer and formatter- "); | |
cprintf ("(c)1987,88 KindelCo Software Systems\r\n\r\n"); | |
if (argc == 1) /* if there is nothing on the command line then print docs */ | |
sp_abort (NOERR); | |
textcolor (LIGHTMAGENTA); | |
while ((option = getopt (argc, argv, OPTSTRING)) != EOF) | |
switch (toupper (option)) | |
{ case LINE_OPT : NumLines = strtol (optarg, NULL, 0); /* strtol converts a string to a long int. */ | |
cprintf (" spit: Option not implemented yet: /%c.\r\n", option); | |
sp_abort (CMNDERR); | |
break; | |
case PAGE_OPT : PageLen = strtol (optarg, NULL, 0); | |
cprintf (" spit: Option not implemented yet: /%c.\r\n", option); | |
sp_abort (CMNDERR); | |
PageLen = strtol (optarg, NULL, 0); | |
break; | |
case WIDE_OPT : if (NumIndent == DEFINDENT) | |
NumIndent = 8; | |
NumCols = 132; | |
wideflg = TRUE; | |
break; | |
case OUT_OPT : outfile = malloc (strlen (optarg)); | |
outfile = optarg; | |
break; | |
case INDENT_OPT : NumIndent = strtol (optarg, NULL, 0); | |
break; | |
case UNKNOWN_OPT : cprintf (" spit: unknown command line option.\r\n"); | |
sp_abort (CMNDERR); | |
break; | |
case FF_OPT : formflg = TRUE; | |
break; | |
case SINGLE_OPT : singleflg = TRUE; | |
break; | |
default : cprintf (" spit: Option not implemented yet: /%c.\r\n", option); | |
sp_abort (CMNDERR); | |
break; | |
} | |
if (NumLines >= (PageLen - 8)) | |
{ cprintf (" spit: The number of lines must not exceed the page length - 8.\r\n"); | |
sp_abort (OPTERR); | |
} | |
while (optind < argc) | |
{ infile = (char*) malloc (strlen (argv[optind])+2); | |
strcpy (infile, argv [optind++]); | |
if ((in_f = fopen (infile, READ)) == NULL) | |
{ cprintf (" spit: can't open input file "); | |
textcolor (WHITE); | |
cprintf ("%s\r\n", infile); | |
textcolor (LIGHTMAGENTA); | |
sp_abort (INFILEERR); | |
} | |
if (outfile == NULL) | |
{ outfile = malloc (4); | |
strcpy (outfile, DEFOUT); | |
} | |
if ((out_f = fopen (outfile, WRITE)) == NULL) | |
{ cprintf (" spit: can't open output file "); | |
textcolor (WHITE); | |
cprintf ("%s\r\n", outfile); | |
textcolor (LIGHTMAGENTA); | |
sp_abort (OUTFILEERR); | |
} | |
cprintf ("Printing "); | |
textcolor (WHITE); | |
cprintf ("%s ", infile); | |
textcolor (LIGHTMAGENTA); | |
cprintf ("..."); | |
if (strlen (infile) > 19) | |
{ strcpy (header, infile); | |
cur = header; | |
while (strlen (cur) > 16) | |
*(cur++) = '.'; | |
cur -= 3; | |
strcpy (header, cur); | |
strcat (header, " "); | |
} | |
else | |
{ strcpy (header, infile); | |
while (strlen (header) < 20) | |
strcat (header, " "); | |
} | |
strcat (header, "- Revised "); | |
stat (infile, &f_info); /* get file date */ | |
strcat (header, ctime (&f_info.st_mtime)); | |
*strchr (header, '\n') = NULL; | |
strcat (header, " -"); | |
while (strlen (header) < 69) | |
strcat (header, " "); | |
strcat (header, "Page "); | |
strcpy (footer, " - Printed on \0"); | |
time (&secs_now); /* get time in seconds */ | |
strcat (footer, ctime (&secs_now)); /* make it into a string */ | |
*(strchr (footer, '\n')) = NULL; | |
strcat (footer, " -"); | |
sp_io (in_f, out_f); | |
if (fclose (in_f)) | |
cprintf ("Error closing input file."); | |
if (fclose (out_f)) | |
cprintf ("Error closing output file."); | |
cprintf ("\r\n"); | |
free (infile); | |
} | |
cprintf ("\r\n"); | |
return; | |
} | |
/*==========================================================================*/ | |
/* sp_io */ | |
/* */ | |
/*--------------------------------------------------------------------------*/ | |
void sp_io (FILE *input_f, FILE *output_f) | |
{ char line [150]; | |
short LineCount = 0, PageCount = 0, i = 0; | |
if (singleflg) | |
{ cprintf ("\r\nInsert paper and press any key..."); | |
(void) getch (); | |
cprintf ("%c %c", CR,CR); | |
} | |
fprintf (output_f, "%c%c%c", ESC, INIT, COMPOFF); | |
if (wideflg != 0) fprintf (output_f, "%c%c", ESC, COMPON); | |
fprintf (output_f, "\n%c%c", ESC, BOLDON); | |
fprintf (output_f, " %s %d", header, ++PageCount); | |
fprintf (output_f, "%c%c\n\n\n", ESC, BOLDOFF); | |
while (fgets (line, (NumCols - NumIndent), input_f) != NULL) | |
{ | |
if (LineCount == NumLines) | |
{ LineCount = 0; | |
fprintf (output_f, "\n\n\n"); | |
fprintf (output_f, "%c%c%s%c", ESC, BOLDON, footer, FF); | |
if (singleflg) | |
{ cprintf ("Insert paper and press any key..."); | |
(void) getch (); | |
cprintf ("%c %c", CR,CR); | |
} | |
fprintf (output_f, "\n %s %d", header, ++PageCount); | |
fprintf (output_f, "%c%c\n\n\n", ESC, BOLDOFF); | |
} | |
if (NumIndent > 0) | |
for (i = 1; i < NumIndent; i++) | |
fprintf (output_f, " "); | |
i = 0; | |
while ((line[i] != '\n') && (line[i] != NULL) && (i <= (NumCols - NumIndent))) | |
{ if (line[i] == FF) | |
{ for (; LineCount < NumLines; LineCount++) | |
fprintf (output_f, "\n"); | |
fprintf (output_f, "%c%c", ESC, BOLDON); | |
fprintf (output_f, "\n\n\n%s%c", footer, FF); | |
if (singleflg) | |
{ cprintf ("Insert paper and press any key..."); | |
(void) getch (); | |
cprintf ("%c %c", CR,CR); | |
} | |
fprintf (output_f, "\n %s %d", header, ++PageCount); | |
fprintf (output_f, "%c%c\n\n\n", ESC, BOLDOFF); | |
LineCount = 0; | |
} | |
else | |
fputc (line[i], output_f); | |
i++; | |
} | |
fputc ('\n', output_f); | |
LineCount++; | |
} | |
for (; LineCount < NumLines; ++LineCount) | |
fprintf (output_f, "\n"); | |
fprintf (output_f, "%c%c", ESC, BOLDON); | |
fprintf (output_f, "\n\n\n%s%c%c", footer, ESC, BOLDOFF); | |
fprintf (output_f, "%c", FF); | |
fprintf (output_f, "%c",COMPOFF); | |
if (formflg != 0) | |
fprintf (output_f, "%c", FF); | |
return; | |
} | |
/*==========================================================================*/ | |
/* Abort */ | |
/*==========================================================================*/ | |
void sp_abort (short errcode) | |
{ char *help; | |
help= " Usage - spit [options] <filename.ext>\r\n" | |
" Options:\r\n" | |
" /Pn : Where n is the page length in lines. Default is 66 lines.\r\n\r\n" | |
" /Ln : Where n is the number of lines to be printed per page. \r\n" | |
" Default is 58 lines.\r\n\r\n" | |
" /W : Sets compressed mode on IBM/EPSON dot matrix printers. Sets the\r\n" | |
" number of columns to 132 and indents 8 characters. Both\r\n" | |
" the columns and indentation can be altered with /cn and /in.\r\n\r\n" | |
" /Cn : where n is the number of columns. Default is 80 columns.\r\n\r\n" | |
" /In : where n is the number of columns to indent from the left margin.\r\n\r\n" | |
" /S : Single sheet option. Pauses before printing each page.\r\n\r\n" | |
" /O<fil> : Where <fil> is an output filename. Default is the standard\r\n" | |
" print device (PRN).\r\n"; | |
textcolor (LIGHTRED); | |
if (errcode != NOERR) | |
cprintf ("\r\n"); | |
cprintf ("%s",help); | |
exit (errcode); | |
} | |
/*==========================================================================*/ | |
/* End of spit - (c) KindelCo 1987 */ | |
/*==========================================================================*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment