1*45864Skarels /* @(#)psgrind.c 1.3 12/31/90 */
232172Sedward /*
332172Sedward * psgrind - quick hack to grind C source files directly into
432172Sedward * PostScript.
532172Sedward *
632172Sedward * John Coker
732172Sedward * University of California, Berkeley
832172Sedward *
932172Sedward * The basis for this program is the enscript utility provided
1032172Sedward * by TranScript to driver the Apple LaserWriter printer. This
1132172Sedward * code was taken and mangled without permission of any kind;
1232172Sedward * don't tell anyone. -john
1332172Sedward */
1432172Sedward
1532172Sedward #define POSTSCRIPTPRINTER "gp"
1632172Sedward
1732172Sedward #define HEADERFONT "Helvetica-Bold"
1832172Sedward #define BODYFONT "Helvetica"
1932172Sedward #define KWORDFONT "Helvetica-Bold"
2032172Sedward #define COMMENTFONT "Helvetica-Oblique"
2132172Sedward #define LITERALFONT "Courier"
2232172Sedward
2332172Sedward #ifndef PSGRINDPRO
2432172Sedward #define PSGRINDPRO "/psgrind.pro"
2532172Sedward #endif !PSGRINDPRO
2632172Sedward
2732172Sedward #ifndef PSGRINDTEMP
2832172Sedward #define PSGRINDTEMP "/GRXXXXXX"
2932172Sedward #endif !PSGRINDTEMP
3032172Sedward
3132172Sedward #define UperInch 1440
3232172Sedward #define PtsPerInch 72
3332172Sedward #define UperPt 20
3432172Sedward #define TruePageWidth (UperInch*17/2)
35*45864Skarels #define PageWidth (UperInch*(4*17-3)/8)
3632172Sedward #define PageLength (UperInch*(8*11-3)/8)
3732172Sedward #define TruePageLength (UperInch*11)
3832172Sedward
3932172Sedward #include <stdio.h>
4032172Sedward #include <ctype.h>
4132172Sedward #include <strings.h>
4232172Sedward #include <pwd.h>
4332172Sedward #include <sys/types.h>
4432172Sedward #include <sys/stat.h>
4532172Sedward #include "transcript.h"
4632172Sedward
4732172Sedward #define LPR "lpr"
4832172Sedward #define REVERSE "psrev"
4932172Sedward
5032172Sedward #define MAXBAD 20 /* number of bad chars to pass before complaint */
5132172Sedward
5232172Sedward private struct stat S;
5332172Sedward char *ctime ();
5432172Sedward char *getenv ();
5532172Sedward char *rindex ();
5632172Sedward
5732172Sedward #define FSIZEMAX 256 /* number of chars per font */
5832172Sedward
5932172Sedward /* the layout of a font information block */
6032172Sedward struct font {
6132172Sedward char name[100]; /* PostScript font name */
6232172Sedward int dsize; /* size */
6332172Sedward int Xwid[FSIZEMAX]; /* X widths for each character */
6432172Sedward };
6532172Sedward
6632172Sedward private struct font fonts[16]; /* 16 possible fonts at one time */
6732172Sedward private int nf = 0; /* number of fonts known about */
6832172Sedward
6932172Sedward private int HeaderFont = -1; /* handle for header font */
7032172Sedward private int BodyFont = -1; /* handle for body font */
7132172Sedward private int KwordFont = -1; /* handle for keyword font */
7232172Sedward private int LiteralFont = -1; /* handle for literal font */
7332172Sedward private int CommentFont = -1; /* handle for comment font */
7432172Sedward
7532172Sedward private int TabWidth = TruePageWidth / 10; /* width of a tab */
7632172Sedward private int BSWidth; /* width of a backspace */
7732172Sedward
7832172Sedward private int UperLine = UperInch / 7;
7932172Sedward private int UperHLine = UperInch / 7;
8032172Sedward
8132172Sedward private char *prog; /* program name argv[0] */
8232172Sedward private char TempName[100]; /* name of temporary PostScript file */
8332172Sedward private char OutName[256] = 0; /* filename for disk output */
8432172Sedward private int PipeOut = 0; /* true if output to stdout (-p -) */
8532172Sedward private int ListOmitted = 0; /* list omitted chars on the tty */
8632172Sedward private int LPTsimulate = 0; /* true if an lpt should be simulated */
8732172Sedward private int LinesLeft = 64; /* lines left on page when in LPT mode */
88*45864Skarels private int col; /* column number on current line */
8932172Sedward private int LineNo; /* line number in current file */
9032172Sedward private int SeenText = 1; /* true if seen some text on this page */
9132172Sedward private int OutOnly = 0; /* true if PS file only wanted */
9232172Sedward private int Rotated = 0; /* true if the page is to be rotated */
9332172Sedward private int Reverse = 0; /* output should be piped to psrev */
9432172Sedward private char *PageSpec = 0; /* ditto */
9532172Sedward private int PreFeed = 0; /* true if prefeed should be enabled */
9632172Sedward private int TwoColumn = 0; /* true of if in two-column mode */
9732172Sedward private int FirstCol = 1; /* true if we're printing column 1 */
9832172Sedward private int NoTitle = 0; /* true if title line is to be suppressed */
9932172Sedward private int Cvted = 0; /* true if converted a file to PS format */
10032172Sedward
10132172Sedward private int IgnoreGarbage = 0; /* true if garbage should be ignored */
10232172Sedward private int SeenFile = 0; /* true if a file has been processed */
10332172Sedward private int SeenFont = 0; /* true if we've seen a font request */
10432172Sedward private int ScannedFonts = 0; /* true if we've scanned the font file */
10532172Sedward private char *FileName = 0; /* name of file currently being PSed */
10632172Sedward private char *FileDate = 0; /* last mod date of file being PSed */
10732172Sedward private char DateStr[27]; /* thanks, but no thanks ctime! */
10832172Sedward
10932172Sedward private char *spoolJobClass = 0;
11032172Sedward private char *spoolJobName = 0;
11132172Sedward private char *PrinterName = 0;
11232172Sedward private int spoolNotify = 0;
11332172Sedward private int spoolNoBurst = 0;
11432172Sedward private int spoolCopies = 1;
11532172Sedward
11632172Sedward private char tempstr[256]; /* various path names */
11732172Sedward
11832172Sedward private int CurFont; /* current Font */
11932172Sedward private int LastFont; /* previous Font */
12032172Sedward
12132172Sedward private int cX, cY; /* current page positions */
12232172Sedward private int dX, dY; /* desired page positions */
12332172Sedward private int lX, lY; /* page positions of the start of the line */
12432172Sedward private int crX, crY; /* X and Y increments to apply to CR's */
12532172Sedward
12632172Sedward #define None 0
12732172Sedward #define RelX 1
12832172Sedward #define RelY 2
12932172Sedward #define RelXY 3
13032172Sedward #define AbsX 4
13132172Sedward #define AbsY 8
13232172Sedward #define AbsXY 12
13332172Sedward
13432172Sedward private int movepending; /* moveto pending coords on stack */
13532172Sedward private int showpending; /* number of characters waiting to be shown */
13632172Sedward private char *UsersHeader = 0; /* user specified heading */
13732172Sedward private char *Header = 0; /* generated header (usually FileName) */
13832172Sedward private int Page = 0; /* current page number */
13932172Sedward private int TotalPages = 0; /* total number of pages printed */
14032172Sedward private int TruncChars = 0; /* number of characters truncated */
14132172Sedward private int UndefChars = 0; /* number of characters skipped because
14232172Sedward they weren't defined in some font */
14332172Sedward private int BadChars = 0; /* number of bad characters seen so far */
14432172Sedward
14532172Sedward private FILE *OutFile = 0; /* output ps file */
14632172Sedward
14732172Sedward /* decode a fontname string - e.g. Courier10 Helvetica-Bold12 */
decodefont(name,f)14832172Sedward private decodefont (name, f)
14932172Sedward register char *name;
15032172Sedward register struct font *f; {
15132172Sedward register char *d, *p;
15232172Sedward
15332172Sedward SeenFont++;
15432172Sedward if (ScannedFonts) {
15532172Sedward fprintf(stderr,"Fonts must be specified before any files are processed\n");
15632172Sedward exit(1);
15732172Sedward }
15832172Sedward p = name;
15932172Sedward d = f->name;
16032172Sedward while (isascii(*p) && (isalpha(*p) || (*p == '-'))) {*d++ = *p++;}
16132172Sedward *d++ = '\0';
16232172Sedward if (isascii(*p) && isdigit(*p)) {
16332172Sedward f->dsize = 0;
16432172Sedward do
16532172Sedward f->dsize = f->dsize * 10 + *p++ - '0';
16632172Sedward while ('0' <= *p && *p <= '9');
16732172Sedward }
16832172Sedward if (*p || !f->dsize || !f->name[0]) {
16932172Sedward fprintf (stderr, "Poorly formed font name: \"%s\"\n", name);
17032172Sedward exit (1);
17132172Sedward }
17232172Sedward }
17332172Sedward
17432172Sedward
17532172Sedward #define NOTDEF 0x8000
17632172Sedward #define ForAllFonts(p) for(p = &fonts[nf-1]; p >= &fonts[0]; p--)
17732172Sedward
17832172Sedward /* Scan the font metrics directory looking for entries that match the
17932172Sedward * entries in ``fonts''. For entries
18032172Sedward * that are found the data in the font description is filled in,
18132172Sedward * if any are missing, it dies horribly.
18232172Sedward */
ScanFont()18332172Sedward private ScanFont () {
18432172Sedward register struct font *f;
18532172Sedward register FILE *FontData; /* afm file */
18632172Sedward char *c;
18732172Sedward int ccode, cwidth, inChars;
18832172Sedward char *MetricsDir = (char *) getenv ("METRICS");
18932172Sedward char FontFile[512]; /* afm file name */
19032172Sedward char afmbuf[BUFSIZ];
19132172Sedward
19232172Sedward if (MetricsDir == 0)
19332172Sedward MetricsDir = LibDir;
19432172Sedward
19532172Sedward if (!SeenFont & Rotated & TwoColumn) {
19632172Sedward fonts[HeaderFont].dsize = 10;
19732172Sedward fonts[BodyFont].dsize = 7;
19832172Sedward fonts[KwordFont].dsize = 7;
19932172Sedward fonts[LiteralFont].dsize = 8;
20032172Sedward fonts[CommentFont].dsize = 7;
20132172Sedward }
20232172Sedward
20332172Sedward /* loop through fonts, find and read metric entry in dir */
20432172Sedward ForAllFonts (f) {
20532172Sedward mstrcat(FontFile, MetricsDir, "/", sizeof FontFile);
20632172Sedward mstrcat(FontFile, FontFile, f->name, sizeof FontFile);
20732172Sedward mstrcat(FontFile, FontFile, ".afm", sizeof FontFile);
20832172Sedward if ((FontData = fopen(FontFile,"r")) == NULL){
20932172Sedward fprintf(stderr,"Can't open font metrics file %s\n",FontFile);
21032172Sedward exit(1);
21132172Sedward }
21232172Sedward /* read the .afm file to get the widths */
21332172Sedward for (ccode = 0; ccode < FSIZEMAX; ccode++) f->Xwid[ccode] = NOTDEF;
21432172Sedward
21532172Sedward inChars = 0;
21632172Sedward while(fgets(afmbuf, sizeof afmbuf, FontData) != NULL) {
21732172Sedward /* strip off newline */
21832172Sedward if ((c = index(afmbuf, '\n')) == 0) {
21932172Sedward fprintf(stderr, "AFM file %s line too long %s\n", FontFile, afmbuf);
22032172Sedward exit(1);
22132172Sedward }
22232172Sedward *c = '\0';
22332172Sedward if (*afmbuf == '\0') continue;
22432172Sedward if (strcmp(afmbuf, "StartCharMetrics") == 0) {
22532172Sedward inChars++;
22632172Sedward continue;
22732172Sedward }
22832172Sedward if (strcmp(afmbuf, "EndCharMetrics") == 0) break;
22932172Sedward if (inChars == 1) {
23032172Sedward if (sscanf(afmbuf, "C %d ; WX %d ;",&ccode,&cwidth) != 2) {
23132172Sedward fprintf(stderr,"Trouble with AFM file %s\n",FontFile);
23232172Sedward exit(1);
23332172Sedward }
23432172Sedward /* get out once we see an unencoded char */
23532172Sedward if (ccode == -1) break;
23632172Sedward if (ccode > 255) continue;
23732172Sedward f->Xwid[ccode] = (cwidth * f->dsize * UperPt) / 1000;
23832172Sedward continue;
23932172Sedward }
24032172Sedward }
24132172Sedward fclose (FontData);
24232172Sedward }
24332172Sedward
24432172Sedward TabWidth = fonts[BodyFont].Xwid['0'] * 8; /* 8 * figure width */
24532172Sedward BSWidth = fonts[BodyFont].Xwid[' ']; /* space width */
24632172Sedward
24732172Sedward UperLine = (fonts[BodyFont].dsize + 1) * UperPt;
24832172Sedward
24932172Sedward if (LPTsimulate)
25032172Sedward UperHLine = UperLine;
25132172Sedward else
25232172Sedward UperHLine = (fonts[HeaderFont].dsize + 1) * UperPt;
25332172Sedward
25432172Sedward crX = 0;
25532172Sedward crY = -UperLine;
25632172Sedward }
25732172Sedward
25832172Sedward /* Return a font number for the font with the indicated name
25932172Sedward * and size. Adds info to the font list for the eventual search.
26032172Sedward */
DefineFont(name,size)26132172Sedward private DefineFont (name, size)
26232172Sedward char *name; {
26332172Sedward register struct font *p;
26432172Sedward p = &fonts[nf];
26532172Sedward strcpy (p->name, name);
26632172Sedward p->dsize = size;
26732172Sedward return (nf++);
26832172Sedward }
26932172Sedward
27032172Sedward /* add a shown character to the PS file */
OUTputc(c)27132172Sedward private OUTputc (c)
27232172Sedward unsigned char c; {
27332172Sedward if (showpending == 0) {putc('(', OutFile); showpending++;}
27432172Sedward if (c == '\\' || c=='(' || c == ')') putc('\\', OutFile);
27532172Sedward if ((c > 0176) || (c < 040)) {
27632172Sedward putc('\\',OutFile);
27732172Sedward putc((c >> 6) +'0',OutFile);
27832172Sedward putc(((c >> 3) & 07)+'0', OutFile);
27932172Sedward putc((c & 07)+'0',OutFile);
28032172Sedward }
28132172Sedward else putc (c, OutFile);
28232172Sedward }
28332172Sedward
28432172Sedward /* Set the current font */
SetFont(f)28532172Sedward private SetFont (f) {
28632172Sedward FlushShow();
28732172Sedward LastFont = CurFont;
28832172Sedward fprintf(OutFile, "%d F\n", CurFont = f);
28932172Sedward }
29032172Sedward
29132172Sedward /* Reset to previous font */
PrevFont()29232172Sedward private PrevFont () {
29332172Sedward int temp;
29432172Sedward
29532172Sedward FlushShow();
29632172Sedward temp = CurFont;
29732172Sedward CurFont = LastFont;
29832172Sedward LastFont = temp;
29932172Sedward fprintf(OutFile, "%d F\n", CurFont);
30032172Sedward }
30132172Sedward
30232172Sedward /* put a character onto the page at the desired X and Y positions.
30332172Sedward * If the current position doesn't agree with the desired position, put out
30432172Sedward * movement directives. Leave the current position updated
30532172Sedward * to account for the character.
30632172Sedward */
ShowChar(c)30732172Sedward private ShowChar (c)
30832172Sedward register int c; {
30932172Sedward register struct font *f;
31032172Sedward register nX, nY;
31132172Sedward static level = 0;
31232172Sedward
31332172Sedward level++;
31432172Sedward f = &fonts[CurFont];
31532172Sedward
31632172Sedward if (f->Xwid[c] == NOTDEF) {
31732172Sedward UndefChars++;
31832172Sedward if(ListOmitted)
31932172Sedward printf("\'%c\' (%03o) not found in font %s\n",c,c,f->name);
32032172Sedward if(level<=1){
32132172Sedward ShowChar('\\');
32232172Sedward ShowChar((c>>6)+'0');
32332172Sedward ShowChar(((c>>3)&07)+'0');
32432172Sedward ShowChar((c&07)+'0');
32532172Sedward }
32632172Sedward level--;
32732172Sedward return;
32832172Sedward }
32932172Sedward nX = dX + f->Xwid[c]; /* resulting position after showing this char */
33032172Sedward nY = dY;
33132172Sedward
332*45864Skarels if (c != ' ' || ((cX == dX) && (cY == dY))) {
333*45864Skarels /*
334*45864Skarels * If character doesn't fit on this line
335*45864Skarels * (and we're not at left margin), simulate newline
336*45864Skarels * and then call ourselves recursively.
337*45864Skarels */
338*45864Skarels if (((!Rotated && nX > PageWidth)
339*45864Skarels || (Rotated && nX > PageLength)) &&
340*45864Skarels dX > lX) {
341*45864Skarels LineNo++;
342*45864Skarels SeenText++;
343*45864Skarels dY = lY = lY + crY;
344*45864Skarels dX = lX = lX + crX;
345*45864Skarels if (((!Rotated) && (dY < UperLine))
346*45864Skarels || (Rotated && (dY < ((PageLength-TruePageWidth) +
347*45864Skarels 3*UperLine+480)))
348*45864Skarels || (LPTsimulate && (--LinesLeft <= 0)))
349*45864Skarels PageEject ();
350*45864Skarels col = 1;
351*45864Skarels ShowChar(c);
352*45864Skarels level--;
353*45864Skarels return;
354*45864Skarels }
35532172Sedward if (cX != dX) {
35632172Sedward if (cY != dY) {
35732172Sedward FlushShow();
35832172Sedward /* absolute x, relative y */
35932172Sedward fprintf(OutFile,"%d %d",dX, dY);
36032172Sedward movepending = AbsXY;
36132172Sedward }
36232172Sedward else {
36332172Sedward FlushShow();
36432172Sedward fprintf(OutFile,"%d",dX-cX); /* relative x */
36532172Sedward movepending = RelX;
36632172Sedward }
36732172Sedward }
36832172Sedward else if (cY != dY) {
36932172Sedward FlushShow();
37032172Sedward fprintf(OutFile,"%d",dY-cY); /* relative y */
37132172Sedward movepending = RelY;
37232172Sedward }
37332172Sedward OUTputc (c);
37432172Sedward showpending++;
37532172Sedward cX = nX;
37632172Sedward cY = nY;
37732172Sedward }
37832172Sedward dX = nX;
37932172Sedward dY = nY;
38032172Sedward
38132172Sedward level--;
38232172Sedward }
38332172Sedward
38432172Sedward /* put out a shown string to the PS file */
ShowStr(s)38532172Sedward private ShowStr (s)
38632172Sedward register char *s; {
38732172Sedward while (*s) {
38832172Sedward if (*s >= 040) ShowChar (*s);
38932172Sedward s++;
39032172Sedward }
39132172Sedward }
39232172Sedward
39332172Sedward /* flush pending show */
FlushShow()39432172Sedward private FlushShow() {
39532172Sedward if (showpending) {
39632172Sedward putc(')',OutFile);
39732172Sedward switch (movepending) {
39832172Sedward case RelX:
39932172Sedward putc('X',OutFile);
40032172Sedward break;
40132172Sedward case RelY:
40232172Sedward putc('Y',OutFile);
40332172Sedward break;
40432172Sedward case AbsXY:
40532172Sedward putc('B',OutFile);
40632172Sedward break;
40732172Sedward case None:
40832172Sedward putc('S',OutFile);
40932172Sedward break;
41032172Sedward }
41132172Sedward putc('\n',OutFile);
41232172Sedward movepending = None;
41332172Sedward showpending = 0;
41432172Sedward }
41532172Sedward }
41632172Sedward
41732172Sedward /* put out a page heading to the PS file */
InitPage()41832172Sedward private InitPage () {
41932172Sedward char *basename();
42032172Sedward char header[200];
42132172Sedward register int OldFont = CurFont;
42232172Sedward
42332172Sedward TotalPages++;
42432172Sedward fprintf(OutFile, "%%%%Page: ? %d\n", TotalPages);
42532172Sedward fprintf(OutFile, "StartPage\n");
42632172Sedward LinesLeft = 64;
42732172Sedward SeenText = 0;
42832172Sedward cX = cY = -1;
42932172Sedward showpending = 0;
43032172Sedward FirstCol = 1;
43132172Sedward lX = dX = UperInch;
43232172Sedward lY = dY = PageLength - UperHLine * 3 / 2;
43332172Sedward if (Rotated) {
43432172Sedward fprintf(OutFile, "Landscape\n");
43532172Sedward lX = dX = UperInch / 4;
43632172Sedward }
43732172Sedward movepending = None;
43832172Sedward cX = dX; cY = dY;
43932172Sedward if (!NoTitle) {
44032172Sedward SetFont (HeaderFont);
44132172Sedward fprintf(OutFile, "%d %d ", cX, cY);
44232172Sedward movepending = AbsXY;
44332172Sedward if (UsersHeader) {
44432172Sedward if (*UsersHeader == 0) {
44532172Sedward fprintf(OutFile,"()B\n");
44632172Sedward movepending = None;
44732172Sedward showpending = 0;
44832172Sedward }
44932172Sedward else ShowStr (UsersHeader);
45032172Sedward }
45132172Sedward else {
45232172Sedward Page++;
45332172Sedward if (FileName == 0)
45432172Sedward sprintf(header, "Page %d", Page);
45532172Sedward else
45632172Sedward sprintf (header, "%s, page %d", basename(FileName), Page);
45732172Sedward ShowStr (header);
45832172Sedward }
45932172Sedward FlushShow();
46032172Sedward dX = lX = lX + crX * 3;
46132172Sedward dY = lY = lY + crY * 3;
46232172Sedward }
46332172Sedward else {
46432172Sedward /* fake it to force a moveto */
46532172Sedward cX = cY = 0;
46632172Sedward }
46732172Sedward SetFont (OldFont);
46832172Sedward }
46932172Sedward
47032172Sedward /* terminate a page. */
ClosePage()47132172Sedward private ClosePage () {
47232172Sedward FlushShow();
47332172Sedward fprintf(OutFile,"EndPage\n");
47432172Sedward }
47532172Sedward
47632172Sedward /* skip to a new page */
PageEject()47732172Sedward private PageEject () {
47832172Sedward if (TwoColumn && FirstCol) {
47932172Sedward FirstCol = 0;
48032172Sedward lX = dX = TruePageWidth / 2;
48132172Sedward lY = dY = PageLength - (UperHLine * 3 / 2);
48232172Sedward if (Rotated) {
48332172Sedward lX = dX = TruePageLength / 2;
48432172Sedward }
48532172Sedward if (!NoTitle) {
48632172Sedward dX = lX = lX + crX * 3;
48732172Sedward dY = lY = lY + crY * 3;
48832172Sedward }
48932172Sedward }
49032172Sedward else {
49132172Sedward ClosePage ();
49232172Sedward InitPage ();
49332172Sedward }
49432172Sedward LinesLeft = 64;
49532172Sedward SeenText = 0;
49632172Sedward }
49732172Sedward
49832172Sedward #if 0
49932172Sedward /* commented out AIS Fri Feb 22 10:00:36 1985 */
50032172Sedward private PageMessage (TotalPages)
50132172Sedward {
50232172Sedward if (TotalPages > 0) {
50332172Sedward printf ("psgrind formatted[ %d page%s * %d cop%s ]\n",
50432172Sedward TotalPages, TotalPages > 1 ? "s" : "",
50532172Sedward spoolCopies, spoolCopies > 1 ? "ies" : "y" );
50632172Sedward }
50732172Sedward }
50832172Sedward #endif
50932172Sedward
CommentHeader()51032172Sedward private CommentHeader() {
51132172Sedward long clock;
51232172Sedward struct passwd *pswd;
51332172Sedward char hostname[40];
51432172Sedward /* copy the file, prepending a new comment header */
51532172Sedward fprintf(OutFile,"%%!%s\n",COMMENTVERSION);
51632172Sedward fprintf(OutFile,"%%%%Creator: ");
51732172Sedward pswd = getpwuid(getuid());
51832172Sedward gethostname(hostname, (int) sizeof hostname);
51932172Sedward fprintf(OutFile,"%s:%s (%s)%s\n", hostname, pswd->pw_name,
52032172Sedward pswd->pw_gecos, spoolJobClass);
52132172Sedward
52232172Sedward fprintf(OutFile,"%%%%Title: %s %s\n",
52332172Sedward (FileName?FileName:"stdin"),
52432172Sedward spoolJobName);
52532172Sedward
52632172Sedward fprintf(OutFile,"%%%%CreationDate: %s",(time(&clock),ctime(&clock)));
52732172Sedward }
52832172Sedward
52932172Sedward
53032172Sedward /* list of C keywords to put in KwordFont */
53132172Sedward private char *KeyWordList[] = {
53232180Sedward "asm", "auto", "break", "case", "char", "continue", "default", "do",
53332180Sedward "double", "else", "entry", "enum", "extern", "float", "for", "fortran",
53432180Sedward "goto", "if", "int", "long", "register", "return", "short", "sizeof",
53532180Sedward "static", "struct", "switch", "typedef", "union", "unsigned", "void",
53632180Sedward "while", NULL
53732172Sedward };
53832172Sedward
53932172Sedward /* macros identifying C identifiers */
54032172Sedward #define isfirst(c) (isalpha(c) || (c) == '_')
54132172Sedward #define isident(c) (isalnum(c) || (c) == '_')
54232172Sedward
54332172Sedward /* Copy the standard input file to the PS file */
CopyFile()54432172Sedward private CopyFile () {
54532172Sedward register int c, last;
54632172Sedward int InComment, InString, InChar, IsKword;
54732172Sedward char token[50], *tend = token + sizeof (token) - 1;
54832172Sedward register char *tp, **kwp;
54932172Sedward
550*45864Skarels col = 1;
55132172Sedward if (OutFile == 0) {
55232172Sedward if (OutOnly && !(PageSpec || Reverse)) {
55332172Sedward OutFile = PipeOut ? stdout : fopen(OutName,"w");
55432172Sedward }
55532172Sedward else {
55632172Sedward mktemp(mstrcat(TempName,TempDir,PSGRINDTEMP,sizeof TempName));
55732172Sedward OutFile = fopen (TempName, "w");
55832172Sedward }
55932172Sedward }
56032172Sedward if (OutFile == NULL) {
56132172Sedward fprintf(stderr, "Can't create PS file %s\n",TempName);
56232172Sedward exit(1);
56332172Sedward }
56432172Sedward if (!ScannedFonts) {
56532172Sedward ScannedFonts++;
56632172Sedward ScanFont();
56732172Sedward }
56832172Sedward if (!Cvted) {
56932172Sedward CommentHeader();
57032172Sedward if (nf) {
57132172Sedward register struct font *f;
57232172Sedward fprintf(OutFile,"%%%%DocumentFonts:");
57332172Sedward ForAllFonts(f) {
57432172Sedward fprintf(OutFile," %s",f->name);
57532172Sedward }
57632172Sedward fprintf(OutFile,"\n");
57732172Sedward }
57832172Sedward /* copy in fixed prolog */
57932172Sedward if (copyfile(mstrcat(tempstr,LibDir,PSGRINDPRO,sizeof tempstr),
58032172Sedward OutFile)) {
58132172Sedward fprintf(stderr,"trouble copying prolog file \"%s\".\n",tempstr);
58232172Sedward exit(1);
58332172Sedward }
58432172Sedward fprintf(OutFile,"StartEnscriptDoc %% end fixed prolog\n");
58532172Sedward DumpFonts();
58632172Sedward fprintf(OutFile,"%%%%EndProlog\n");
58732172Sedward if (PreFeed) {
58832172Sedward fprintf(OutFile,"true DoPreFeed\n");
58932172Sedward }
59032172Sedward }
59132172Sedward Cvted++;
59232172Sedward
59332172Sedward Page = 0;
59432172Sedward LineNo = 1;
59532172Sedward BadChars = 0; /* give each file a clean slate */
59632172Sedward InitPage ();
59732172Sedward last = '\0';
59832172Sedward InComment = InChar = InString = 0;
59932172Sedward while ((c = getchar ()) != EOF) {
60032172Sedward if ((c > 0177 || c < 0) && (!IgnoreGarbage)) {
60132172Sedward if (BadChars++ > MAXBAD) {/* allow some kruft but not much */
60232172Sedward fprintf(stderr,"\"%s\" not a text file? - char '\\%03o'@0%o\nTry -g.\n",
60332172Sedward FileName ? FileName : "stdin", c, ftell (stdin) - 1);
60432172Sedward exit(1);
60532172Sedward }
60632172Sedward } else {
60732172Sedward switch (c) {
60832172Sedward case 010: /* backspace */
60932172Sedward dX -= BSWidth;
61032172Sedward break;
61132172Sedward case 015: /* carriage return ^M */
61232172Sedward dY = lY;
61332172Sedward dX = lX;
61432172Sedward break;
61532172Sedward case 012: /* linefeed ^J */
61632172Sedward LineNo++;
61732172Sedward if (dX != lX || dY != lY || !LPTsimulate || SeenText){
61832172Sedward SeenText++;
61932172Sedward dY = lY = lY + crY;
62032172Sedward dX = lX = lX + crX;
62132172Sedward }
62232172Sedward else
62332172Sedward LinesLeft = 64;
62432172Sedward if (((!Rotated) && (dY < UperLine))
62532172Sedward || (Rotated && (dY < ((PageLength-TruePageWidth) +
62632172Sedward 3*UperLine+480)))
62732172Sedward || (LPTsimulate && (--LinesLeft <= 0)))
62832172Sedward PageEject ();
62932172Sedward col = 1;
63032172Sedward break;
63132172Sedward case 014: /* form feed ^L */
63232172Sedward PageEject ();
63332172Sedward col = 1;
63432172Sedward break;
63532172Sedward case 011: /* tab ^I */
63632172Sedward col = (col - 1) / 8 * 8 + 9;
637*45864Skarels dX += TabWidth - ((dX - lX) % TabWidth);
63832172Sedward break;
63932172Sedward case '\\': /* special escape */
64032172Sedward last = c;
64132172Sedward if ((c = getchar()) == EOF)
64232172Sedward goto done;
64332172Sedward ShowChar('\\');
64432172Sedward col++;
64532172Sedward if (c == '\n') {
64632172Sedward /* want to leave newlines alone */
64732172Sedward ungetc(c, stdin);
64832172Sedward } else {
64932172Sedward ShowChar(c);
65032172Sedward col++;
65132172Sedward }
65232172Sedward break;
65332172Sedward case '"': /* a string quote mark */
65432172Sedward if (InComment || InChar) {
65532172Sedward /* just put out the quote */
65632172Sedward ShowChar('"');
65732172Sedward col++;
65832172Sedward } else if (InString) {
65932172Sedward ShowChar('"');
66032172Sedward col++;
66132172Sedward PrevFont();
66232172Sedward InString = 0;
66332172Sedward } else {
66432172Sedward SetFont(LiteralFont);
66532172Sedward ShowChar('"');
66632172Sedward col++;
66732172Sedward InString = 1;
66832172Sedward }
66932172Sedward break;
67032172Sedward case '\'': /* a char quote mark */
67132172Sedward if (InComment || InString) {
67232172Sedward /* just put out the character */
67332172Sedward ShowChar('\'');
67432172Sedward col++;
67532172Sedward } else if (InChar) {
67632172Sedward ShowChar('\'');
67732172Sedward col++;
67832172Sedward PrevFont();
67932172Sedward InChar = 0;
68032172Sedward } else {
68132172Sedward SetFont(LiteralFont);
68232172Sedward ShowChar('\'');
68332172Sedward col++;
68432172Sedward InChar = 1;
68532172Sedward }
68632172Sedward break;
68732172Sedward case '/':
68832172Sedward if (InComment && last == '*') {
68932172Sedward ShowChar('/');
69032172Sedward col++;
69132172Sedward SetFont(BodyFont);
69232172Sedward InComment = 0;
69332172Sedward } else if ((c = getchar()) == '*' && !InComment) {
69432172Sedward SetFont(CommentFont);
69532172Sedward InComment = 1;
69632172Sedward ShowChar('/');
69732172Sedward ShowChar('*');
69832172Sedward col += 2;
69932172Sedward } else {
70032172Sedward ungetc(c, stdin);
70132172Sedward ShowChar('/');
70232172Sedward col++;
70332172Sedward c = '/';
70432172Sedward }
70532172Sedward break;
70632172Sedward default: /* plain text, put it out */
70732172Sedward if (!InComment && !InString && isfirst(c)) {
70832172Sedward tp = token;
70932172Sedward while (isident(c) && tp < tend) {
71032172Sedward *tp++ = c;
71132172Sedward last = c;
71232172Sedward c = getchar();
71332172Sedward }
71432172Sedward *tp = '\0';
71532172Sedward ungetc(c, stdin);
71632172Sedward tp = token;
71732172Sedward IsKword = 0;
71832180Sedward for (kwp = KeyWordList;
71932180Sedward *kwp != NULL && **kwp <= *tp; kwp++)
72032172Sedward if (!strcmp(*kwp, tp)) {
72132172Sedward IsKword = 1;
72232172Sedward break;
72332172Sedward }
72432172Sedward if (IsKword)
72532172Sedward SetFont(KwordFont);
72632172Sedward ShowStr(tp);
72732172Sedward col += strlen(tp);
72832172Sedward if (IsKword)
72932172Sedward SetFont(BodyFont);
73032172Sedward } else if (fonts[CurFont].Xwid[c] != NOTDEF) {
73132172Sedward /* other normal character */
73232172Sedward ShowChar (c);
73332172Sedward col++;
73432172Sedward } else { /* not in font, quote it */
73532172Sedward ShowChar ('\\');
73632172Sedward ShowChar ((c >> 6) + '0');
73732172Sedward ShowChar (((c >> 3) & 7) + '0');
73832172Sedward ShowChar ((c & 7) + '0');
73932172Sedward col += 4;
74032172Sedward }
74132172Sedward break;
74232172Sedward }
74332172Sedward }
74432172Sedward last = c;
74532172Sedward }
74632172Sedward
74732172Sedward done:
74832172Sedward ClosePage ();
74932172Sedward }
75032172Sedward
75132172Sedward /* dump the fonts to the PS file for setup */
DumpFonts()75232172Sedward private DumpFonts () {
75332172Sedward register struct font *f;
75432172Sedward
75532172Sedward ForAllFonts (f) {
75632172Sedward fprintf(OutFile,"%d %d /%s\n",f-&fonts[0],f->dsize*UperPt,f->name);
75732172Sedward }
75832172Sedward fprintf(OutFile, "%d SetUpFonts\n", nf);
75932172Sedward }
76032172Sedward
76132172Sedward
76232172Sedward /*
76332172Sedward * close the PS file
76432172Sedward */
ClosePS()76532172Sedward private ClosePS () {
76632172Sedward fprintf(OutFile,"%%%%Trailer\n");
76732172Sedward if (PreFeed) {
76832172Sedward fprintf(OutFile,"false DoPreFeed\n");
76932172Sedward }
77032172Sedward fprintf(OutFile,"EndEnscriptDoc\nEnscriptJob restore\n");
77132172Sedward }
77232172Sedward
ProcessArg(p)77332172Sedward private ProcessArg (p)
77432172Sedward register char *p; {
77532172Sedward static enum State {
77632172Sedward normal, PSname,
77732172Sedward H_fontname, B_fontname, K_fontname, C_fontname, L_fontname,
77832172Sedward grabheader, getclass, getjobname
77932172Sedward } state = normal;
78032172Sedward
78132172Sedward switch (state) {
78232172Sedward case PSname:
78332172Sedward strcpy (OutName, p);
78432172Sedward if (strcmp(OutName,"-") == 0) PipeOut++;
78532172Sedward state = normal;
78632172Sedward break;
78732172Sedward case H_fontname:
78832172Sedward decodefont (p, &fonts[HeaderFont]);
78932172Sedward state = normal;
79032172Sedward break;
79132172Sedward case B_fontname:
79232172Sedward decodefont (p, &fonts[BodyFont]);
79332172Sedward state = normal;
79432172Sedward break;
79532172Sedward case K_fontname:
79632172Sedward decodefont (p, &fonts[KwordFont]);
79732172Sedward state = normal;
79832172Sedward break;
79932172Sedward case L_fontname:
80032172Sedward decodefont (p, &fonts[LiteralFont]);
80132172Sedward state = normal;
80232172Sedward break;
80332172Sedward case C_fontname:
80432172Sedward decodefont (p, &fonts[CommentFont]);
80532172Sedward state = normal;
80632172Sedward break;
80732172Sedward case grabheader:
80832172Sedward UsersHeader = p;
80932172Sedward state = normal;
81032172Sedward break;
81132172Sedward case getclass:
81232172Sedward spoolJobClass = p;
81332172Sedward state = normal;
81432172Sedward break;
81532172Sedward case getjobname:
81632172Sedward spoolJobName = p;
81732172Sedward state = normal;
81832172Sedward break;
81932172Sedward default:
82032172Sedward if (*p == '-') while (*++p) switch (*p) {
82132172Sedward case '1':
82232172Sedward TwoColumn = 0;
82332172Sedward if (SeenFile) {
82432172Sedward fprintf(stderr,"Specify -1 before any files\n");
82532172Sedward exit(1);
82632172Sedward }
82732172Sedward break;
82832172Sedward case '2':
82932172Sedward TwoColumn++;
83032172Sedward if (SeenFile){
83132172Sedward fprintf(stderr,"Specify -2 before any files\n");
83232172Sedward exit(1);
83332172Sedward }
83432172Sedward break;
83532172Sedward case 'v':
83632172Sedward Reverse = 1;
83732172Sedward break;
83832172Sedward case 's':
83932172Sedward PageSpec = (++p);
84032172Sedward while (*p != '\0') p++;
84132172Sedward return;
84232172Sedward
84332172Sedward /* the following options allow uswer specification
84432172Sedward of the five files used by the program */
84532172Sedward case 'H': state = H_fontname; break;
84632172Sedward case 'B': state = B_fontname; break;
84732172Sedward case 'K': state = K_fontname; break;
84832172Sedward case 'L': state = L_fontname; break;
84932172Sedward case 'C': state = C_fontname; break;
85032172Sedward
85132172Sedward case 'g': IgnoreGarbage++; break;
85232172Sedward case 'o': ListOmitted++; break;
85332172Sedward case 'p': OutOnly++; state = PSname; break;
85432172Sedward case 'r':
85532172Sedward Rotated++;
85632172Sedward if (SeenFile){
85732172Sedward fprintf(stderr,"Specify rotation before any files\n");
85832172Sedward exit(1);
85932172Sedward }
86032172Sedward break;
86132172Sedward case 'R':
86232172Sedward Rotated = 0;
86332172Sedward if (SeenFile){
86432172Sedward fprintf(stderr,"Specify rotation before any files\n");
86532172Sedward exit(1);
86632172Sedward }
86732172Sedward break;
86832172Sedward case 'k':
86932172Sedward PreFeed++;
87032172Sedward if (SeenFile){
87132172Sedward fprintf(stderr,"Specify prefeed before any files\n");
87232172Sedward exit(1);
87332172Sedward }
87432172Sedward break;
87532172Sedward
87632172Sedward /* the following switches are as in lpr(1) and */
87732172Sedward /* are passed through when spooling to a printer */
87832172Sedward case 'P': /* printer name */
87932172Sedward PrinterName = (++p);
88032172Sedward while (*p != '\0') p++;
88132172Sedward return;
88232172Sedward case 'J': /* job name (title) for the Job: field */
88332172Sedward state = getjobname;
88432172Sedward break;
88532172Sedward case 'm': /* notify by mail */
88632172Sedward spoolNotify = 1;
88732172Sedward break;
88832172Sedward case 'h':
88932172Sedward spoolNoBurst = 1;
89032172Sedward break;
89132172Sedward case '#':
89232172Sedward spoolCopies = atoi(++p);
89332172Sedward if (spoolCopies < 1){
89432172Sedward fprintf(stderr,"Bad argument for -# (number of copies)\n");
89532172Sedward exit(1);
89632172Sedward }
89732172Sedward break;
89832172Sedward
89932172Sedward default:
90032172Sedward printf ("Unknown option: %c\n", *p);
90132172Sedward SeenFile++;
90232172Sedward break;
90332172Sedward }
90432172Sedward else {/* not a flag -- a filename */
90532172Sedward FileName = Header = p;
90632172Sedward if (freopen (FileName, "r", stdin) == NULL) {
90732172Sedward printf ("Can't open %s\n", FileName);
90832172Sedward exit (1);
90932172Sedward }
91032172Sedward fstat (fileno (stdin), &S);
91132172Sedward FileDate = strcpy(DateStr,ctime (&S.st_mtime));
91232172Sedward CopyFile ();
91332172Sedward fclose (stdin);
91432172Sedward SeenFile = 1;
91532172Sedward }
91632172Sedward }
91732172Sedward }
91832172Sedward
main(argc,argv)91932172Sedward main (argc, argv)
92032172Sedward char **argv; {
92132172Sedward register char *p, *arg;
92232172Sedward
92332172Sedward prog = *argv;
92432172Sedward
92532172Sedward BodyFont = LastFont = CurFont = DefineFont (BODYFONT, 10);
92632172Sedward HeaderFont = DefineFont (HEADERFONT, 12);
92732172Sedward KwordFont = DefineFont (KWORDFONT, 10);
92832172Sedward CommentFont = DefineFont (COMMENTFONT, 10);
92932172Sedward LiteralFont = DefineFont (LITERALFONT, 11);
93032172Sedward
93132172Sedward /* process args in environment variable PSGRIND */
93232172Sedward if (p = getenv ("PSGRIND"))
93332172Sedward while (1) {
93432172Sedward register char quote = ' ';
93532172Sedward while (*p == ' ')
93632172Sedward p++;
93732172Sedward if (*p == '"' || *p == '\'')
93832172Sedward quote = *p++;
93932172Sedward arg = p;
94032172Sedward while (*p != quote && *p != '\0')
94132172Sedward p++;
94232172Sedward if (*p == '\0') {
94332172Sedward if (*arg)
94432172Sedward ProcessArg (arg);
94532172Sedward break;
94632172Sedward }
94732172Sedward *p++ = '\0';
94832172Sedward ProcessArg (arg);
94932172Sedward }
95032172Sedward
95132172Sedward /* process the command line arguments */
95232172Sedward while (argc > 1) {
95332172Sedward argc--;
95432172Sedward ProcessArg (*++argv);
95532172Sedward }
95632172Sedward
95732172Sedward if (!SeenFile) {
95832172Sedward FileName = Header = 0;
95932172Sedward FileDate = "";
96032172Sedward fstat (fileno (stdin), &S);
96132172Sedward
96232172Sedward if ((S.st_mode & S_IFMT) == S_IFREG)
96332172Sedward FileDate = strcpy(DateStr, ctime (&S.st_mtime));
96432172Sedward CopyFile ();
96532172Sedward }
96632172Sedward
96732172Sedward if (Cvted) {
96832172Sedward ClosePS ();
96932172Sedward fclose (OutFile);
97032172Sedward OutFile = 0;
97132172Sedward }
97232172Sedward if (TruncChars)
97332172Sedward printf ("%d characters omitted because of long lines.\n",
97432172Sedward TruncChars);
97532172Sedward if (UndefChars)
97632172Sedward printf ("%d characters omitted because of incomplete fonts.\n",
97732172Sedward UndefChars);
97832172Sedward /* PageMessage (TotalPages); */
97932172Sedward if (Cvted) {
98032172Sedward if (OutOnly) {
98132172Sedward if (Reverse || PageSpec) {
98232172Sedward char temparg[200];
98332172Sedward char *sargs[200];
98432172Sedward int args = 0;
98532172Sedward
98632172Sedward int cpid = 0;
98732172Sedward /* feed Temporary through psrev */
98832172Sedward freopen(TempName, "r", stdin);
98932172Sedward if (!PipeOut) freopen(OutName, "w", stdout);
99032172Sedward unlink(TempName);
99132172Sedward
99232172Sedward addarg(sargs, REVERSE, &args);
99332172Sedward addarg(sargs, "-r", &args);
99432172Sedward if (!Reverse) addarg(sargs, "-R", &args);
99532172Sedward
99632172Sedward if (PageSpec) {
99732172Sedward sprintf(temparg,"-s%s",PageSpec);
99832172Sedward addarg(sargs, temparg, &args);
99932172Sedward }
100032172Sedward if ((cpid = fork()) < 0) pexit(prog,1);
100132172Sedward if (cpid == 0) {
100232172Sedward execvp(REVERSE, sargs);
100332172Sedward pexit(prog,1);
100432172Sedward }
100532172Sedward else {
100632172Sedward wait(0);
100732172Sedward }
100832172Sedward }
100932172Sedward /* fprintf (stderr,"PS file left on %s\n", OutName); */
101032172Sedward }
101132172Sedward else
101232172Sedward SpoolIt();
101332172Sedward }
101432172Sedward }
101532172Sedward
addarg(argv,argstr,argc)101632172Sedward private addarg(argv, argstr, argc)
101732172Sedward char **argv;
101832172Sedward char *argstr;
101932172Sedward register int *argc;
102032172Sedward {
102132172Sedward register char *p = (char *) malloc (strlen(argstr) + 1);
102232172Sedward strcpy (p, argstr);
102332172Sedward argv[(*argc)++] = p;
102432172Sedward argv[*argc] = '\0';
102532172Sedward }
102632172Sedward
SpoolIt()102732172Sedward private SpoolIt()
102832172Sedward {
102932172Sedward char temparg[200];
103032172Sedward char *argstr[200];
103132172Sedward int nargs = 0;
103232172Sedward
103332172Sedward char *rargs[40];
103432172Sedward int nr = 0;
103532172Sedward int cpid =0;
103632172Sedward int fdpipe[2];
103732172Sedward
103832172Sedward addarg(argstr, LPR, &nargs);
103932172Sedward if (spoolCopies > 1) {
104032172Sedward sprintf(temparg,"-#%d",spoolCopies);
104132172Sedward addarg(argstr, temparg, &nargs);
104232172Sedward }
104332172Sedward if (PrinterName) {
104432172Sedward sprintf(temparg,"-P%s",PrinterName);
104532172Sedward addarg(argstr, temparg, &nargs);
104632172Sedward }
104732172Sedward else if (getenv("PRINTER") == 0) {
104832172Sedward /* no printer name known anywhere, use default */
104932172Sedward sprintf(temparg,"-P%s",POSTSCRIPTPRINTER);
105032172Sedward addarg(argstr, temparg, &nargs);
105132172Sedward }
105232172Sedward if (spoolJobClass) {
105332172Sedward addarg(argstr, "-C", &nargs);
105432172Sedward addarg(argstr, spoolJobClass, &nargs);
105532172Sedward }
105632172Sedward addarg(argstr, "-J", &nargs);
105732172Sedward if (spoolJobName) {
105832172Sedward addarg(argstr, spoolJobName, &nargs);
105932172Sedward }
106032172Sedward else {
106132172Sedward if (!FileName) addarg(argstr, "stdin", &nargs);
106232172Sedward else addarg(argstr, FileName, &nargs);
106332172Sedward }
106432172Sedward if (spoolNotify) {
106532172Sedward addarg(argstr, "-m", &nargs);
106632172Sedward }
106732172Sedward if (spoolNoBurst) {
106832172Sedward addarg(argstr, "-h", &nargs);
106932172Sedward }
107032172Sedward
107132172Sedward if (Reverse || PageSpec) {
107232172Sedward /* lpr input will be stdin */
107332172Sedward
107432172Sedward addarg(rargs, REVERSE, &nr);
107532172Sedward addarg(rargs, "-r", &nr);
107632172Sedward if (!Reverse) addarg(rargs, "-R", &nr);
107732172Sedward if (PageSpec) {
107832172Sedward sprintf(temparg,"-s%s",PageSpec);
107932172Sedward addarg(rargs, temparg, &nr);
108032172Sedward }
108132172Sedward /* addarg(rargs, TempName, &nr); */
108232172Sedward
108332172Sedward freopen(TempName,"r",stdin);
108432172Sedward unlink(TempName);
108532172Sedward if (pipe(fdpipe)) pexit(prog,1);
108632172Sedward if ((cpid = fork()) < 0) pexit(prog,1);
108732172Sedward else if (!cpid) { /* child */
108832172Sedward if (close(1)) {
108932172Sedward pexit(prog,1);
109032172Sedward }
109132172Sedward /* set stdout to be the output pipe */
109232172Sedward if (dup (fdpipe[1]) == -1) {
109332172Sedward pexit(prog,1);
109432172Sedward }
109532172Sedward /* don't want to read or write the pipe itself, since dup */
109632172Sedward if (close (fdpipe[1]) || close (fdpipe[0])) {
109732172Sedward pexit(prog,1);
109832172Sedward }
109932172Sedward /* leave stderr alone */
110032172Sedward execvp (REVERSE, rargs);
110132172Sedward pexit(prog,1);
110232172Sedward }
110332172Sedward else {
110432172Sedward /* parent */
110532172Sedward /* replace stdin with pipe */
110632172Sedward if (close(0)) {
110732172Sedward pexit(prog,1);
110832172Sedward }
110932172Sedward
111032172Sedward if (dup(fdpipe[0]) == -1) {
111132172Sedward pexit(prog,1);
111232172Sedward }
111332172Sedward if (close (fdpipe[0]) || close (fdpipe[1])) {
111432172Sedward pexit(prog,1);
111532172Sedward }
111632172Sedward
111732172Sedward /* leave stdout and stderr alone */
111832172Sedward execvp(LPR, argstr);
111932172Sedward pexit(prog,1);
112032172Sedward }
112132172Sedward }
112232172Sedward else { /* just do lpr */
112332172Sedward /* remove the temporary file after spooling */
112432172Sedward addarg(argstr, "-r", &nargs); /* should we use a symbolic link too? */
112532172Sedward addarg(argstr, TempName, &nargs);
112632172Sedward execvp(LPR, argstr);
112732172Sedward pexit(prog,1);
112832172Sedward }
112932172Sedward }
113032172Sedward
113132172Sedward char *
basename(path)113232172Sedward basename(path)
113332172Sedward char *path;
113432172Sedward {
113532172Sedward register char *cp;
113632172Sedward
113732172Sedward for (cp = path; *cp != '\0'; cp++)
113832172Sedward ;
113932172Sedward for (--cp; cp > path && *cp != '/'; cp--)
114032172Sedward ;
114132172Sedward if (*cp == '/' && *(cp+1) != '\0')
114232172Sedward return (cp + 1);
114332172Sedward else
114432172Sedward return (path);
114532172Sedward }
1146