1*219b2ee8SDavid du Colombier /*
2*219b2ee8SDavid du Colombier *
3*219b2ee8SDavid du Colombier * posttek - PostScript translator for tektronix 4014 files
4*219b2ee8SDavid du Colombier *
5*219b2ee8SDavid du Colombier * A program that can be used to translate tektronix 4014 files into PostScript.
6*219b2ee8SDavid du Colombier * Most of the code was borrowed from the tektronix 4014 emulator that was written
7*219b2ee8SDavid du Colombier * for DMDs. Things have been cleaned up some, but there's still plently that
8*219b2ee8SDavid du Colombier * could be done.
9*219b2ee8SDavid du Colombier *
10*219b2ee8SDavid du Colombier * The PostScript prologue is copied from *prologue before any of the input files
11*219b2ee8SDavid du Colombier * are translated. The program expects that the following PostScript procedures
12*219b2ee8SDavid du Colombier * are defined in that file:
13*219b2ee8SDavid du Colombier *
14*219b2ee8SDavid du Colombier * setup
15*219b2ee8SDavid du Colombier *
16*219b2ee8SDavid du Colombier * mark ... setup -
17*219b2ee8SDavid du Colombier *
18*219b2ee8SDavid du Colombier * Handles special initialization stuff that depends on how the program
19*219b2ee8SDavid du Colombier * was called. Expects to find a mark followed by key/value pairs on the
20*219b2ee8SDavid du Colombier * stack. The def operator is applied to each pair up to the mark, then
21*219b2ee8SDavid du Colombier * the default state is set up.
22*219b2ee8SDavid du Colombier *
23*219b2ee8SDavid du Colombier * pagesetup
24*219b2ee8SDavid du Colombier *
25*219b2ee8SDavid du Colombier * page pagesetup -
26*219b2ee8SDavid du Colombier *
27*219b2ee8SDavid du Colombier * Does whatever is needed to set things up for the next page. Expects
28*219b2ee8SDavid du Colombier * to find the current page number on the stack.
29*219b2ee8SDavid du Colombier *
30*219b2ee8SDavid du Colombier * v
31*219b2ee8SDavid du Colombier *
32*219b2ee8SDavid du Colombier * mark dx1 dy1 ... dxn dyn x y v mark
33*219b2ee8SDavid du Colombier *
34*219b2ee8SDavid du Colombier * Draws the vector described by the numbers on the stack. The top two
35*219b2ee8SDavid du Colombier * numbers are the starting point. The rest are relative displacements
36*219b2ee8SDavid du Colombier * from the preceeding point. Must make sure we don't put too much on
37*219b2ee8SDavid du Colombier * the stack!
38*219b2ee8SDavid du Colombier *
39*219b2ee8SDavid du Colombier * t
40*219b2ee8SDavid du Colombier *
41*219b2ee8SDavid du Colombier * x y string t -
42*219b2ee8SDavid du Colombier *
43*219b2ee8SDavid du Colombier * Prints the string that's on the top of the stack starting at point
44*219b2ee8SDavid du Colombier * (x, y).
45*219b2ee8SDavid du Colombier *
46*219b2ee8SDavid du Colombier * p
47*219b2ee8SDavid du Colombier *
48*219b2ee8SDavid du Colombier * x y p -
49*219b2ee8SDavid du Colombier *
50*219b2ee8SDavid du Colombier * Marks the point (x, y) with a circle whose radius varies with the
51*219b2ee8SDavid du Colombier * current intensity setting.
52*219b2ee8SDavid du Colombier *
53*219b2ee8SDavid du Colombier * i
54*219b2ee8SDavid du Colombier *
55*219b2ee8SDavid du Colombier * percent focus i -
56*219b2ee8SDavid du Colombier *
57*219b2ee8SDavid du Colombier * Changes the size of the circle used to mark individual points to
58*219b2ee8SDavid du Colombier * percent of maximum for focused mode (focus=1) or defocused mode
59*219b2ee8SDavid du Colombier * (focus=0). The implementation leaves much to be desired!
60*219b2ee8SDavid du Colombier *
61*219b2ee8SDavid du Colombier * l
62*219b2ee8SDavid du Colombier *
63*219b2ee8SDavid du Colombier * mark array l mark
64*219b2ee8SDavid du Colombier *
65*219b2ee8SDavid du Colombier * Set the line drawing mode according to the description given in array.
66*219b2ee8SDavid du Colombier * The arrays that describe the different line styles are declared in
67*219b2ee8SDavid du Colombier * STYLES (file posttek.h). The array really belongs in the prologue!
68*219b2ee8SDavid du Colombier *
69*219b2ee8SDavid du Colombier * w
70*219b2ee8SDavid du Colombier *
71*219b2ee8SDavid du Colombier * n w -
72*219b2ee8SDavid du Colombier *
73*219b2ee8SDavid du Colombier * Adjusts the line width for vector drawing. Used to select normal (n=0)
74*219b2ee8SDavid du Colombier * or defocused (n=1) mode.
75*219b2ee8SDavid du Colombier *
76*219b2ee8SDavid du Colombier * f
77*219b2ee8SDavid du Colombier *
78*219b2ee8SDavid du Colombier * size f -
79*219b2ee8SDavid du Colombier *
80*219b2ee8SDavid du Colombier * Changes the size of the font that's used to print characters in alpha
81*219b2ee8SDavid du Colombier * mode. size is the tektronix character width and is used to choose an
82*219b2ee8SDavid du Colombier * appropriate point size in the current font.
83*219b2ee8SDavid du Colombier *
84*219b2ee8SDavid du Colombier * done
85*219b2ee8SDavid du Colombier *
86*219b2ee8SDavid du Colombier * done
87*219b2ee8SDavid du Colombier *
88*219b2ee8SDavid du Colombier * Makes sure the last page is printed. Only needed when we're printing
89*219b2ee8SDavid du Colombier * more than one page on each sheet of paper.
90*219b2ee8SDavid du Colombier *
91*219b2ee8SDavid du Colombier * The default line width is zero, which forces lines to be one pixel wide. That
92*219b2ee8SDavid du Colombier * works well on 'write to black' engines but won't be right for 'write to white'
93*219b2ee8SDavid du Colombier * engines. The line width can be changed using the -w option, or you can change
94*219b2ee8SDavid du Colombier * the initialization of linewidth in the prologue.
95*219b2ee8SDavid du Colombier *
96*219b2ee8SDavid du Colombier * Many default values, like the magnification and orientation, are defined in
97*219b2ee8SDavid du Colombier * the prologue, which is where they belong. If they're changed (by options), an
98*219b2ee8SDavid du Colombier * appropriate definition is made after the prologue is added to the output file.
99*219b2ee8SDavid du Colombier * The -P option passes arbitrary PostScript through to the output file. Among
100*219b2ee8SDavid du Colombier * other things it can be used to set (or change) values that can't be accessed by
101*219b2ee8SDavid du Colombier * other options.
102*219b2ee8SDavid du Colombier *
103*219b2ee8SDavid du Colombier */
104*219b2ee8SDavid du Colombier
105*219b2ee8SDavid du Colombier #include <stdio.h>
106*219b2ee8SDavid du Colombier #include <signal.h>
107*219b2ee8SDavid du Colombier #include <sys/types.h>
108*219b2ee8SDavid du Colombier #include <fcntl.h>
109*219b2ee8SDavid du Colombier
110*219b2ee8SDavid du Colombier #include "comments.h" /* PostScript file structuring comments */
111*219b2ee8SDavid du Colombier #include "gen.h" /* general purpose definitions */
112*219b2ee8SDavid du Colombier #include "path.h" /* for the prologue */
113*219b2ee8SDavid du Colombier #include "ext.h" /* external variable definitions */
114*219b2ee8SDavid du Colombier #include "posttek.h" /* control codes and other definitions */
115*219b2ee8SDavid du Colombier
116*219b2ee8SDavid du Colombier char *optnames = "a:c:f:m:n:o:p:w:x:y:A:C:E:J:L:P:R:DI";
117*219b2ee8SDavid du Colombier
118*219b2ee8SDavid du Colombier char *prologue = POSTTEK; /* default PostScript prologue */
119*219b2ee8SDavid du Colombier char *formfile = FORMFILE; /* stuff for multiple pages per sheet */
120*219b2ee8SDavid du Colombier
121*219b2ee8SDavid du Colombier int formsperpage = 1; /* page images on each piece of paper */
122*219b2ee8SDavid du Colombier int copies = 1; /* and this many copies of each sheet */
123*219b2ee8SDavid du Colombier
124*219b2ee8SDavid du Colombier int charheight[] = CHARHEIGHT; /* height */
125*219b2ee8SDavid du Colombier int charwidth[] = CHARWIDTH; /* and width arrays for tek characters */
126*219b2ee8SDavid du Colombier int tekfont = TEKFONT; /* index into charheight[] and charwidth[] */
127*219b2ee8SDavid du Colombier
128*219b2ee8SDavid du Colombier char intensity[] = INTENSITY; /* special point intensity array */
129*219b2ee8SDavid du Colombier char *styles[] = STYLES; /* description of line styles */
130*219b2ee8SDavid du Colombier int linestyle = 0; /* index into styles[] */
131*219b2ee8SDavid du Colombier int linetype = 0; /* 0 for normal, 1 for defocused */
132*219b2ee8SDavid du Colombier
133*219b2ee8SDavid du Colombier int dispmode = ALPHA; /* current tektronix state */
134*219b2ee8SDavid du Colombier int points = 0; /* points making up the current vector */
135*219b2ee8SDavid du Colombier int characters = 0; /* characters waiting to be printed */
136*219b2ee8SDavid du Colombier int pen = UP; /* just for point plotting */
137*219b2ee8SDavid du Colombier int margin = 0; /* left edge - ALPHA state */
138*219b2ee8SDavid du Colombier
139*219b2ee8SDavid du Colombier Point cursor; /* should be current cursor position */
140*219b2ee8SDavid du Colombier
141*219b2ee8SDavid du Colombier Fontmap fontmap[] = FONTMAP; /* for translating font names */
142*219b2ee8SDavid du Colombier char *fontname = "Courier"; /* use this PostScript font */
143*219b2ee8SDavid du Colombier
144*219b2ee8SDavid du Colombier int page = 0; /* page we're working on */
145*219b2ee8SDavid du Colombier int printed = 0; /* printed this many pages */
146*219b2ee8SDavid du Colombier
147*219b2ee8SDavid du Colombier FILE *fp_in; /* read from this file */
148*219b2ee8SDavid du Colombier FILE *fp_out = stdout; /* and write stuff here */
149*219b2ee8SDavid du Colombier FILE *fp_acct = NULL; /* for accounting data */
150*219b2ee8SDavid du Colombier
151*219b2ee8SDavid du Colombier /*****************************************************************************/
152*219b2ee8SDavid du Colombier
main(agc,agv)153*219b2ee8SDavid du Colombier main(agc, agv)
154*219b2ee8SDavid du Colombier
155*219b2ee8SDavid du Colombier int agc;
156*219b2ee8SDavid du Colombier char *agv[];
157*219b2ee8SDavid du Colombier
158*219b2ee8SDavid du Colombier {
159*219b2ee8SDavid du Colombier
160*219b2ee8SDavid du Colombier /*
161*219b2ee8SDavid du Colombier *
162*219b2ee8SDavid du Colombier * A simple program that can be used to translate tektronix 4014 files into
163*219b2ee8SDavid du Colombier * PostScript. Most of the code was taken from the DMD tektronix 4014 emulator,
164*219b2ee8SDavid du Colombier * although things have been cleaned up some.
165*219b2ee8SDavid du Colombier *
166*219b2ee8SDavid du Colombier */
167*219b2ee8SDavid du Colombier
168*219b2ee8SDavid du Colombier argv = agv; /* so everyone can use them */
169*219b2ee8SDavid du Colombier argc = agc;
170*219b2ee8SDavid du Colombier
171*219b2ee8SDavid du Colombier prog_name = argv[0]; /* just for error messages */
172*219b2ee8SDavid du Colombier
173*219b2ee8SDavid du Colombier init_signals(); /* sets up interrupt handling */
174*219b2ee8SDavid du Colombier header(); /* PostScript header comments */
175*219b2ee8SDavid du Colombier options(); /* handle the command line options */
176*219b2ee8SDavid du Colombier setup(); /* for PostScript */
177*219b2ee8SDavid du Colombier arguments(); /* followed by each input file */
178*219b2ee8SDavid du Colombier done(); /* print the last page etc. */
179*219b2ee8SDavid du Colombier account(); /* job accounting data */
180*219b2ee8SDavid du Colombier
181*219b2ee8SDavid du Colombier exit(x_stat); /* nothing could be wrong */
182*219b2ee8SDavid du Colombier
183*219b2ee8SDavid du Colombier } /* End of main */
184*219b2ee8SDavid du Colombier
185*219b2ee8SDavid du Colombier /*****************************************************************************/
186*219b2ee8SDavid du Colombier
init_signals()187*219b2ee8SDavid du Colombier init_signals()
188*219b2ee8SDavid du Colombier
189*219b2ee8SDavid du Colombier {
190*219b2ee8SDavid du Colombier
191*219b2ee8SDavid du Colombier /*
192*219b2ee8SDavid du Colombier *
193*219b2ee8SDavid du Colombier * Make sure we handle interrupts.
194*219b2ee8SDavid du Colombier *
195*219b2ee8SDavid du Colombier */
196*219b2ee8SDavid du Colombier
197*219b2ee8SDavid du Colombier if ( signal(SIGINT, interrupt) == SIG_IGN ) {
198*219b2ee8SDavid du Colombier signal(SIGINT, SIG_IGN);
199*219b2ee8SDavid du Colombier signal(SIGQUIT, SIG_IGN);
200*219b2ee8SDavid du Colombier signal(SIGHUP, SIG_IGN);
201*219b2ee8SDavid du Colombier } else {
202*219b2ee8SDavid du Colombier signal(SIGHUP, interrupt);
203*219b2ee8SDavid du Colombier signal(SIGQUIT, interrupt);
204*219b2ee8SDavid du Colombier } /* End else */
205*219b2ee8SDavid du Colombier
206*219b2ee8SDavid du Colombier signal(SIGTERM, interrupt);
207*219b2ee8SDavid du Colombier
208*219b2ee8SDavid du Colombier } /* End of init_signals */
209*219b2ee8SDavid du Colombier
210*219b2ee8SDavid du Colombier /*****************************************************************************/
211*219b2ee8SDavid du Colombier
header()212*219b2ee8SDavid du Colombier header()
213*219b2ee8SDavid du Colombier
214*219b2ee8SDavid du Colombier {
215*219b2ee8SDavid du Colombier
216*219b2ee8SDavid du Colombier int ch; /* return value from getopt() */
217*219b2ee8SDavid du Colombier int old_optind = optind; /* for restoring optind - should be 1 */
218*219b2ee8SDavid du Colombier
219*219b2ee8SDavid du Colombier /*
220*219b2ee8SDavid du Colombier *
221*219b2ee8SDavid du Colombier * Scans the option list looking for things, like the prologue file, that we need
222*219b2ee8SDavid du Colombier * right away but could be changed from the default. Doing things this way is an
223*219b2ee8SDavid du Colombier * attempt to conform to Adobe's latest file structuring conventions. In particular
224*219b2ee8SDavid du Colombier * they now say there should be nothing executed in the prologue, and they have
225*219b2ee8SDavid du Colombier * added two new comments that delimit global initialization calls. Once we know
226*219b2ee8SDavid du Colombier * where things really are we write out the job header, follow it by the prologue,
227*219b2ee8SDavid du Colombier * and then add the ENDPROLOG and BEGINSETUP comments.
228*219b2ee8SDavid du Colombier *
229*219b2ee8SDavid du Colombier */
230*219b2ee8SDavid du Colombier
231*219b2ee8SDavid du Colombier while ( (ch = getopt(argc, argv, optnames)) != EOF )
232*219b2ee8SDavid du Colombier if ( ch == 'L' )
233*219b2ee8SDavid du Colombier prologue = optarg;
234*219b2ee8SDavid du Colombier else if ( ch == '?' )
235*219b2ee8SDavid du Colombier error(FATAL, "");
236*219b2ee8SDavid du Colombier
237*219b2ee8SDavid du Colombier optind = old_optind; /* get ready for option scanning */
238*219b2ee8SDavid du Colombier
239*219b2ee8SDavid du Colombier fprintf(stdout, "%s", CONFORMING);
240*219b2ee8SDavid du Colombier fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION);
241*219b2ee8SDavid du Colombier fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND);
242*219b2ee8SDavid du Colombier fprintf(stdout, "%s %s\n", PAGES, ATEND);
243*219b2ee8SDavid du Colombier fprintf(stdout, "%s", ENDCOMMENTS);
244*219b2ee8SDavid du Colombier
245*219b2ee8SDavid du Colombier if ( cat(prologue) == FALSE )
246*219b2ee8SDavid du Colombier error(FATAL, "can't read %s", prologue);
247*219b2ee8SDavid du Colombier
248*219b2ee8SDavid du Colombier fprintf(stdout, "%s", ENDPROLOG);
249*219b2ee8SDavid du Colombier fprintf(stdout, "%s", BEGINSETUP);
250*219b2ee8SDavid du Colombier fprintf(stdout, "mark\n");
251*219b2ee8SDavid du Colombier
252*219b2ee8SDavid du Colombier } /* End of header */
253*219b2ee8SDavid du Colombier
254*219b2ee8SDavid du Colombier /*****************************************************************************/
255*219b2ee8SDavid du Colombier
options()256*219b2ee8SDavid du Colombier options()
257*219b2ee8SDavid du Colombier
258*219b2ee8SDavid du Colombier {
259*219b2ee8SDavid du Colombier
260*219b2ee8SDavid du Colombier int ch; /* value returned by getopt() */
261*219b2ee8SDavid du Colombier
262*219b2ee8SDavid du Colombier /*
263*219b2ee8SDavid du Colombier *
264*219b2ee8SDavid du Colombier * Reads and processes the command line options. Added the -P option so arbitrary
265*219b2ee8SDavid du Colombier * PostScript code can be passed through. Expect it could be useful for changing
266*219b2ee8SDavid du Colombier * definitions in the prologue for which options have not been defined.
267*219b2ee8SDavid du Colombier *
268*219b2ee8SDavid du Colombier */
269*219b2ee8SDavid du Colombier
270*219b2ee8SDavid du Colombier while ( (ch = getopt(argc, argv, optnames)) != EOF ) {
271*219b2ee8SDavid du Colombier switch ( ch ) {
272*219b2ee8SDavid du Colombier case 'a': /* aspect ratio */
273*219b2ee8SDavid du Colombier fprintf(stdout, "/aspectratio %s def\n", optarg);
274*219b2ee8SDavid du Colombier break;
275*219b2ee8SDavid du Colombier
276*219b2ee8SDavid du Colombier case 'c': /* copies */
277*219b2ee8SDavid du Colombier copies = atoi(optarg);
278*219b2ee8SDavid du Colombier fprintf(stdout, "/#copies %s store\n", optarg);
279*219b2ee8SDavid du Colombier break;
280*219b2ee8SDavid du Colombier
281*219b2ee8SDavid du Colombier case 'f': /* use this PostScript font */
282*219b2ee8SDavid du Colombier fontname = get_font(optarg);
283*219b2ee8SDavid du Colombier fprintf(stdout, "/font /%s def\n", fontname);
284*219b2ee8SDavid du Colombier break;
285*219b2ee8SDavid du Colombier
286*219b2ee8SDavid du Colombier case 'm': /* magnification */
287*219b2ee8SDavid du Colombier fprintf(stdout, "/magnification %s def\n", optarg);
288*219b2ee8SDavid du Colombier break;
289*219b2ee8SDavid du Colombier
290*219b2ee8SDavid du Colombier case 'n': /* forms per page */
291*219b2ee8SDavid du Colombier formsperpage = atoi(optarg);
292*219b2ee8SDavid du Colombier fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg);
293*219b2ee8SDavid du Colombier fprintf(stdout, "/formsperpage %s def\n", optarg);
294*219b2ee8SDavid du Colombier break;
295*219b2ee8SDavid du Colombier
296*219b2ee8SDavid du Colombier case 'o': /* output page list */
297*219b2ee8SDavid du Colombier out_list(optarg);
298*219b2ee8SDavid du Colombier break;
299*219b2ee8SDavid du Colombier
300*219b2ee8SDavid du Colombier case 'p': /* landscape or portrait mode */
301*219b2ee8SDavid du Colombier if ( *optarg == 'l' )
302*219b2ee8SDavid du Colombier fprintf(stdout, "/landscape true def\n");
303*219b2ee8SDavid du Colombier else fprintf(stdout, "/landscape false def\n");
304*219b2ee8SDavid du Colombier break;
305*219b2ee8SDavid du Colombier
306*219b2ee8SDavid du Colombier case 'w': /* line width */
307*219b2ee8SDavid du Colombier fprintf(stdout, "/linewidth %s def\n", optarg);
308*219b2ee8SDavid du Colombier break;
309*219b2ee8SDavid du Colombier
310*219b2ee8SDavid du Colombier case 'x': /* shift horizontally */
311*219b2ee8SDavid du Colombier fprintf(stdout, "/xoffset %s def\n", optarg);
312*219b2ee8SDavid du Colombier break;
313*219b2ee8SDavid du Colombier
314*219b2ee8SDavid du Colombier case 'y': /* and vertically on the page */
315*219b2ee8SDavid du Colombier fprintf(stdout, "/yoffset %s def\n", optarg);
316*219b2ee8SDavid du Colombier break;
317*219b2ee8SDavid du Colombier
318*219b2ee8SDavid du Colombier case 'A': /* force job accounting */
319*219b2ee8SDavid du Colombier case 'J':
320*219b2ee8SDavid du Colombier if ( (fp_acct = fopen(optarg, "a")) == NULL )
321*219b2ee8SDavid du Colombier error(FATAL, "can't open accounting file %s", optarg);
322*219b2ee8SDavid du Colombier break;
323*219b2ee8SDavid du Colombier
324*219b2ee8SDavid du Colombier case 'C': /* copy file straight to output */
325*219b2ee8SDavid du Colombier if ( cat(optarg) == FALSE )
326*219b2ee8SDavid du Colombier error(FATAL, "can't read %s", optarg);
327*219b2ee8SDavid du Colombier break;
328*219b2ee8SDavid du Colombier
329*219b2ee8SDavid du Colombier case 'E': /* text font encoding */
330*219b2ee8SDavid du Colombier fontencoding = optarg;
331*219b2ee8SDavid du Colombier break;
332*219b2ee8SDavid du Colombier
333*219b2ee8SDavid du Colombier case 'L': /* PostScript prologue file */
334*219b2ee8SDavid du Colombier prologue = optarg;
335*219b2ee8SDavid du Colombier break;
336*219b2ee8SDavid du Colombier
337*219b2ee8SDavid du Colombier case 'P': /* PostScript pass through */
338*219b2ee8SDavid du Colombier fprintf(stdout, "%s\n", optarg);
339*219b2ee8SDavid du Colombier break;
340*219b2ee8SDavid du Colombier
341*219b2ee8SDavid du Colombier case 'R': /* special global or page level request */
342*219b2ee8SDavid du Colombier saverequest(optarg);
343*219b2ee8SDavid du Colombier break;
344*219b2ee8SDavid du Colombier
345*219b2ee8SDavid du Colombier case 'D': /* debug flag */
346*219b2ee8SDavid du Colombier debug = ON;
347*219b2ee8SDavid du Colombier break;
348*219b2ee8SDavid du Colombier
349*219b2ee8SDavid du Colombier case 'I': /* ignore FATAL errors */
350*219b2ee8SDavid du Colombier ignore = ON;
351*219b2ee8SDavid du Colombier break;
352*219b2ee8SDavid du Colombier
353*219b2ee8SDavid du Colombier case '?': /* don't know the option */
354*219b2ee8SDavid du Colombier error(FATAL, "");
355*219b2ee8SDavid du Colombier break;
356*219b2ee8SDavid du Colombier
357*219b2ee8SDavid du Colombier default: /* don't know what to do for ch */
358*219b2ee8SDavid du Colombier error(FATAL, "missing case for option %c", ch);
359*219b2ee8SDavid du Colombier break;
360*219b2ee8SDavid du Colombier } /* End switch */
361*219b2ee8SDavid du Colombier } /* End while */
362*219b2ee8SDavid du Colombier
363*219b2ee8SDavid du Colombier argc -= optind;
364*219b2ee8SDavid du Colombier argv += optind;
365*219b2ee8SDavid du Colombier
366*219b2ee8SDavid du Colombier } /* End of options */
367*219b2ee8SDavid du Colombier
368*219b2ee8SDavid du Colombier /*****************************************************************************/
369*219b2ee8SDavid du Colombier
get_font(name)370*219b2ee8SDavid du Colombier char *get_font(name)
371*219b2ee8SDavid du Colombier
372*219b2ee8SDavid du Colombier char *name; /* name the user asked for */
373*219b2ee8SDavid du Colombier
374*219b2ee8SDavid du Colombier {
375*219b2ee8SDavid du Colombier
376*219b2ee8SDavid du Colombier int i; /* for looking through fontmap[] */
377*219b2ee8SDavid du Colombier
378*219b2ee8SDavid du Colombier /*
379*219b2ee8SDavid du Colombier *
380*219b2ee8SDavid du Colombier * Called from options() to map a user's font name into a legal PostScript name.
381*219b2ee8SDavid du Colombier * If the lookup fails *name is returned to the caller. That should let you choose
382*219b2ee8SDavid du Colombier * any PostScript font.
383*219b2ee8SDavid du Colombier *
384*219b2ee8SDavid du Colombier */
385*219b2ee8SDavid du Colombier
386*219b2ee8SDavid du Colombier for ( i = 0; fontmap[i].name != NULL; i++ )
387*219b2ee8SDavid du Colombier if ( strcmp(name, fontmap[i].name) == 0 )
388*219b2ee8SDavid du Colombier return(fontmap[i].val);
389*219b2ee8SDavid du Colombier
390*219b2ee8SDavid du Colombier return(name);
391*219b2ee8SDavid du Colombier
392*219b2ee8SDavid du Colombier } /* End of get_font */
393*219b2ee8SDavid du Colombier
394*219b2ee8SDavid du Colombier /*****************************************************************************/
395*219b2ee8SDavid du Colombier
setup()396*219b2ee8SDavid du Colombier setup()
397*219b2ee8SDavid du Colombier
398*219b2ee8SDavid du Colombier {
399*219b2ee8SDavid du Colombier
400*219b2ee8SDavid du Colombier /*
401*219b2ee8SDavid du Colombier *
402*219b2ee8SDavid du Colombier * Handles things that must be done after the options are read but before the
403*219b2ee8SDavid du Colombier * input files are processed.
404*219b2ee8SDavid du Colombier *
405*219b2ee8SDavid du Colombier */
406*219b2ee8SDavid du Colombier
407*219b2ee8SDavid du Colombier writerequest(0, stdout); /* global requests eg. manual feed */
408*219b2ee8SDavid du Colombier setencoding(fontencoding);
409*219b2ee8SDavid du Colombier fprintf(stdout, "setup\n");
410*219b2ee8SDavid du Colombier
411*219b2ee8SDavid du Colombier if ( formsperpage > 1 ) {
412*219b2ee8SDavid du Colombier if ( cat(formfile) == FALSE )
413*219b2ee8SDavid du Colombier error(FATAL, "can't read %s", formfile);
414*219b2ee8SDavid du Colombier fprintf(stdout, "%d setupforms\n", formsperpage);
415*219b2ee8SDavid du Colombier } /* End if */
416*219b2ee8SDavid du Colombier
417*219b2ee8SDavid du Colombier fprintf(stdout, "%s", ENDSETUP);
418*219b2ee8SDavid du Colombier
419*219b2ee8SDavid du Colombier } /* End of setup */
420*219b2ee8SDavid du Colombier
421*219b2ee8SDavid du Colombier /*****************************************************************************/
422*219b2ee8SDavid du Colombier
arguments()423*219b2ee8SDavid du Colombier arguments()
424*219b2ee8SDavid du Colombier
425*219b2ee8SDavid du Colombier {
426*219b2ee8SDavid du Colombier
427*219b2ee8SDavid du Colombier /*
428*219b2ee8SDavid du Colombier *
429*219b2ee8SDavid du Colombier * Makes sure all the non-option command line arguments are processed. If we get
430*219b2ee8SDavid du Colombier * here and there aren't any arguments left, or if '-' is one of the input files
431*219b2ee8SDavid du Colombier * we'll process stdin.
432*219b2ee8SDavid du Colombier *
433*219b2ee8SDavid du Colombier */
434*219b2ee8SDavid du Colombier
435*219b2ee8SDavid du Colombier if ( argc < 1 )
436*219b2ee8SDavid du Colombier statemachine(fp_in = stdin);
437*219b2ee8SDavid du Colombier else { /* at least one argument is left */
438*219b2ee8SDavid du Colombier while ( argc > 0 ) {
439*219b2ee8SDavid du Colombier if ( strcmp(*argv, "-") == 0 )
440*219b2ee8SDavid du Colombier fp_in = stdin;
441*219b2ee8SDavid du Colombier else if ( (fp_in = fopen(*argv, "r")) == NULL )
442*219b2ee8SDavid du Colombier error(FATAL, "can't open %s", *argv);
443*219b2ee8SDavid du Colombier statemachine(fp_in);
444*219b2ee8SDavid du Colombier if ( fp_in != stdin )
445*219b2ee8SDavid du Colombier fclose(fp_in);
446*219b2ee8SDavid du Colombier argc--;
447*219b2ee8SDavid du Colombier argv++;
448*219b2ee8SDavid du Colombier } /* End while */
449*219b2ee8SDavid du Colombier } /* End else */
450*219b2ee8SDavid du Colombier
451*219b2ee8SDavid du Colombier } /* End of arguments */
452*219b2ee8SDavid du Colombier
453*219b2ee8SDavid du Colombier /*****************************************************************************/
454*219b2ee8SDavid du Colombier
done()455*219b2ee8SDavid du Colombier done()
456*219b2ee8SDavid du Colombier
457*219b2ee8SDavid du Colombier {
458*219b2ee8SDavid du Colombier
459*219b2ee8SDavid du Colombier /*
460*219b2ee8SDavid du Colombier *
461*219b2ee8SDavid du Colombier * Finished with all the input files, so mark the end of the pages with a TRAILER
462*219b2ee8SDavid du Colombier * comment, make sure the last page prints, and add things like the PAGES comment
463*219b2ee8SDavid du Colombier * that can only be determined after all the input files have been read.
464*219b2ee8SDavid du Colombier *
465*219b2ee8SDavid du Colombier */
466*219b2ee8SDavid du Colombier
467*219b2ee8SDavid du Colombier fprintf(stdout, "%s", TRAILER);
468*219b2ee8SDavid du Colombier fprintf(stdout, "done\n");
469*219b2ee8SDavid du Colombier fprintf(stdout, "%s %s\n", DOCUMENTFONTS, fontname);
470*219b2ee8SDavid du Colombier fprintf(stdout, "%s %d\n", PAGES, printed);
471*219b2ee8SDavid du Colombier
472*219b2ee8SDavid du Colombier } /* End of done */
473*219b2ee8SDavid du Colombier
474*219b2ee8SDavid du Colombier /*****************************************************************************/
475*219b2ee8SDavid du Colombier
account()476*219b2ee8SDavid du Colombier account()
477*219b2ee8SDavid du Colombier
478*219b2ee8SDavid du Colombier {
479*219b2ee8SDavid du Colombier
480*219b2ee8SDavid du Colombier /*
481*219b2ee8SDavid du Colombier *
482*219b2ee8SDavid du Colombier * Writes an accounting record to *fp_acct provided it's not NULL. Accounting
483*219b2ee8SDavid du Colombier * is requested using the -A or -J options.
484*219b2ee8SDavid du Colombier *
485*219b2ee8SDavid du Colombier */
486*219b2ee8SDavid du Colombier
487*219b2ee8SDavid du Colombier if ( fp_acct != NULL )
488*219b2ee8SDavid du Colombier fprintf(fp_acct, " print %d\n copies %d\n", printed, copies);
489*219b2ee8SDavid du Colombier
490*219b2ee8SDavid du Colombier } /* End of account */
491*219b2ee8SDavid du Colombier
492*219b2ee8SDavid du Colombier /*****************************************************************************/
493*219b2ee8SDavid du Colombier
statemachine(fp)494*219b2ee8SDavid du Colombier statemachine(fp)
495*219b2ee8SDavid du Colombier
496*219b2ee8SDavid du Colombier FILE *fp; /* used to set fp_in */
497*219b2ee8SDavid du Colombier
498*219b2ee8SDavid du Colombier {
499*219b2ee8SDavid du Colombier
500*219b2ee8SDavid du Colombier /*
501*219b2ee8SDavid du Colombier *
502*219b2ee8SDavid du Colombier * Controls the translation of the next input file. Tektronix states (dispmode)
503*219b2ee8SDavid du Colombier * are typically changed in control() and esc().
504*219b2ee8SDavid du Colombier *
505*219b2ee8SDavid du Colombier */
506*219b2ee8SDavid du Colombier
507*219b2ee8SDavid du Colombier redirect(-1); /* get ready for the first page */
508*219b2ee8SDavid du Colombier formfeed();
509*219b2ee8SDavid du Colombier dispmode = RESET;
510*219b2ee8SDavid du Colombier
511*219b2ee8SDavid du Colombier while ( 1 )
512*219b2ee8SDavid du Colombier switch ( dispmode ) {
513*219b2ee8SDavid du Colombier case RESET:
514*219b2ee8SDavid du Colombier reset();
515*219b2ee8SDavid du Colombier break;
516*219b2ee8SDavid du Colombier
517*219b2ee8SDavid du Colombier case ALPHA:
518*219b2ee8SDavid du Colombier alpha();
519*219b2ee8SDavid du Colombier break;
520*219b2ee8SDavid du Colombier
521*219b2ee8SDavid du Colombier case GIN:
522*219b2ee8SDavid du Colombier gin();
523*219b2ee8SDavid du Colombier break;
524*219b2ee8SDavid du Colombier
525*219b2ee8SDavid du Colombier case GRAPH:
526*219b2ee8SDavid du Colombier graph();
527*219b2ee8SDavid du Colombier break;
528*219b2ee8SDavid du Colombier
529*219b2ee8SDavid du Colombier case POINT:
530*219b2ee8SDavid du Colombier case SPECIALPOINT:
531*219b2ee8SDavid du Colombier point();
532*219b2ee8SDavid du Colombier break;
533*219b2ee8SDavid du Colombier
534*219b2ee8SDavid du Colombier case INCREMENTAL:
535*219b2ee8SDavid du Colombier incremental();
536*219b2ee8SDavid du Colombier break;
537*219b2ee8SDavid du Colombier
538*219b2ee8SDavid du Colombier case EXIT:
539*219b2ee8SDavid du Colombier formfeed();
540*219b2ee8SDavid du Colombier return;
541*219b2ee8SDavid du Colombier } /* End switch */
542*219b2ee8SDavid du Colombier
543*219b2ee8SDavid du Colombier } /* End of statemachine */
544*219b2ee8SDavid du Colombier
545*219b2ee8SDavid du Colombier /*****************************************************************************/
546*219b2ee8SDavid du Colombier
reset()547*219b2ee8SDavid du Colombier reset()
548*219b2ee8SDavid du Colombier
549*219b2ee8SDavid du Colombier {
550*219b2ee8SDavid du Colombier
551*219b2ee8SDavid du Colombier /*
552*219b2ee8SDavid du Colombier *
553*219b2ee8SDavid du Colombier * Called to reset things, typically only at the beginning of each input file.
554*219b2ee8SDavid du Colombier *
555*219b2ee8SDavid du Colombier */
556*219b2ee8SDavid du Colombier
557*219b2ee8SDavid du Colombier tekfont = -1;
558*219b2ee8SDavid du Colombier home();
559*219b2ee8SDavid du Colombier setfont(TEKFONT);
560*219b2ee8SDavid du Colombier setmode(ALPHA);
561*219b2ee8SDavid du Colombier
562*219b2ee8SDavid du Colombier } /* End of reset */
563*219b2ee8SDavid du Colombier
564*219b2ee8SDavid du Colombier /*****************************************************************************/
565*219b2ee8SDavid du Colombier
alpha()566*219b2ee8SDavid du Colombier alpha()
567*219b2ee8SDavid du Colombier
568*219b2ee8SDavid du Colombier {
569*219b2ee8SDavid du Colombier
570*219b2ee8SDavid du Colombier int c; /* next character */
571*219b2ee8SDavid du Colombier int x, y; /* cursor will be here when we're done */
572*219b2ee8SDavid du Colombier
573*219b2ee8SDavid du Colombier /*
574*219b2ee8SDavid du Colombier *
575*219b2ee8SDavid du Colombier * Takes care of printing characters in the current font.
576*219b2ee8SDavid du Colombier *
577*219b2ee8SDavid du Colombier */
578*219b2ee8SDavid du Colombier
579*219b2ee8SDavid du Colombier if ( (c = nextchar()) == OUTMODED )
580*219b2ee8SDavid du Colombier return;
581*219b2ee8SDavid du Colombier
582*219b2ee8SDavid du Colombier if ( (c < 040) && ((c = control(c)) <= 0) )
583*219b2ee8SDavid du Colombier return;
584*219b2ee8SDavid du Colombier
585*219b2ee8SDavid du Colombier x = cursor.x; /* where the cursor is right now */
586*219b2ee8SDavid du Colombier y = cursor.y;
587*219b2ee8SDavid du Colombier
588*219b2ee8SDavid du Colombier switch ( c ) {
589*219b2ee8SDavid du Colombier case DEL:
590*219b2ee8SDavid du Colombier return;
591*219b2ee8SDavid du Colombier
592*219b2ee8SDavid du Colombier case BS:
593*219b2ee8SDavid du Colombier if ((x -= charwidth[tekfont]) < margin)
594*219b2ee8SDavid du Colombier x = TEKXMAX - charwidth[tekfont];
595*219b2ee8SDavid du Colombier break;
596*219b2ee8SDavid du Colombier
597*219b2ee8SDavid du Colombier case NL:
598*219b2ee8SDavid du Colombier y -= charheight[tekfont];
599*219b2ee8SDavid du Colombier break;
600*219b2ee8SDavid du Colombier
601*219b2ee8SDavid du Colombier case CR:
602*219b2ee8SDavid du Colombier x = margin;
603*219b2ee8SDavid du Colombier break;
604*219b2ee8SDavid du Colombier
605*219b2ee8SDavid du Colombier case VT:
606*219b2ee8SDavid du Colombier if ((y += charheight[tekfont]) >= TEKYMAX)
607*219b2ee8SDavid du Colombier y = 0;
608*219b2ee8SDavid du Colombier break;
609*219b2ee8SDavid du Colombier
610*219b2ee8SDavid du Colombier case HT:
611*219b2ee8SDavid du Colombier case ' ':
612*219b2ee8SDavid du Colombier default:
613*219b2ee8SDavid du Colombier if ( characters++ == 0 )
614*219b2ee8SDavid du Colombier fprintf(fp_out, "%d %d (", cursor.x, cursor.y);
615*219b2ee8SDavid du Colombier switch ( c ) {
616*219b2ee8SDavid du Colombier case '(':
617*219b2ee8SDavid du Colombier case ')':
618*219b2ee8SDavid du Colombier case '\\':
619*219b2ee8SDavid du Colombier putc('\\', fp_out);
620*219b2ee8SDavid du Colombier
621*219b2ee8SDavid du Colombier default:
622*219b2ee8SDavid du Colombier putc(c, fp_out);
623*219b2ee8SDavid du Colombier } /* End switch */
624*219b2ee8SDavid du Colombier x += charwidth[tekfont];
625*219b2ee8SDavid du Colombier move(x, y);
626*219b2ee8SDavid du Colombier break;
627*219b2ee8SDavid du Colombier } /* End switch */
628*219b2ee8SDavid du Colombier
629*219b2ee8SDavid du Colombier if (x >= TEKXMAX) {
630*219b2ee8SDavid du Colombier x = margin;
631*219b2ee8SDavid du Colombier y -= charheight[tekfont];
632*219b2ee8SDavid du Colombier } /* End if */
633*219b2ee8SDavid du Colombier
634*219b2ee8SDavid du Colombier if (y < 0) {
635*219b2ee8SDavid du Colombier y = TEKYMAX - charheight[tekfont];
636*219b2ee8SDavid du Colombier x -= margin;
637*219b2ee8SDavid du Colombier margin = (TEKXMAX/2) - margin;
638*219b2ee8SDavid du Colombier if ((x += margin) > TEKXMAX)
639*219b2ee8SDavid du Colombier x -= margin;
640*219b2ee8SDavid du Colombier } /* End if */
641*219b2ee8SDavid du Colombier
642*219b2ee8SDavid du Colombier if ( y != cursor.y || x != cursor.x )
643*219b2ee8SDavid du Colombier text();
644*219b2ee8SDavid du Colombier
645*219b2ee8SDavid du Colombier move(x, y);
646*219b2ee8SDavid du Colombier
647*219b2ee8SDavid du Colombier } /* End of alpha */
648*219b2ee8SDavid du Colombier
649*219b2ee8SDavid du Colombier /*****************************************************************************/
650*219b2ee8SDavid du Colombier
graph()651*219b2ee8SDavid du Colombier graph()
652*219b2ee8SDavid du Colombier
653*219b2ee8SDavid du Colombier {
654*219b2ee8SDavid du Colombier
655*219b2ee8SDavid du Colombier int c; /* next character */
656*219b2ee8SDavid du Colombier int b; /* for figuring out loy */
657*219b2ee8SDavid du Colombier int x, y; /* next point in the vector */
658*219b2ee8SDavid du Colombier static int hix, hiy; /* upper */
659*219b2ee8SDavid du Colombier static int lox, loy; /* and lower part of the address */
660*219b2ee8SDavid du Colombier static int extra; /* for extended addressing */
661*219b2ee8SDavid du Colombier
662*219b2ee8SDavid du Colombier /*
663*219b2ee8SDavid du Colombier *
664*219b2ee8SDavid du Colombier * Handles things when we're in GRAPH, POINT, or SPECIALPOINT mode.
665*219b2ee8SDavid du Colombier *
666*219b2ee8SDavid du Colombier */
667*219b2ee8SDavid du Colombier
668*219b2ee8SDavid du Colombier if ((c = nextchar()) < 040) {
669*219b2ee8SDavid du Colombier control(c);
670*219b2ee8SDavid du Colombier return;
671*219b2ee8SDavid du Colombier } /* End if */
672*219b2ee8SDavid du Colombier
673*219b2ee8SDavid du Colombier if ((c & 0140) == 040) { /* new hiy */
674*219b2ee8SDavid du Colombier hiy = c & 037;
675*219b2ee8SDavid du Colombier do
676*219b2ee8SDavid du Colombier if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED))
677*219b2ee8SDavid du Colombier return;
678*219b2ee8SDavid du Colombier while (c == 0);
679*219b2ee8SDavid du Colombier } /* End if */
680*219b2ee8SDavid du Colombier
681*219b2ee8SDavid du Colombier if ((c & 0140) == 0140) { /* new loy */
682*219b2ee8SDavid du Colombier b = c & 037;
683*219b2ee8SDavid du Colombier do
684*219b2ee8SDavid du Colombier if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED))
685*219b2ee8SDavid du Colombier return;
686*219b2ee8SDavid du Colombier while (c == 0);
687*219b2ee8SDavid du Colombier if ((c & 0140) == 0140) { /* no, it was extra */
688*219b2ee8SDavid du Colombier extra = b;
689*219b2ee8SDavid du Colombier loy = c & 037;
690*219b2ee8SDavid du Colombier do
691*219b2ee8SDavid du Colombier if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED))
692*219b2ee8SDavid du Colombier return;
693*219b2ee8SDavid du Colombier while (c == 0);
694*219b2ee8SDavid du Colombier } else loy = b;
695*219b2ee8SDavid du Colombier } /* End if */
696*219b2ee8SDavid du Colombier
697*219b2ee8SDavid du Colombier if ((c & 0140) == 040) { /* new hix */
698*219b2ee8SDavid du Colombier hix = c & 037;
699*219b2ee8SDavid du Colombier do
700*219b2ee8SDavid du Colombier if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED))
701*219b2ee8SDavid du Colombier return;
702*219b2ee8SDavid du Colombier while (c == 0);
703*219b2ee8SDavid du Colombier } /* End if */
704*219b2ee8SDavid du Colombier
705*219b2ee8SDavid du Colombier lox = c & 037; /* this should be lox */
706*219b2ee8SDavid du Colombier if (extra & 020)
707*219b2ee8SDavid du Colombier margin = TEKXMAX/2;
708*219b2ee8SDavid du Colombier
709*219b2ee8SDavid du Colombier x = (hix<<7) | (lox<<2) | (extra & 03);
710*219b2ee8SDavid du Colombier y = (hiy<<7) | (loy<<2) | ((extra & 014)>>2);
711*219b2ee8SDavid du Colombier
712*219b2ee8SDavid du Colombier if ( points > 100 ) { /* don't put too much on the stack */
713*219b2ee8SDavid du Colombier draw();
714*219b2ee8SDavid du Colombier points = 1;
715*219b2ee8SDavid du Colombier } /* End if */
716*219b2ee8SDavid du Colombier
717*219b2ee8SDavid du Colombier if ( points++ )
718*219b2ee8SDavid du Colombier fprintf(fp_out, "%d %d\n", cursor.x - x, cursor.y - y);
719*219b2ee8SDavid du Colombier
720*219b2ee8SDavid du Colombier move(x, y); /* adjust the cursor */
721*219b2ee8SDavid du Colombier
722*219b2ee8SDavid du Colombier } /* End of graph */
723*219b2ee8SDavid du Colombier
724*219b2ee8SDavid du Colombier /*****************************************************************************/
725*219b2ee8SDavid du Colombier
point()726*219b2ee8SDavid du Colombier point()
727*219b2ee8SDavid du Colombier
728*219b2ee8SDavid du Colombier {
729*219b2ee8SDavid du Colombier
730*219b2ee8SDavid du Colombier int c; /* next input character */
731*219b2ee8SDavid du Colombier
732*219b2ee8SDavid du Colombier /*
733*219b2ee8SDavid du Colombier *
734*219b2ee8SDavid du Colombier * Special point mode permits gray scaling by varying the size of the stored
735*219b2ee8SDavid du Colombier * point, which is controlled by an intensity character that preceeds each point
736*219b2ee8SDavid du Colombier * address.
737*219b2ee8SDavid du Colombier *
738*219b2ee8SDavid du Colombier */
739*219b2ee8SDavid du Colombier
740*219b2ee8SDavid du Colombier if ( dispmode == SPECIALPOINT ) {
741*219b2ee8SDavid du Colombier if ( (c = nextchar()) < 040 || c > 0175 )
742*219b2ee8SDavid du Colombier return(control(c));
743*219b2ee8SDavid du Colombier
744*219b2ee8SDavid du Colombier fprintf(fp_out, "%d %d i\n", intensity[c - ' '], c & 0100);
745*219b2ee8SDavid du Colombier } /* End if */
746*219b2ee8SDavid du Colombier
747*219b2ee8SDavid du Colombier graph();
748*219b2ee8SDavid du Colombier draw();
749*219b2ee8SDavid du Colombier
750*219b2ee8SDavid du Colombier } /* End of point */
751*219b2ee8SDavid du Colombier
752*219b2ee8SDavid du Colombier /*****************************************************************************/
753*219b2ee8SDavid du Colombier
incremental()754*219b2ee8SDavid du Colombier incremental()
755*219b2ee8SDavid du Colombier
756*219b2ee8SDavid du Colombier {
757*219b2ee8SDavid du Colombier
758*219b2ee8SDavid du Colombier int c; /* for the next few characters */
759*219b2ee8SDavid du Colombier int x, y; /* cursor position when we're done */
760*219b2ee8SDavid du Colombier
761*219b2ee8SDavid du Colombier /*
762*219b2ee8SDavid du Colombier *
763*219b2ee8SDavid du Colombier * Handles incremental plot mode. It's entered after the RS control code and is
764*219b2ee8SDavid du Colombier * used to mark points relative to our current position. It's typically followed
765*219b2ee8SDavid du Colombier * by one or two bytes that set the pen state and are used to increment the
766*219b2ee8SDavid du Colombier * current position.
767*219b2ee8SDavid du Colombier *
768*219b2ee8SDavid du Colombier */
769*219b2ee8SDavid du Colombier
770*219b2ee8SDavid du Colombier if ( (c = nextchar()) == OUTMODED )
771*219b2ee8SDavid du Colombier return;
772*219b2ee8SDavid du Colombier
773*219b2ee8SDavid du Colombier if ( (c < 040) && ((c = control(c)) <= 0) )
774*219b2ee8SDavid du Colombier return;
775*219b2ee8SDavid du Colombier
776*219b2ee8SDavid du Colombier x = cursor.x; /* where we are right now */
777*219b2ee8SDavid du Colombier y = cursor.y;
778*219b2ee8SDavid du Colombier
779*219b2ee8SDavid du Colombier if ( c & 060 )
780*219b2ee8SDavid du Colombier pen = ( c & 040 ) ? UP : DOWN;
781*219b2ee8SDavid du Colombier
782*219b2ee8SDavid du Colombier if ( c & 04 ) y++;
783*219b2ee8SDavid du Colombier if ( c & 010 ) y--;
784*219b2ee8SDavid du Colombier if ( c & 01 ) x++;
785*219b2ee8SDavid du Colombier if ( c & 02 ) x--;
786*219b2ee8SDavid du Colombier
787*219b2ee8SDavid du Colombier move(x, y);
788*219b2ee8SDavid du Colombier
789*219b2ee8SDavid du Colombier if ( pen == DOWN ) {
790*219b2ee8SDavid du Colombier points = 1;
791*219b2ee8SDavid du Colombier draw();
792*219b2ee8SDavid du Colombier } /* End if */
793*219b2ee8SDavid du Colombier
794*219b2ee8SDavid du Colombier } /* End of incremental */
795*219b2ee8SDavid du Colombier
796*219b2ee8SDavid du Colombier /*****************************************************************************/
797*219b2ee8SDavid du Colombier
gin()798*219b2ee8SDavid du Colombier gin()
799*219b2ee8SDavid du Colombier
800*219b2ee8SDavid du Colombier {
801*219b2ee8SDavid du Colombier
802*219b2ee8SDavid du Colombier /*
803*219b2ee8SDavid du Colombier *
804*219b2ee8SDavid du Colombier * All we really have to do for GIN mode is make sure it's properly ended.
805*219b2ee8SDavid du Colombier *
806*219b2ee8SDavid du Colombier */
807*219b2ee8SDavid du Colombier
808*219b2ee8SDavid du Colombier control(nextchar());
809*219b2ee8SDavid du Colombier
810*219b2ee8SDavid du Colombier } /* End of gin */
811*219b2ee8SDavid du Colombier
812*219b2ee8SDavid du Colombier /*****************************************************************************/
813*219b2ee8SDavid du Colombier
control(c)814*219b2ee8SDavid du Colombier control(c)
815*219b2ee8SDavid du Colombier
816*219b2ee8SDavid du Colombier int c; /* check this control character */
817*219b2ee8SDavid du Colombier
818*219b2ee8SDavid du Colombier {
819*219b2ee8SDavid du Colombier
820*219b2ee8SDavid du Colombier /*
821*219b2ee8SDavid du Colombier *
822*219b2ee8SDavid du Colombier * Checks character c and does special things, like mode changes, that depend
823*219b2ee8SDavid du Colombier * not only on the character, but also on the current state. If the mode changed
824*219b2ee8SDavid du Colombier * becuase of c, OUTMODED is returned to the caller. In all other cases the
825*219b2ee8SDavid du Colombier * return value is c or 0, if c doesn't make sense in the current mode.
826*219b2ee8SDavid du Colombier *
827*219b2ee8SDavid du Colombier */
828*219b2ee8SDavid du Colombier
829*219b2ee8SDavid du Colombier switch ( c ) {
830*219b2ee8SDavid du Colombier case BEL:
831*219b2ee8SDavid du Colombier return(0);
832*219b2ee8SDavid du Colombier
833*219b2ee8SDavid du Colombier case BS:
834*219b2ee8SDavid du Colombier case HT:
835*219b2ee8SDavid du Colombier case VT:
836*219b2ee8SDavid du Colombier return(dispmode == ALPHA ? c : 0);
837*219b2ee8SDavid du Colombier
838*219b2ee8SDavid du Colombier case CR:
839*219b2ee8SDavid du Colombier if ( dispmode != ALPHA ) {
840*219b2ee8SDavid du Colombier setmode(ALPHA);
841*219b2ee8SDavid du Colombier ungetc(c, fp_in);
842*219b2ee8SDavid du Colombier return(OUTMODED);
843*219b2ee8SDavid du Colombier } else return(c);
844*219b2ee8SDavid du Colombier
845*219b2ee8SDavid du Colombier case FS:
846*219b2ee8SDavid du Colombier if ( (dispmode == ALPHA) || (dispmode == GRAPH) ) {
847*219b2ee8SDavid du Colombier setmode(POINT);
848*219b2ee8SDavid du Colombier return(OUTMODED);
849*219b2ee8SDavid du Colombier } /* End if */
850*219b2ee8SDavid du Colombier return(0);
851*219b2ee8SDavid du Colombier
852*219b2ee8SDavid du Colombier case GS:
853*219b2ee8SDavid du Colombier if ( (dispmode == ALPHA) || (dispmode == GRAPH) ) {
854*219b2ee8SDavid du Colombier setmode(GRAPH);
855*219b2ee8SDavid du Colombier return(OUTMODED);
856*219b2ee8SDavid du Colombier } /* End if */
857*219b2ee8SDavid du Colombier return(0);
858*219b2ee8SDavid du Colombier
859*219b2ee8SDavid du Colombier case NL:
860*219b2ee8SDavid du Colombier ungetc(CR, fp_in);
861*219b2ee8SDavid du Colombier return(dispmode == ALPHA ? c : 0);
862*219b2ee8SDavid du Colombier
863*219b2ee8SDavid du Colombier case RS:
864*219b2ee8SDavid du Colombier if ( dispmode != GIN ) {
865*219b2ee8SDavid du Colombier setmode(INCREMENTAL);
866*219b2ee8SDavid du Colombier return(OUTMODED);
867*219b2ee8SDavid du Colombier } /* End if */
868*219b2ee8SDavid du Colombier return(0);
869*219b2ee8SDavid du Colombier
870*219b2ee8SDavid du Colombier case US:
871*219b2ee8SDavid du Colombier if ( dispmode == ALPHA )
872*219b2ee8SDavid du Colombier return(0);
873*219b2ee8SDavid du Colombier setmode(ALPHA);
874*219b2ee8SDavid du Colombier return(OUTMODED);
875*219b2ee8SDavid du Colombier
876*219b2ee8SDavid du Colombier case ESC:
877*219b2ee8SDavid du Colombier return(esc());
878*219b2ee8SDavid du Colombier
879*219b2ee8SDavid du Colombier case OUTMODED:
880*219b2ee8SDavid du Colombier return(c);
881*219b2ee8SDavid du Colombier
882*219b2ee8SDavid du Colombier default:
883*219b2ee8SDavid du Colombier return(c < 040 ? 0 : c);
884*219b2ee8SDavid du Colombier } /* End switch */
885*219b2ee8SDavid du Colombier
886*219b2ee8SDavid du Colombier } /* End of control */
887*219b2ee8SDavid du Colombier
888*219b2ee8SDavid du Colombier /*****************************************************************************/
889*219b2ee8SDavid du Colombier
esc()890*219b2ee8SDavid du Colombier esc()
891*219b2ee8SDavid du Colombier
892*219b2ee8SDavid du Colombier {
893*219b2ee8SDavid du Colombier
894*219b2ee8SDavid du Colombier int c; /* next input character */
895*219b2ee8SDavid du Colombier int ignore; /* skip it if nonzero */
896*219b2ee8SDavid du Colombier
897*219b2ee8SDavid du Colombier /*
898*219b2ee8SDavid du Colombier *
899*219b2ee8SDavid du Colombier * Handles tektronix escape code. Called from control() whenever an ESC character
900*219b2ee8SDavid du Colombier * is found in the input file.
901*219b2ee8SDavid du Colombier *
902*219b2ee8SDavid du Colombier */
903*219b2ee8SDavid du Colombier
904*219b2ee8SDavid du Colombier do {
905*219b2ee8SDavid du Colombier c = nextchar();
906*219b2ee8SDavid du Colombier ignore = 0;
907*219b2ee8SDavid du Colombier switch ( c ) {
908*219b2ee8SDavid du Colombier case CAN:
909*219b2ee8SDavid du Colombier return(0);
910*219b2ee8SDavid du Colombier
911*219b2ee8SDavid du Colombier case CR:
912*219b2ee8SDavid du Colombier ignore = 1;
913*219b2ee8SDavid du Colombier break;
914*219b2ee8SDavid du Colombier
915*219b2ee8SDavid du Colombier case ENQ:
916*219b2ee8SDavid du Colombier setmode(ALPHA);
917*219b2ee8SDavid du Colombier return(OUTMODED);
918*219b2ee8SDavid du Colombier
919*219b2ee8SDavid du Colombier case ETB:
920*219b2ee8SDavid du Colombier return(0);
921*219b2ee8SDavid du Colombier
922*219b2ee8SDavid du Colombier case FF:
923*219b2ee8SDavid du Colombier formfeed();
924*219b2ee8SDavid du Colombier setmode(ALPHA);
925*219b2ee8SDavid du Colombier return(OUTMODED);
926*219b2ee8SDavid du Colombier
927*219b2ee8SDavid du Colombier case FS:
928*219b2ee8SDavid du Colombier if ( (dispmode == INCREMENTAL) || ( dispmode == GIN) )
929*219b2ee8SDavid du Colombier return(0);
930*219b2ee8SDavid du Colombier setmode(SPECIALPOINT);
931*219b2ee8SDavid du Colombier return(OUTMODED);
932*219b2ee8SDavid du Colombier
933*219b2ee8SDavid du Colombier case SI:
934*219b2ee8SDavid du Colombier case SO:
935*219b2ee8SDavid du Colombier return(0);
936*219b2ee8SDavid du Colombier
937*219b2ee8SDavid du Colombier case SUB:
938*219b2ee8SDavid du Colombier setmode(GIN);
939*219b2ee8SDavid du Colombier return(OUTMODED);
940*219b2ee8SDavid du Colombier
941*219b2ee8SDavid du Colombier case OUTMODED:
942*219b2ee8SDavid du Colombier return(OUTMODED);
943*219b2ee8SDavid du Colombier
944*219b2ee8SDavid du Colombier case '8':
945*219b2ee8SDavid du Colombier case '9':
946*219b2ee8SDavid du Colombier case ':':
947*219b2ee8SDavid du Colombier case ';':
948*219b2ee8SDavid du Colombier setfont(c - '8');
949*219b2ee8SDavid du Colombier return(0);
950*219b2ee8SDavid du Colombier
951*219b2ee8SDavid du Colombier default:
952*219b2ee8SDavid du Colombier if ( c == '?' && dispmode == GRAPH )
953*219b2ee8SDavid du Colombier return(DEL);
954*219b2ee8SDavid du Colombier if ( (c<'`') || (c>'w') )
955*219b2ee8SDavid du Colombier break;
956*219b2ee8SDavid du Colombier c -= '`';
957*219b2ee8SDavid du Colombier if ( (c & 010) != linetype )
958*219b2ee8SDavid du Colombier fprintf(fp_out, "%d w\n", (linetype = (c & 010))/010);
959*219b2ee8SDavid du Colombier if ( ((c + 1) & 7) >= 6 )
960*219b2ee8SDavid du Colombier break;
961*219b2ee8SDavid du Colombier if ( (c + 1) & 7 )
962*219b2ee8SDavid du Colombier if ( (c & 7) != linestyle ) {
963*219b2ee8SDavid du Colombier linestyle = c & 7;
964*219b2ee8SDavid du Colombier setmode(dispmode);
965*219b2ee8SDavid du Colombier fprintf(fp_out, "%s l\n", styles[linestyle]);
966*219b2ee8SDavid du Colombier } /* End if */
967*219b2ee8SDavid du Colombier return(0);
968*219b2ee8SDavid du Colombier } /* End switch */
969*219b2ee8SDavid du Colombier
970*219b2ee8SDavid du Colombier } while (ignore);
971*219b2ee8SDavid du Colombier
972*219b2ee8SDavid du Colombier return(0);
973*219b2ee8SDavid du Colombier
974*219b2ee8SDavid du Colombier } /* End of esc */
975*219b2ee8SDavid du Colombier
976*219b2ee8SDavid du Colombier /*****************************************************************************/
977*219b2ee8SDavid du Colombier
move(x,y)978*219b2ee8SDavid du Colombier move(x, y)
979*219b2ee8SDavid du Colombier
980*219b2ee8SDavid du Colombier int x, y; /* move the cursor here */
981*219b2ee8SDavid du Colombier
982*219b2ee8SDavid du Colombier {
983*219b2ee8SDavid du Colombier
984*219b2ee8SDavid du Colombier /*
985*219b2ee8SDavid du Colombier *
986*219b2ee8SDavid du Colombier * Moves the cursor to the point (x, y).
987*219b2ee8SDavid du Colombier *
988*219b2ee8SDavid du Colombier */
989*219b2ee8SDavid du Colombier
990*219b2ee8SDavid du Colombier cursor.x = x;
991*219b2ee8SDavid du Colombier cursor.y = y;
992*219b2ee8SDavid du Colombier
993*219b2ee8SDavid du Colombier } /* End of move */
994*219b2ee8SDavid du Colombier
995*219b2ee8SDavid du Colombier /*****************************************************************************/
996*219b2ee8SDavid du Colombier
setmode(mode)997*219b2ee8SDavid du Colombier setmode(mode)
998*219b2ee8SDavid du Colombier
999*219b2ee8SDavid du Colombier int mode; /* this should be the new mode */
1000*219b2ee8SDavid du Colombier
1001*219b2ee8SDavid du Colombier {
1002*219b2ee8SDavid du Colombier
1003*219b2ee8SDavid du Colombier /*
1004*219b2ee8SDavid du Colombier *
1005*219b2ee8SDavid du Colombier * Makes sure the current mode is properly ended and then sets dispmode to mode.
1006*219b2ee8SDavid du Colombier *
1007*219b2ee8SDavid du Colombier */
1008*219b2ee8SDavid du Colombier
1009*219b2ee8SDavid du Colombier switch ( dispmode ) {
1010*219b2ee8SDavid du Colombier case ALPHA:
1011*219b2ee8SDavid du Colombier text();
1012*219b2ee8SDavid du Colombier break;
1013*219b2ee8SDavid du Colombier
1014*219b2ee8SDavid du Colombier case GRAPH:
1015*219b2ee8SDavid du Colombier draw();
1016*219b2ee8SDavid du Colombier break;
1017*219b2ee8SDavid du Colombier
1018*219b2ee8SDavid du Colombier case INCREMENTAL:
1019*219b2ee8SDavid du Colombier pen = UP;
1020*219b2ee8SDavid du Colombier break;
1021*219b2ee8SDavid du Colombier } /* End switch */
1022*219b2ee8SDavid du Colombier
1023*219b2ee8SDavid du Colombier dispmode = mode;
1024*219b2ee8SDavid du Colombier
1025*219b2ee8SDavid du Colombier } /* End of setmode */
1026*219b2ee8SDavid du Colombier
1027*219b2ee8SDavid du Colombier /*****************************************************************************/
1028*219b2ee8SDavid du Colombier
home()1029*219b2ee8SDavid du Colombier home()
1030*219b2ee8SDavid du Colombier
1031*219b2ee8SDavid du Colombier {
1032*219b2ee8SDavid du Colombier
1033*219b2ee8SDavid du Colombier /*
1034*219b2ee8SDavid du Colombier *
1035*219b2ee8SDavid du Colombier * Makes sure the cursor is positioned at the upper left corner of the page.
1036*219b2ee8SDavid du Colombier *
1037*219b2ee8SDavid du Colombier */
1038*219b2ee8SDavid du Colombier
1039*219b2ee8SDavid du Colombier margin = 0;
1040*219b2ee8SDavid du Colombier move(0, TEKYMAX);
1041*219b2ee8SDavid du Colombier
1042*219b2ee8SDavid du Colombier } /* End of home */
1043*219b2ee8SDavid du Colombier
1044*219b2ee8SDavid du Colombier /*****************************************************************************/
1045*219b2ee8SDavid du Colombier
setfont(newfont)1046*219b2ee8SDavid du Colombier setfont(newfont)
1047*219b2ee8SDavid du Colombier
1048*219b2ee8SDavid du Colombier int newfont; /* use this font next */
1049*219b2ee8SDavid du Colombier
1050*219b2ee8SDavid du Colombier {
1051*219b2ee8SDavid du Colombier
1052*219b2ee8SDavid du Colombier /*
1053*219b2ee8SDavid du Colombier *
1054*219b2ee8SDavid du Colombier * Generates the call to the procedure that's responsible for changing the
1055*219b2ee8SDavid du Colombier * tektronix font (really just the size).
1056*219b2ee8SDavid du Colombier *
1057*219b2ee8SDavid du Colombier */
1058*219b2ee8SDavid du Colombier
1059*219b2ee8SDavid du Colombier if ( newfont != tekfont ) {
1060*219b2ee8SDavid du Colombier setmode(dispmode);
1061*219b2ee8SDavid du Colombier fprintf(fp_out, "%d f\n", charwidth[newfont]);
1062*219b2ee8SDavid du Colombier } /* End if */
1063*219b2ee8SDavid du Colombier
1064*219b2ee8SDavid du Colombier tekfont = newfont;
1065*219b2ee8SDavid du Colombier
1066*219b2ee8SDavid du Colombier } /* End of setfont */
1067*219b2ee8SDavid du Colombier
1068*219b2ee8SDavid du Colombier /*****************************************************************************/
1069*219b2ee8SDavid du Colombier
text()1070*219b2ee8SDavid du Colombier text()
1071*219b2ee8SDavid du Colombier
1072*219b2ee8SDavid du Colombier {
1073*219b2ee8SDavid du Colombier
1074*219b2ee8SDavid du Colombier /*
1075*219b2ee8SDavid du Colombier *
1076*219b2ee8SDavid du Colombier * Makes sure any text we've put on the stack is printed.
1077*219b2ee8SDavid du Colombier *
1078*219b2ee8SDavid du Colombier */
1079*219b2ee8SDavid du Colombier
1080*219b2ee8SDavid du Colombier if ( dispmode == ALPHA && characters > 0 )
1081*219b2ee8SDavid du Colombier fprintf(fp_out, ") t\n");
1082*219b2ee8SDavid du Colombier
1083*219b2ee8SDavid du Colombier characters = 0;
1084*219b2ee8SDavid du Colombier
1085*219b2ee8SDavid du Colombier } /* End of text */
1086*219b2ee8SDavid du Colombier
1087*219b2ee8SDavid du Colombier /*****************************************************************************/
1088*219b2ee8SDavid du Colombier
draw()1089*219b2ee8SDavid du Colombier draw()
1090*219b2ee8SDavid du Colombier
1091*219b2ee8SDavid du Colombier {
1092*219b2ee8SDavid du Colombier
1093*219b2ee8SDavid du Colombier /*
1094*219b2ee8SDavid du Colombier *
1095*219b2ee8SDavid du Colombier * Called whenever we need to draw a vector or plot a point. Nothing will be
1096*219b2ee8SDavid du Colombier * done if points is 0 or if it's 1 and we're in GRAPH mode.
1097*219b2ee8SDavid du Colombier *
1098*219b2ee8SDavid du Colombier */
1099*219b2ee8SDavid du Colombier
1100*219b2ee8SDavid du Colombier if ( points > 1 ) /* it's a vector */
1101*219b2ee8SDavid du Colombier fprintf(fp_out, "%d %d v\n", cursor.x, cursor.y);
1102*219b2ee8SDavid du Colombier else if ( points == 1 && dispmode != GRAPH )
1103*219b2ee8SDavid du Colombier fprintf(fp_out, "%d %d p\n", cursor.x, cursor.y);
1104*219b2ee8SDavid du Colombier
1105*219b2ee8SDavid du Colombier points = 0;
1106*219b2ee8SDavid du Colombier
1107*219b2ee8SDavid du Colombier } /* End of draw */
1108*219b2ee8SDavid du Colombier
1109*219b2ee8SDavid du Colombier /*****************************************************************************/
1110*219b2ee8SDavid du Colombier
formfeed()1111*219b2ee8SDavid du Colombier formfeed()
1112*219b2ee8SDavid du Colombier
1113*219b2ee8SDavid du Colombier {
1114*219b2ee8SDavid du Colombier
1115*219b2ee8SDavid du Colombier /*
1116*219b2ee8SDavid du Colombier *
1117*219b2ee8SDavid du Colombier * Usually called when we've finished the last page and want to get ready for the
1118*219b2ee8SDavid du Colombier * next one. Also used at the beginning and end of each input file, so we have to
1119*219b2ee8SDavid du Colombier * be careful about exactly what's done.
1120*219b2ee8SDavid du Colombier *
1121*219b2ee8SDavid du Colombier */
1122*219b2ee8SDavid du Colombier
1123*219b2ee8SDavid du Colombier setmode(dispmode); /* end any outstanding text or graphics */
1124*219b2ee8SDavid du Colombier
1125*219b2ee8SDavid du Colombier if ( fp_out == stdout ) /* count the last page */
1126*219b2ee8SDavid du Colombier printed++;
1127*219b2ee8SDavid du Colombier
1128*219b2ee8SDavid du Colombier fprintf(fp_out, "cleartomark\n");
1129*219b2ee8SDavid du Colombier fprintf(fp_out, "showpage\n");
1130*219b2ee8SDavid du Colombier fprintf(fp_out, "saveobj restore\n");
1131*219b2ee8SDavid du Colombier fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed);
1132*219b2ee8SDavid du Colombier
1133*219b2ee8SDavid du Colombier if ( ungetc(getc(fp_in), fp_in) == EOF )
1134*219b2ee8SDavid du Colombier redirect(-1);
1135*219b2ee8SDavid du Colombier else redirect(++page);
1136*219b2ee8SDavid du Colombier
1137*219b2ee8SDavid du Colombier fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1);
1138*219b2ee8SDavid du Colombier fprintf(fp_out, "/saveobj save def\n");
1139*219b2ee8SDavid du Colombier fprintf(fp_out, "mark\n");
1140*219b2ee8SDavid du Colombier writerequest(printed+1, fp_out);
1141*219b2ee8SDavid du Colombier fprintf(fp_out, "%d pagesetup\n", printed+1);
1142*219b2ee8SDavid du Colombier fprintf(fp_out, "%d f\n", charwidth[tekfont]);
1143*219b2ee8SDavid du Colombier fprintf(fp_out, "%s l\n", styles[linestyle]);
1144*219b2ee8SDavid du Colombier
1145*219b2ee8SDavid du Colombier home();
1146*219b2ee8SDavid du Colombier
1147*219b2ee8SDavid du Colombier } /* End of formfeed */
1148*219b2ee8SDavid du Colombier
1149*219b2ee8SDavid du Colombier /*****************************************************************************/
1150*219b2ee8SDavid du Colombier
nextchar()1151*219b2ee8SDavid du Colombier nextchar()
1152*219b2ee8SDavid du Colombier
1153*219b2ee8SDavid du Colombier {
1154*219b2ee8SDavid du Colombier
1155*219b2ee8SDavid du Colombier int ch; /* next input character */
1156*219b2ee8SDavid du Colombier
1157*219b2ee8SDavid du Colombier /*
1158*219b2ee8SDavid du Colombier *
1159*219b2ee8SDavid du Colombier * Reads the next character from the current input file and returns it to the
1160*219b2ee8SDavid du Colombier * caller. When we're finished with the file dispmode is set to EXIT and OUTMODED
1161*219b2ee8SDavid du Colombier * is returned to the caller.
1162*219b2ee8SDavid du Colombier *
1163*219b2ee8SDavid du Colombier */
1164*219b2ee8SDavid du Colombier
1165*219b2ee8SDavid du Colombier if ( (ch = getc(fp_in)) == EOF ) {
1166*219b2ee8SDavid du Colombier setmode(EXIT);
1167*219b2ee8SDavid du Colombier ch = OUTMODED;
1168*219b2ee8SDavid du Colombier } /* End if */
1169*219b2ee8SDavid du Colombier
1170*219b2ee8SDavid du Colombier return(ch);
1171*219b2ee8SDavid du Colombier
1172*219b2ee8SDavid du Colombier } /* End of nextchar */
1173*219b2ee8SDavid du Colombier
1174*219b2ee8SDavid du Colombier /*****************************************************************************/
1175*219b2ee8SDavid du Colombier
redirect(pg)1176*219b2ee8SDavid du Colombier redirect(pg)
1177*219b2ee8SDavid du Colombier
1178*219b2ee8SDavid du Colombier int pg; /* next page we're printing */
1179*219b2ee8SDavid du Colombier
1180*219b2ee8SDavid du Colombier {
1181*219b2ee8SDavid du Colombier
1182*219b2ee8SDavid du Colombier static FILE *fp_null = NULL; /* if output is turned off */
1183*219b2ee8SDavid du Colombier
1184*219b2ee8SDavid du Colombier /*
1185*219b2ee8SDavid du Colombier *
1186*219b2ee8SDavid du Colombier * If we're not supposed to print page pg, fp_out will be directed to /dev/null,
1187*219b2ee8SDavid du Colombier * otherwise output goes to stdout.
1188*219b2ee8SDavid du Colombier *
1189*219b2ee8SDavid du Colombier */
1190*219b2ee8SDavid du Colombier
1191*219b2ee8SDavid du Colombier if ( pg >= 0 && in_olist(pg) == ON )
1192*219b2ee8SDavid du Colombier fp_out = stdout;
1193*219b2ee8SDavid du Colombier else if ( (fp_out = fp_null) == NULL )
1194*219b2ee8SDavid du Colombier fp_out = fp_null = fopen("/dev/null", "w");
1195*219b2ee8SDavid du Colombier
1196*219b2ee8SDavid du Colombier } /* End of redirect */
1197*219b2ee8SDavid du Colombier
1198*219b2ee8SDavid du Colombier /*****************************************************************************/
1199*219b2ee8SDavid du Colombier
1200