BSD 4 development
[unix-history] / usr / src / cmd / vpr / rvsort.c
CommitLineData
0d808062
BJ
1# include <stdio.h>
2/*
3 * vsort - Sort troff output for versatec to reduce amount of reverse leading
4 */
5
6#define NULL 0
7
8double atof();
9char *calloc();
10
11FILE *in,*out;
12
13struct achar *piles[500], *afreel;
14
15int skipfirst = 1; /* skip the first leading so start at top of page */
16int cpsize = 02; /* Funny sizes */
17struct point_sizes {
18 int stupid_code;
19 int real_code;
20} point_sizes[] = {
21 010, 6,
22 0, 7,
23 01, 8,
24 07, 9,
25 02, 10,
26 03, 11,
27 04, 12,
28 05, 14,
29 0211, 16,
30 06, 18,
31 0212, 20,
32 0213, 22,
33 0214, 24,
34 0215, 28,
35 0216, 36,
36 0, 0
37};
38
39int pagelength = 144 * 11; /* in Leading units */
40int pagemod; /* horizontal page number (for versatec) */
41#define MODOFF 3672 /* 432 * 8.5 */
42
43int esc, lead, back, verd, mcase, railmag;
44int col, row;
45
46int oback, omcase, orailmag, ocol, orow, overd;
47int opsize = 02;
48
49struct achar
50{
51 char code;
52 char psize;
53 short col;
54 short row;
55 char railmag;
56 char verd;
57 char back;
58 char mcase;
59 struct achar *next;
60};
61
62main(argc, argv)
63 int argc;
64 char *argv[];
65{
66 register i;
67
68 for(i = 3; i < 15; i++)
69 close(i);
70 while (argc > 1 && argv[1][0] == '-') {
71 switch (argv[1][1]) {
72 case 'l': {
73 float f = 144 * atof(argv[1] + 2);
74 if (f < 144) {
75 error("bad length");
76 exit(1);
77 }
78 pagelength = f;
79 break;
80 }
81 }
82 argc--; argv++;
83 }
84 out = stdout;
85 if(argc > 1) {
86 while(--argc) {
87 argv++;
88 if((in=fopen(argv[0], "r")) == NULL)
89 perror("vsort");
90 else {
91 ofile();
92 fclose(in);
93 }
94 }
95 } else {
96 in = stdin;
97 ofile();
98 }
99 exit(0);
100}
101
102ofile()
103{
104 register int c;
105 static int initialized;
106
107 while((c = getch()) != -1) {
108 if(!c)
109 continue;
110 if(c & 0200) { /* escape (left/right) */
111 esc += (~c) & 0177;
112 continue;
113 }
114 if(esc) {
115 if(back)
116 esc = -esc;
117 col += esc;
118 esc = 0;
119 }
120 if((c & 0377) < 0100) /* Purely for efficiency */
121 goto normal_char;
122 switch(c) {
123
124 case 0100:
125 if(initialized++) {
126 linesflush();
127 return;
128 }
129 row = 0;
130 col = 0; esc = 0;
131 lead = 0;
132 verd = 0; back = 0; mcase = 0;
133 railmag = 0;
134 ocol = 0;
135 orow = 0;
136 oback = 0; omcase = 0;
137 orailmag = 0;
138 if(loadfont(railmag, cpsize) < 0)
139 error("init");
140 putc(0100, out);
141 break;
142
143 case 0101: /* lower rail */
144 crail(railmag &= ~01);
145 break;
146
147 case 0102: /* upper rail */
148 crail(railmag |= 01);
149 break;
150
151 case 0103: /* upper mag */
152 crail(railmag |= 02);
153 break;
154
155 case 0104: /* lower mag */
156 crail(railmag &= ~02);
157 break;
158
159 case 0105: /* lower case */
160 mcase = 0;
161 break;
162
163 case 0106: /* upper case */
164 mcase = 1;
165 break;
166
167 case 0107: /* escape forward */
168 back = 0;
169 break;
170
171 case 0110: /* escape backwards */
172 back = 1;
173 break;
174
175 case 0111: /* stop */
176 break;
177
178 case 0112: /* lead forward */
179 verd = 0;
180 break;
181
182 case 0113: /* undefined */
183 break;
184
185 case 0114: /* lead backward */
186 verd = 1;
187 break;
188
189 case 0115: /* undefined */
190 case 0116:
191 case 0117:
192 break;
193
194 default:
195 if((c & 0340) == 0140) {/* leading */
196 lead = (~c) & 037;
197 if(verd)
198 lead = -lead;
199 if (skipfirst > 0) {
200 skipfirst--;
201 continue;
202 }
203 row += lead;
204 if (row >= pagelength)
205 allflush();
206 continue;
207 }
208 if((c & 0360)== 0120) { /* size change */
209 col += stupidadj(c & 017, cpsize);
210 loadfont(railmag, c & 017);
211 continue;
212 }
213 if(c & 0300)
214 continue;
215 normal_char:
216 c = (c & 077);
217 stuffc(c);
218 }
219 }
220 linesflush();
221 putc(0111, out);
222 putc(0111, out);
223 putc(0111, out);
224 putc(0111, out);
225 putc(0111, out);
226 putc(0111, out);
227 putc(0111, out);
228 putc(0111, out);
229}
230
231int peekc;
232
233getch()
234{
235 register c;
236
237 if(peekc) {
238 c = peekc;
239 peekc = 0;
240 return(c);
241 }
242 return(getc(in));
243}
244
245ungetc(c)
246{
247 peekc = c;
248}
249
250error(s)
251 char *s;
252{
253
254 fflush(out);
255 fprintf(stderr, "vsort: %s\n", s);
256}
257
258crail(nrail)
259 int nrail;
260{
261
262 railmag = nrail;
263 loadfont(nrail, cpsize);
264}
265
266loadfont(fnum, size)
267 int fnum;
268 int size;
269{
270
271 cpsize = size;
272 return(0);
273}
274
275stuffc(code)
276 register int code;
277{
278 register struct achar *ap, **bp;
279
280 if (col < 0 || col >= 500*8)
281 return;
282 if (afreel) {
283 ap = afreel;
284 afreel = ap->next;
285 } else
286 ap = (struct achar *)malloc(sizeof (*ap));
287 ap->row = row;
288 ap->col = col;
289 ap->psize = cpsize;
290 ap->verd = verd;
291 ap->back = back;
292 ap->mcase = mcase;
293 ap->code = code;
294 ap->railmag = railmag;
295 bp = &piles[col / 8];
296 ap->next = *bp;
297 *bp = ap;
298}
299
300allflush()
301{
302
303 linesflush();
304 if (row > orow)
305 ptlead(row - orow);
306 row -= pagelength;
307 orow = row;
308}
309
310
311linesflush()
312{
313 register struct achar **ap, *bp, *cp;
314 static notfirst;
315
316 if (notfirst)
317 putc(0115, out);
318 orow = 0;
319 ocol = 0;
320 notfirst = 1;
321 for (ap = &piles[0]; ap < &piles[500]; ap++) {
322 for (bp = *ap; bp; bp = cp) {
323 sendchar(bp);
324 cp = bp->next;
325 bp->next = afreel;
326 afreel = bp;
327 }
328 *ap = 0;
329 }
330}
331
332sendchar(cp)
333 register struct achar *cp;
334{
335 register int i;
336
337#ifdef DUMPCHAR
338 dumpchar(cp);
339#endif
340 if(cp->railmag != orailmag)
341 ptrail(cp->railmag);
342 if(cp->psize != opsize)
343 ptsize(cp->psize);
344 if(cp->mcase != omcase)
345 ptmcase();
346 if(cp->row != orow)
347 ptlead(cp->row - orow);
348 if(cp->col != ocol)
349 ptesc(cp->col - ocol);
350 if(cp->back != oback)
351 ptback();
352 putc(cp->code, out);
353 orow = cp->row;
354 orailmag = cp->railmag;
355 opsize = cp->psize;
356 omcase = cp->mcase;
357 ocol = cp->col;
358 oback = cp->back;
359}
360
361ptrail(rlmg)
362 register int rlmg;
363{
364
365 if((rlmg & 01) != (orailmag & 01))
366 putc((rlmg & 01) ? 0102:0101, out); /* rail */
367 if((rlmg & 02) != (orailmag & 02))
368 putc((rlmg & 02) ? 0103:0104, out); /* mag */
369}
370
371ptback()
372{
373
374 putc(oback ? 0107:0110, out);
375 oback = !oback;
376}
377
378ptsize(size)
379 register int size;
380{
381
382 putc(0120 | (size & 017), out);
383 ptesc(-stupidadj(size, opsize));
384}
385
386stupidadj(code, lcode)
387 register int code;
388 int lcode;
389{
390 register struct point_sizes *psp;
391 register struct point_sizes *lpsp;
392
393 psp = point_sizes;
394 while(psp->real_code != 0) {
395 if((psp->stupid_code & 017) == code)
396 break;
397 psp++;
398 }
399 lpsp = point_sizes;
400 while(lpsp->real_code != 0) {
401 if((lpsp->stupid_code & 017) == lcode)
402 break;
403 lpsp++;
404 }
405 code = 0;
406 if(!(lpsp->stupid_code & 0200) && (psp->stupid_code & 0200))
407 code = -55;
408 else
409 if((lpsp->stupid_code & 0200) && !(psp->stupid_code & 0200))
410 code = 55;
411 return(code);
412}
413
414ptmcase()
415{
416
417 putc(omcase ? 0105:0106, out);
418}
419
420ptesc(escc)
421 register int escc;
422{
423
424 if((escc < 0 && !oback ) || (escc >= 0 && oback))
425 ptback();
426 escc = abs(escc);
427 while(escc > 0177) {
428 putc(0200, out);
429 escc -= 0177;
430 }
431 if(escc)
432 putc(0200 | ((~escc) & 0177), out);
433}
434
435ptlead(leadd)
436 register int leadd;
437{
438
439 if (leadd == 0)
440 return;
441 if (leadd < 0) {
442 if (overd == 0)
443 putc(0114, out), overd = 1;
444 leadd = -leadd;
445 } else {
446 if (overd)
447 putc(0112, out), overd = 0;
448 }
449 if (leadd > 64) {
450 putc(0116, out);
451 putc(leadd / 64, out);
452 leadd %= 64;
453 }
454 while (leadd > 037) {
455 putc(0140, out);
456 leadd -= 037;
457 }
458 if (leadd)
459 putc(0140 | ((~leadd) & 037), out);
460}
461
462#ifdef DUMPLINE
463dumpchar(cp)
464register struct achar *cp;
465{
466
467 fprintf(stderr,
468"code %o psize %d col %d row %d railmag %d verd %d back %d mcase %d\n",
469 cp->code, cp->psize, cp->col, cp->row, cp->railmag, cp->verd,
470 cp->back, cp->mcase);
471}
472#endif