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