Windows-Server-2003/sdktools/ppr/ppr.c

966 lines
35 KiB
C

/* lpr.c - fancy paginator for laserprinters
*
* Author: Mark Taylor
*
* Modifications:
*
* 12/85 Mark Zbikowski rewrite to work cleaner
* 4/3/86 MZ Single print jobs will advance page
* 4/3/86 MZ use tools.ini for default printer setup
* 4/20/86 Mike Hanson add banner, etc (add features to make like
* lpr from PS, extensively reorganized, etc)
* 6/6/86 Jay Sipelstein added S and L options to printer desc.
* Trim trailing blanks and blank lines.
* Set mode before raw printing.
* 7/8/86 Byron Bishop Add -q to cause print queue to be printed.
* Fixed bug so -# and -e flags take priority
* over default settings. Runs of blanks
* replaced by escape sequences to reduce
* file size.
* 8/31/86 Craig Wittenberg Added support for PostScript. Used the VMI
* on the LaserJet instead of line/inch to get 62
* lines on one page (two for header). Cleaned
* up iLine (now rowLine) and indentation.
* 10/10/86 John Rae-Grant Added -g flag to allow gutter in portrait mode.
* $USER can now be a list of directories to
* search for tools.ini in. Default printer can
* be specified in tools.ini file. Modified
* landscape mode page numbering to avoid three
* hole punch obliteration.
* 1/27/87 Craig Wittenberg Cleaned up whole program; no change in
* functionality.
* 1/28/87 Thom Landsberger Added CB and CZ (=default) flags to the LJ
* printer description to support the 'Z' font
* cartridge in landscape mode
* 3/23/87 Thom Landsberger Port to Xenix 286 and 68k; environment
* setting of parameters accepted as default
* and with higher priority than tools.ini/.pprrc;
* implemented -m, -M, -c command switches;
* restructured command interpretation.
* 4/10/87 Craig Wittenberg interrupt signal ignored if that is the
* status when ppr is started
* 4/14/87 Thom Landsberger only pure digit strings accepted as
* numeric command line arguments
* 6/05/87 Thom Landsberger double sided printing on HP LJ 2000;
* '/' no switch character on Xenix;
* 'ppr -q -' now does print from stdin.
* 7/5/87 Craig Wittenberg changed fDuplex? names to f?Duplex so they
* compile in 68k Xenix. Invoked ftp with command
* line arguments rather than printing the commands
* to stdin. -t now removes label (used to require
* -m "").
*
* Ppr reads /etc/default/ppr if there is not
* $HOME/.pprrc. Duplex printing now does not
* print on the back of the banner page (even if
* not raw). Added -s flag: disables messages
* which indicate ppr's progress. Changed the PS
* setup to avoid VMErrors. Allowed the default
* printer in the tools.ini/.pprrc file to have
* options (e.g. default=lpt1, LJ L). Changed the
* default printer on Xenix from net9 to net.
*
* ~8/1/87 Ralph Ryan Ported to OS/2 LanManager
*
* 11/24/87 Craig Wittenberg Rearranged sources - mostly to isloate the OS
* specific network routines in lplow.c
* Ppr now uses clem as the transfer machine for
* DOS print jobs when /usr/eu/bin/ppr is not
* present (indicating a machine in another
* division).
*
* 12/2/87 Alan Bauer Version 2.5
* Final porting to OS/2 LAN Manager. Mainly
* polished up network routines to work properly
* Released to OS/2 people, DOSENV, NEWENV, and
* new 68K version.
*
* 3/17/88 Alan Bauer Version 2.6
* Fixed so that the username is still printed in
* lower left corner of the file listing when the
* "no banner" option is specified (ppr -b0).
* Ppr -? now prints to stdout rather than stderr.
* Now supports ppr -q for OS/2.
*
* 4/04/88 Alan Bauer Version 2.7
* Added -c<n> option to print <n> copies of the
* specified files.
* Seperates large print jobs into roughly 100K
* amounts.
* Better feed back on PRINTING progress.
* Fixed so that an empty password is now passed to
* mkalias correctly (Xenix 386 version).
* Now map ppr -p "xenix name" to
* "mkalias name name printing [password]".
* Errors opening input files no longer abort; just
* go on to the next file.
*
* 4/05/88 Alan Bauer Version 2.71
* Fixed problem with last file to be printed
* putting the current print job over 100K,
* therefore causing new print job to be performed
* (with no more files to be printed).
*
* 4/13/88 Alan Bauer Version 2.8
* Added ability to specify options in TOOLS.INI
* file.
*
* 5/19/88 Alan Bauer Version 2.81
* Fixed General Protection Fault in OS/2 dealing
* with login usernames which are more than 12
* characters long.
*
* 6/20/88 Alan Bauer Version 2.82
* Fixed LANMAN error message handling problems
* and a bug where ppr failed if redirection to
* the same printer as established in the environ-
* ment variable was already set up.
*
* 3/3/89 Robert Hess Version 2.9
* Completely changed PostScript support.
* Added 'PC' (Portrait Condensed) and 'PSF'
* (PostScriptFile) printer specific switches.
*
* 3/22/89 Robert Hess Version 2.10
* Modifications to how 'FormFeed' was handled
* for PostScript usage.
*
* 7/12/89 Robert Hess Version 2.11
* Fixed a bug that prevented lengthy Postscript
* files to be printed.
*
* 9/14/89 Robert Hess Version 2.12
* Fixed -M option in PostScript code.
* Fixed the 'opts=<option>' parsing from
* TOOLS.INI (wasn't allowing leading spaces)
*
* 10/6/89 Robert Hess Version 2.12b
* Minor fix, repaired linking to include
* SetArgV.OBJ (to automatically expand
* wildcards in filenames - ooops!), and
* added error handling to the '-q' command.
*
* 10/20/89 Robert Hess Version 2.13
* Date and time of *FILE* is now printed at
* the bottom of the page for PostScript.
* (...ooops...)
*
* 12/06/89 Robert Hess Version 2.14
* Added switches -v (verify, for debugging),
* and -w (column width).
*
* 4/9/90 Scott Means Version 2.15
* Support of non-printable IBM characters and
* added progress indicator.
*
* 4/18/90 Robert Hess Version 2.2
* Re-Wrote postscript header code to allow
* full sensing of actual printer area, and
* corrected several bugs in old header.
* Fixed 'pathname' for network drives
* Fixed '-t' switch for Postscript mode
* Added 'psuedo' printer name support.
*
* 6/15/90 Robert Hess Version 2.3
* Added better implementation of 'extended
* ascii' mode. Added more debugging code
* for network usage. Added R and C printer
* switches to better support odd sized paper.
* Improved 'usage' text.
* Switched to using some TOOLSVR api calls.
* General cleanup and bug fixes.
* Enlisted into \\ToolSvr\Build project.
*
* 7/26/90 Robert Hess Version 2.3a
* Fixed a couple bugs. Added '-l' option for
* listing out contents of TOOLS.INI. Final
* cleanup prior to general release.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <process.h>
#include <signal.h>
#include <ctype.h>
#include <windows.h>
#include <tools.h>
#include "lpr.h"
/* 175 columns:
* 0 1 174
* single page: <bar> 173 columns of text <bar>
* 0 1 86 87 88 173 174
* double page: <bar> 86 columns of text <bar> 86 columns of text <bar>
*/
long lcbOutLPR = 0l; // total amount printed in this job
int cCol = 0; // number of columns being displayed
int cColCom = 0; /* number of columns as specified in
command line. */
int colTabCom = 0; /* number of spaces per tab specified
in command line. Number of spaces
per tab, colTab, is declared in
lpfile.c */
int colGutter = 0; // number of spaces in gutter
int colText = 0; // column where text starts
int cCopies = 1; // number of copies to print
int colWidth; // printable spaces in each column
int defWidth = 0; // <- NEW... to override colWidth calculation
int colMac = colLJMax; // maximum columns on a page
int rowMac = rowLJMax; // maximum rows on a page
int rowPage; /* number of printable lines per page
including header on top */
char *aszSymSet[] = { // supported Laserjet symbol sets
"\033&l1o5.8C\033(0U\033(s0p16.67h8.5v0T",
"\033&l1o5.8C\033(8U\033(s0p16.67h8.5v0T",
"\033&l1o5.8C\033(10U\033(s0p16.67h8.5v0T"
};
BOOL fNumber = FALSE; // TRUE => show line numbers
BOOL fDelete = FALSE; // TRUE => delete file after printing
BOOL fRaw = FALSE; // TRUE => print in raw mode
BOOL fBorder = TRUE; // TRUE => print borders
BOOL fLabel = TRUE; // TRUE => print page heading
BOOL fLaser = TRUE; // TRUE => print on an HP LaserJet
BOOL fPostScript = FALSE; // TRUE => print on postscript printer
BOOL fPSF = FALSE; // TRUE => Use alternate PS Header
char szPSF[MAX_PATH] = ""; // pathname of alternate PS Header
BOOL fPCondensed = FALSE; // TRUE => Condensed portrait mode PS
BOOL fConfidential = FALSE; // TRUE => stamp pages and banner
BOOL fVDuplex = FALSE; // TRUE => double sided, vertical bind
BOOL fHDuplex = FALSE; // TRUE => ditto, but horizontal bind
BOOL fSilent = FALSE; // TRUE => no messages
int cBanner = -1; // # of banners; <0 only 1 group
char chBanner = ' '; // used to form banner characters
char *szBanner = NULL; // banner string, use fname if NULL
char *szStamp = NULL; // additional label put on each page
BOOL fForceFF = TRUE; // TRUE => end at top of page
BOOL fPortrait = FALSE; // TRUE => print in portrait mode
BOOL fQueue = FALSE; // TRUE => list print queue
USHORT usSymSet = 0; // symbol set to use on Laserjet
// FALSE => select Roman-8 symbol set
USHORT usCodePage = 0; // 0 = convert extended ascii to '.'
BOOL fVerify = FALSE; // TRUE => dump out data on what we are doing
BOOL fList = FALSE; // TRUE => use with fVerify to prevent printing
char szPass[cchArgMax] = "";
static void Usage(void);
static void DoArgs(int *, char **[]);
void Abort(void);
void DoIniOptions(void);
int __cdecl main(argc, argv)
int argc;
char **argv;
{
intptr_t err;
int iCopies;
#ifdef notdefined
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
// if not ignored upon startup, set our abort handler
signal(SIGINT, (void (_cdecl *)(int))Abort);
#endif
// hack to get verify and list to work *before* command line is parsed
ConvertAppToOem( argc, argv );
if( argc > 1 ) {
if (argv[1][1] == 'v') {
fVerify = TRUE;
}
if (argv[1][1] == 'l') {
fList = TRUE;
}
if (fVerify) {
fprintf (stdout, "\n");
}
}
DoIniOptions();
if (fVerify) {
fprintf (stdout, "Seen on Command Line:\n");
}
DoArgs(&argc, &argv);
SetupPrinter();
SetupRedir();
// -------------- modifications to switches and precalculated values
// don't allow guttering in landscape mode
if (!fPortrait)
colGutter = 0;
// set global for start of text
colText = colGutter + (fNumber ? cchLNMax : 0);
// set # columns if set in command line.
if (cColCom)
cCol = cColCom;
else if (cCol == 0)
cCol = fPortrait ? 1 : 2;
// set # of spaces per tab if set in command line.
if (colTabCom)
colTab = colTabCom;
colWidth = colMac;
if (fPostScript && fPCondensed) {
colWidth = colMac *= 2;
}
if (defWidth > 0) colWidth = defWidth;
if (fLaser && usCodePage == 850) {
usSymSet = BEGINLANDIBMPC; // for the LaserJet
}
if (cCol != 1) {
// more than one column: divide into separate columns with divider
colWidth = (colMac-1) / cCol - 1;
if (defWidth > 0) colWidth = defWidth;
colMac = (colWidth + 1) * cCol + 1;
}
// rowPage includes border line(s) at top of page
rowPage = rowMac;
if (fBorder || fLabel) {
if (!fLaser && !fPostScript && fPortrait) {
// same bottom margin as old Xenix ppr
rowPage -= 5;
} else {
// don't print on bottom line
rowPage -= 1;
}
}
if (!fLaser && !fPostScript && cBanner == -1) {
// line printer for which the default banner setup is required
cBanner = -2;
}
// ----------------- end modification of switches
if (fVerify) fprintf (stdout, "\n"); // just to clean things up a little
fprintf(stdout, "PPR version: "VERSION"\n");
fprintf(stdout, "----------------------------------------------------------------------------\n");
if (argc == 0) {
/* No file names were listed... assume user wants <stdin> */
if (!fQueue && !fList) {
// print stdin
fprintf (stdout, "Printing from: <stdin> Press <Ctrl-Z> to end.\n");
MyOpenPrinter();
FileOut("");
MyClosePrinter();
}
} else {
// print file(s)
MyOpenPrinter();
while (argc) {
// print more copies if wanted
for(iCopies = 1; iCopies <= cCopies; iCopies++) {
FileOut(*argv);
// end this print job if more than 100K has been printed
// thus far. Then start next print job.
if (lcbOutLPR > 100000 && argc != 1) {
lcbOutLPR = 0l;
MyClosePrinter();
fFirstFile = TRUE;
MyOpenPrinter(); // ready to start next job
}
}
argc--;
argv++;
}
MyClosePrinter();
}
/* if user wants to print queue, spawn a process to do the printing.
The process will inherit the current environment including the
redirection of szPName.
*/
if (fQueue) {
fprintf (stdout, "[Net Print %s]:\n", szNet);
err = _spawnlp(P_WAIT,"net","net","print",szNet,NULL);
if (err)
if (err == -1)
fprintf (stdout, "- Error : Unable to Spawn Queue Status Request -\n");
else
fprintf (stdout, "- Error Returned from Queue Status Request: %d - \n", err);
}
ResetRedir();
return 0;
} /* main */
void Abort()
/* SIGINT handler to abort printing gracefully
*
* Warning: Never returns (exits via Fatal).
*/
{
Fatal("terminated by user", NULL);
} /* Abort */
static void Usage()
{
fprintf(stdout, "PPR version: "VERSION" by: "ANALYST"\n");
fprintf(stdout, "Usage: ppr [-switches] files(s)\n");
fprintf(stdout, "-<digit> :Print in columns (1-9) -n : Print line numbers\n");
fprintf(stdout, "-b <n> :Print <n> banners -o <n> : Offset <n> for gutter\n");
fprintf(stdout, "-c <n> :Print <n> copies -q : List print queue status\n");
fprintf(stdout, "-D :Delete file after print -s : Supress progress message\n");
fprintf(stdout, "-e <n> :Expand tabs to <n> -t : Supress page headers\n");
fprintf(stdout, "-f :NO formfeed at end -r : Print in raw mode\n");
fprintf(stdout, "-h <string>:Use <string> for header -v : Verbose (for debugging)\n");
fprintf(stdout, "-m <string>:Stamp <string> on page -w <n> : Page width in characters\n");
fprintf(stdout, "-M :\"Microsoft Confidential\" -p <string>: Printer description\n");
fprintf(stdout, "\n");
fprintf(stdout, "Printer Description: ppr -p \"<port>,<type> <options>,<columns>,<tabstops>\"\n");
fprintf(stdout, "Types & Options:\n");
fprintf(stdout, "LP : Line Printer DV : Duplex printing vert.\n");
fprintf(stdout, "LJ : HPLaserJet DH : Duplex printing horz.\n");
fprintf(stdout, "PS : PostScript F : No force form feed\n");
fprintf(stdout, "PSF <file>: PostScript w/header L : Landscape\n");
fprintf(stdout, "CZ : 'Z' Cartridge P : Portrait\n");
fprintf(stdout, "CB : 'B' Cartridge PC : Portrait Condensed\n");
fprintf(stdout, "CP <n> : Set CodePage S : Force form feed\n");
fprintf(stdout, "EA : Set CodePage to 850 # : Number of rows\n");
fprintf(stdout, "See PPR.HLP for further information and usage descriptions.\n");
exit(1);
}
// VARARGS
void __cdecl Fatal(char *sz, ...)
{
va_list args;
va_start(args, sz);
fprintf(stderr, "ppr: ");
vfprintf(stderr, sz, args);
fprintf(stderr, "\n");
va_end(args);
MyClosePrinter();
ResetRedir();
exit(1);
}
void __cdecl Error(char *sz, ...)
{
va_list args;
va_start(args, sz);
fprintf(stderr, "ppr: ");
vfprintf(stderr, sz, args);
fprintf(stderr, "\n");
va_end(args);
}
char * SzGetArg(ppch, pargc, pargv)
char **ppch;
int *pargc;
char **pargv[];
// return the string following the current switch; no whitespace required
{
char *tmp;
if (*(*ppch+1))
{
(*ppch)++;
tmp = *ppch;
*ppch += strlen(*ppch) - 1;
// return(*ppch);
return( tmp );
}
else
{
(*pargv)++;
if (--*pargc)
return((*pargv)[0]);
else
return(NULL);
}
}
int WGetArg(ppch, pargc, pargv, nDefault, szXpl)
// return the number following the current switch; no whitespace required
char **ppch;
int *pargc;
char **pargv[];
int nDefault;
char * szXpl;
{
int nRet;
char chSwitch;
chSwitch = **ppch;
if (*(*ppch+1))
{
nRet = atoi(++*ppch);
*ppch += strlen(*ppch) - 1;
}
else
{
if ((*pargc>1) &&
strlen((*pargv)[1]) == strspn((*pargv)[1], "0123456789") )
{
(*pargc)--;
nRet = atoi((++*pargv)[0]);
}
else
nRet = nDefault;
}
if (nRet<0)
{
Fatal("negative %s (switch %c)", szXpl, chSwitch);
return 0;
}
else
return(nRet);
}
void DoIniOptions() // Get any options from the TOOLS.INI file (OPTS=...)
{
#define cargsMax 25
FILE *pfile;
char *szT;
char rgbSW[cchArgMax];
int argc;
char *pchSp;
char *argvT[cargsMax]; // structure to build to be like argv
char **pargvT = argvT;
// if ((pfile = swopen()) != NULL) {
if ((pfile = swopen("$INIT:Tools.INI", "ppr")) != NULL) {
/* 'PPR' tag was found in 'TOOLS.INI' */
if (fVerify || fList) {
fprintf (stdout, "TOOLS.INI contains the following entries:\n");
fprintf (stdout, "[ppr]\n");
}
while (swread(rgbSW, cchArgMax, pfile) != 0) {
/* a 'switch line' was found in the file */
szT = rgbSW + strspn(rgbSW, " \t"); // skip spaces and tabs
if (fVerify || fList) {
fprintf (stdout, " %s \n", szT);
}
// an entry "opts=<options>" will cause the options
// to be set from the parameter file.
if (_strnicmp(szT, OPTS, strlen(OPTS)) == 0) {
if ((szT = strchr(szT, '=')) != NULL) {
szT++; // advance past '='
while (szT[0] == ' ') szT++; // advance past beginning spaces
if(*szT) {
argvT[0] = 0;
for (argc = 1; argc < cargsMax && szT[0] != '\0'; argc++)
{
argvT[argc] = szT;
pchSp = strchr(szT, ' ');
if (pchSp == '\0')
break;
*pchSp = 0;
szT = pchSp + 1;
while (szT[0] == ' ') {
szT++;
}
}
argc++;
argvT[argc] = '\0';
DoArgs(&argc, &pargvT);
}
}
}
}
swclose(pfile);
}
}
static void DoArgs(pargc, pargv) // Parse the argument string.
int * pargc;
char **pargv[];
{
int argc, vArgc; // vArgc - for verify mode
char **argv, **vArgv;
char *p;
argc = vArgc = *pargc;
argv = vArgv = *pargv;
argc--;
argv++;
p = argv[0];
while (argc && (*p == '/' || (*p=='-' && *(p+1)!='\0')))
{
while (*++p)
{
switch (tolower(*p))
{
case 'a':
chBanner = *++p;
break;
case 'b':
cBanner = WGetArg(&p, &argc, &argv, 1, "number of banners");
break;
case 'c':
cCopies= WGetArg(&p, &argc, &argv, 1, "number of copies");
break;
case 'd':
case 'D':
if (*p=='D') // <-- since we did a 'tolower'
fDelete = TRUE;
break;
case 'e':
colTabCom = WGetArg(&p, &argc, &argv, 8, "tabs");
break;
case 'f':
fForceFF = FALSE;
break;
case 'g':
case 'o':
colGutter = WGetArg(&p, &argc, &argv, colGutDef, "offset");
break;
case 'h':
szBanner = SzGetArg(&p, &argc, &argv);
break;
case 'l':
fList = TRUE;
break;
case 'm':
case 'M':
fBorder = TRUE;
fLabel = TRUE;
if (*p=='M') // <-- since we did a 'tolower'
fConfidential = TRUE;
else
szStamp = SzGetArg(&p, &argc, &argv);
break;
case 'n':
fNumber = TRUE;
break;
case 'p':
szPDesc = SzGetArg(&p, &argc, &argv);
break;
case 'q': // Enable print of queue
fQueue = TRUE;
break;
case 'r':
fRaw = TRUE;
break;
case 's':
fSilent = TRUE;
break;
case 't':
if (!fConfidential && szStamp==NULL)
{
fBorder = FALSE;
fLabel = FALSE;
}
break;
case 'v':
fVerify = TRUE;
break;
case 'w':
defWidth = WGetArg(&p, &argc, &argv, 80, "Width of column");
break;
case 'x':
usCodePage = 850;
break;
case '1': case '2':
case '3': case '4':
case '5': case '6':
case '7': case '8':
case '9':
cColCom = *p - '0';
break;
default :
Error("invalid switch: %s\n", p);
case '?':
case 'z':
Usage();
break;
}
}
argc--;
argv++;
p = argv[0];
}
if (fVerify) {
vArgv++; // skip over program name, or null entry
while (--vArgc) fprintf (stdout, "%s ", *(vArgv++));
fprintf (stdout, "\n\n");
}
*pargv = argv;
*pargc = argc;
}
void DoOptSz(szOpt)
/* scan and handle printer options
*
* Entry: szOpt - string containing printer options
*
* Exit: global flags set according to printer options
*
* An option string has the format:
* [, [(LJ [P] [L] [CB|CZ] [D|DV|DH]) | (LP [# lines]) | (PS [P] [L])] [F] [S] [, [tabstop] [, [# columns]]]]
*
* Note: Although this is called by the lpprint module,
* It is here because it deals with command line arguments
* and setting the global print control flags.
*/
register char * szOpt;
{
char szBuf[cchArgMax];
BOOL fLJ = FALSE;
BOOL fLP = FALSE;
BOOL fPS = FALSE;
if (*szOpt++ == ',')
{
while (*szOpt != ',' && *szOpt)
{
szOpt = SzGetSzSz(szOpt, szBuf);
/* First the different printer types*/
// Laser Jet
if (_strcmpi(szBuf, "lj") == 0 && !fLP && !fPS)
{
fLJ = TRUE;
fLaser = TRUE;
fPostScript = FALSE;
// don't set border here so -t works
fPortrait = FALSE;
colMac = colLJMax;
rowMac = rowLJMax;
}
// Line Printer
else if (_strcmpi(szBuf, "lp") == 0 && !fLJ && !fPS)
{
fLP = TRUE;
fLaser = FALSE;
fPostScript = FALSE;
fBorder = FALSE;
fPortrait = TRUE;
colMac = colLPMax;
rowMac = rowLPMax;
}
// PostScript with custom header
else if (_strcmpi(szBuf, "psf") == 0 && !fLP && !fLJ)
{
fPS = TRUE;
fLaser = FALSE;
fPostScript = TRUE;
fPortrait = FALSE;
fPCondensed = FALSE;
colMac = colPSMax;
rowMac = rowPSMax;
fPSF = TRUE;
szOpt = SzGetSzSz(szOpt, szPSF);
}
// PostScript
else if (_strcmpi(szBuf, "ps") == 0 && !fLP && !fLJ)
{
fPS = TRUE;
fLaser = FALSE;
fPostScript = TRUE;
// don't set border here so -t works
fPortrait = FALSE;
fPCondensed = FALSE;
colMac = colPSMax;
rowMac = rowPSMax;
}
/* Now the modifiers */
// Column width to print in
else if (_strcmpi(szBuf, "c") == 0) {
szOpt = SzGetSzSz(szOpt, szBuf);
if (atoi(szBuf) != 0) {
defWidth = atoi(szBuf);
} else {
Fatal ("Non-Numeric Columns specified.");
}
}
// LaserJet with the 'B' cartridge
else if (_strcmpi(szBuf, "cb") == 0 && fLJ)
usSymSet = BEGINLANDROMAN8;
// LaserJet emulation of 'IBM' text
else if (_strcmpi(szBuf, "ci") == 0 && fLJ) {
usSymSet = BEGINLANDIBMPC; // for the LaserJet
usCodePage = 850;
}
// Code Page specification
else if (_strcmpi(szBuf, "cp") == 0) {
szOpt = SzGetSzSz(szOpt, szBuf);
if (atoi(szBuf) != 0) {
usCodePage = (USHORT)atoi(szBuf);
} else {
Fatal ("Non-Numeric CodePage specified.");
}
}
// LaserJet with the 'Z' cartridge
else if (_strcmpi(szBuf, "cz") == 0 && fLJ)
usSymSet = BEGINLANDUSASCII;
// Prep for double sided printing, binding on long edge
else if ((_strcmpi(szBuf, "d") == 0 || _strcmpi(szBuf, "dv") == 0))
fVDuplex = TRUE;
// Prep for double sided printing, binding on short edge
else if (_strcmpi(szBuf, "dh") == 0)
fHDuplex = TRUE;
// Extended Ascii printing - shortcut to CP 850
else if (_strcmpi(szBuf, "ea") == 0) {
usCodePage = 850;
}
// Turn off forced form feed
else if (_strcmpi(szBuf, "f") == 0)
fForceFF = FALSE;
// Landscape
else if (_strcmpi(szBuf, "l") == 0 && (fLJ || fPS))
{
fPortrait = FALSE;
colMac = fLJ ? colLJMax : colPSMax;
}
// Portrait
else if (_strcmpi(szBuf, "p") == 0 && (fLJ || fPS))
{
fPortrait = TRUE;
fBorder = FALSE;
colMac = fLJ ? colLJPortMax : colPSPortMax;
}
// Portrait Condensed
else if (_strcmpi(szBuf, "pc") == 0 && (fLJ || fPS))
{
fPortrait = TRUE;
fPCondensed = TRUE;
fBorder = TRUE;
colMac = fLJ ? colLJPortMax : colPSPortMax;
if (cColCom == 0) cColCom = 2;
}
// Number of rows (same as just # by itself, but more descriptive)
else if (_strcmpi(szBuf, "r") == 0) {
szOpt = SzGetSzSz(szOpt, szBuf);
if (atoi(szBuf) != 0) {
rowMac = atoi(szBuf);
if (rowMac > rowMax)
Fatal ("Too many rows (%d) specified.", rowMac);
} else {
Fatal ("Non-Numeric Rows specified.");
}
}
// Force Form Feed
else if (_strcmpi(szBuf, "s") == 0)
fForceFF = TRUE;
// Number of rows
else if (isdigit(szBuf[0]) && fLP) {
rowMac = atoi(szBuf);
if (rowMac > rowMax)
Fatal("page size %d to long", rowMac);
}
else if (_strcmpi(szBuf, "") == 0)
// empty string
;
else
Fatal("unrecognized printer type option %s", szBuf);
}
/* After the first comma - Tab stop specification */
if (*szOpt++ == ',')
{ // tabstop
szOpt = SzGetSzSz(szOpt, szBuf);
if (isdigit(szBuf[0]))
colTab = atoi(szBuf);
else if (szBuf[0] != '\0')
Fatal("tabstop %s is not a number", szBuf);
/* After the second comma - Column specification (1-9) */
if (*szOpt++ == ',')
{ // # columns (1 - 9)
szOpt = SzGetSzSz(szOpt, szBuf);
if (isdigit(szBuf[0])) // 0 means default # col
cCol = szBuf[0] - '0';
else if (szBuf[0] != '\0')
Fatal("number columns (%s) must be digit 1-9",szBuf);
}
}
}
}