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