/************************************************************************/ /* (C) COPYRIGHT 1986. */ /* BOARD OF TRUSTEES */ /* LELAND STANFORD JUNIOR UNIVERSITY */ /* STANFORD, CA. 94305, U.S.A. */ /* */ /* Arturo Salz */ /* Computer Systems Laboratory */ /* Stanford, CA 94305 */ /* All rights reserved. */ /* */ /************************************************************************/ #include #include #include #include "defs.h" #include "types.h" #include "exports.h" #include "scansw.h" #define ALL_LEVELS 16000 /* just a ridiculously large number */ #define MAXFNAME 256 /* max. length for a filename */ #ifdef SYSVSPOOLER private char SPOOLER[] = "/bin/lp"; /* spooler-printer program */ #else private char SPOOLER[] = "/usr/bsd/lpr"; /* spooler-printer program */ #endif private char EMPTY_STR[] = ""; private char *technology = NULL; private char *outfname = NULL; private char *cifFile = NULL; private char *printer = EMPTY_STR; private char *banner = NULL; private char *usrLayers = NULL; private char *date = EMPTY_STR; private char *fontName = NULL; private char *fontSize = NULL; private char *nCopies = "1"; private char *devName = DEFLT_DEV; private float scaleFac = 0; public int maxLevel = ALL_LEVELS; public int color = FALSE; private int noHeader = FALSE; private int ask = TRUE; private int keepfile = FALSE; private int onePage = TRUE; private int amplify = FALSE; private int noRotate = FALSE; public DevDef *device; private char patternFile[ MAXFNAME ]; private char techfile[ MAXFNAME ]; private char psFile[ MAXFNAME ]; public int reloc = FALSE; /* for relocation */ extern char *GetPSfname(); main( argc, argv ) int argc; char *argv[]; { InitMem(); InitTmpFiles(); ParseArgs( argc, argv ); CheckFiles(); ReadPatterns( patternFile, usrLayers ); ParseCif( cifFile ); scaleFac = SetScale( ask, onePage, amplify, scaleFac, noRotate ); device->Init( psFile, fontSize, fontName, date, banner, outfname, scaleFac, nCopies ); FlattenChip(); device->End(); if( not keepfile ) SpoolFile(); RemoveTmpFiles(); } private SpoolFile() { char *args[ 9 ]; char **argp; int pid; pid = fork(); if( pid == -1 ) { fprintf( stderr, "can't fork printer process" ); exit( 3 ); } if( pid == 0 ) { argp = args; *argp++ = SPOOLER; #ifndef SYSVSPOOLER *argp++ = "-r"; /* delete file after printing */ #endif if( printer != EMPTY_STR ) *argp++ = printer; #ifndef SYSVSPOOLER if( noHeader ) *argp++ = "-h"; else { *argp++ = "-J"; *argp++ = banner; } #endif *argp++ = outfname; *argp = NULL; if( execv( SPOOLER, args ) == -1 ) { fprintf( stderr, "can't execute %s\n", SPOOLER ); exit( 3 ); } } } private ParseArgs( argc, argv ) { static char *pattfile = NULL; static char *psfile = NULL; static char *maxLevelStr = NULL; static char *scaleFacStr = NULL; static char *askStr = NULL; static char *headerStr = NULL; static char *rotStr = NULL; static char *lreloc = NULL; char **nextArg; char *cad, *getenv(); static SwitchTable switches[] = { { "p", 1, &pattfile, " FILE\t\tread stipple patterns from FILE" }, { "T", 1, &technology, " TECH\t\tuse technology TECH" }, { "k", 1, &outfname, " FILE\t\tkeep PostScript output in FILE (don't spool)"}, { "F", 1, &fontName, " FONT\t\tuse FONT for strings (def. Helvetica)" }, { "fp", 1, &psfile, " FILE\tuse FILE as the PostScript prologue" }, { "f", 1, &fontSize, " NUM\t\tuse a NUM size font (def. 5.0)" }, { "P", 0, &printer, "PRINTER\tsend output to PRINTER" }, { "s", 1, &scaleFacStr, " FLOAT[x]\tscale plot by FLOAT factor" }, { "d", 1, &maxLevelStr, " DEPTH\tdisplay up to DEPTH levels" }, { "b", 1, &banner, " BANNER\tuse BANNER as the plot title" }, { "h", 0, &headerStr, "\t\tdon't print the header page" }, { "I", 0, &askStr, "\t\tdon't ask for confirmation, always print" }, { "l", 1, &usrLayers, " LAYERS\tdon't display LAYERS (separated by ',')" }, { "R", 0, &rotStr, "\t\tdon't rotate to fit in page" }, { "D", 0, &date, "FORMAT\tprint date using FORMAT ([m][w][d][y][h])" }, { "V", 1, &devName, " DEV\t\tgenerate output for DEV (def. PS)" }, { "#", 1, &nCopies, " NUM\t\tprint NUM copies" }, { "r", 0, &lreloc, "\t\tgenerate relocatable output for text formatter" }, { NULL, 0, NULL, NULL } }; if( (cad = getenv( "CADDIR" )) == NULL ) cad = CADDIR; nextArg = scansw( argc, argv, switches, "[options] cif-file" ); if( (int) nextArg == -1 ) Crash( "", 1 ); if( nextArg == NULL ) Crash( "No input filename specified\n", 1 ); cifFile = *nextArg; if( technology == NULL ) technology = TECHNOLOGY; sprintf( techfile, "%s%s", cad, technology ); if( psfile ) strcpy( psFile, psfile ); else sprintf( psFile, "%s%s", cad, PSPATHNAME ); if( pattfile ) strcpy( patternFile, pattfile ); else sprintf( patternFile, "%s/pat.%s", cad, technology ); if( maxLevelStr ) { maxLevel = atoi( maxLevelStr ); if( maxLevel < 1 ) Crash( "depth must be greater than 1\n", 1 ); } if( fontSize ) { if( atof( fontSize ) <= 0 ) Crash( "Illegal font-size (%s)\n", 1, fontSize ); } if( scaleFacStr ) { char c = '\0'; if( sscanf( scaleFacStr, "%f%c", &scaleFac, &c ) < 1 ) Crash( "Incorrect scale factor (%s)\n", 1, scaleFacStr ); if( c == 'x' ) amplify = TRUE; onePage = FALSE; } if( date != EMPTY_STR ) date = GetDate( date ); if( rotStr ) noRotate = TRUE; if( lreloc ) reloc = TRUE; if( (device = GetDevice( devName )) == NULL ) Crash( "Unknown device (%s)\n", 1, devName ); if( outfname ) keepfile = TRUE; else outfname = GetPSfname(); #ifdef SYSVSPOOLER if ( printer != EMPTY_STR ) { char *swpl = strstr(printer, "-P"); if (swpl != NULL) *(swpl + 1) = 'd'; else Crash( "Unexpected error: printer garbled in command line\n", 1); } #endif if( askStr ) ask = FALSE; if( atoi( nCopies ) < 1 ) Crash( stderr, "Illegal number of copies (%s)\n", 1, nCopies ); if( headerStr ) noHeader = TRUE; if( banner == NULL ) { register char *s; s = cifFile; while( *s ) s++; while( *s != '/' and s > cifFile ) s--; if( *s == '/' ) banner = ++s; else banner = s; } } CheckFiles() { if( not IsReadable( cifFile ) ) Crash( "can't read cif file '%s'\n", 1, cifFile ); if( not IsReadable( patternFile ) ) Crash( "can't read stipple-pattern file '%s'\n", 1, patternFile ); if( keepfile ) if( not IsWritable( outfname ) ) Crash( "can't write output file '%s'\n", 1, outfname ); } /* varargs */ Crash( fmt, exitcode, s1 ,s2, s3, s4 ) char *fmt; int exitcode; { struct rlimit lim; fprintf( stderr, fmt, s1, s2, s3, s4 ); RemoveTmpFiles(); if( outfname != NULL and Exists( outfname ) ) unlink( outfname ); (void) getrlimit( RLIMIT_DATA, &lim ); exit( exitcode ); }