xref: /original-bsd/old/vfilters/rvsort/rvsort.c (revision e2b66ddc)
18e8eab7dSdist /*
28e8eab7dSdist  * Copyright (c) 1983 Regents of the University of California.
33fcb57bbSbostic  * All rights reserved.
43fcb57bbSbostic  *
53c9ee3e7Sbostic  * %sccs.include.redist.c%
68e8eab7dSdist  */
78e8eab7dSdist 
8a4859cf4Ssam #ifndef lint
93fcb57bbSbostic char copyright[] =
103fcb57bbSbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\
113fcb57bbSbostic  All rights reserved.\n";
123fcb57bbSbostic #endif /* not lint */
133fcb57bbSbostic 
143fcb57bbSbostic #ifndef lint
15*e2b66ddcSbostic static char sccsid[] = "@(#)rvsort.c	5.5 (Berkeley) 03/02/91";
163fcb57bbSbostic #endif /* not lint */
17a4859cf4Ssam 
18079f2f8eSroot /*
19079f2f8eSroot  * Sort troff output for versatec to reduce amount of reverse leading
20079f2f8eSroot  */
21079f2f8eSroot 
22079f2f8eSroot # include <stdio.h>
23079f2f8eSroot 
24079f2f8eSroot #define NULL 0
25079f2f8eSroot 
26079f2f8eSroot double atof();
27079f2f8eSroot char *calloc();
28079f2f8eSroot 
29079f2f8eSroot FILE *in,*out;
30079f2f8eSroot 
31079f2f8eSroot struct achar *piles[500], *afreel;
32079f2f8eSroot 
33079f2f8eSroot int skipfirst = 1;	/* skip the first leading so start at top of page */
34079f2f8eSroot int cpsize = 02;	/*  Funny sizes  */
35079f2f8eSroot struct point_sizes {
36079f2f8eSroot 	int stupid_code;
37079f2f8eSroot 	int real_code;
38079f2f8eSroot } point_sizes[] = {
39079f2f8eSroot 	010, 6,
40079f2f8eSroot 	0, 7,
41079f2f8eSroot 	01, 8,
42079f2f8eSroot 	07, 9,
43079f2f8eSroot 	02, 10,
44079f2f8eSroot 	03, 11,
45079f2f8eSroot 	04, 12,
46079f2f8eSroot 	05, 14,
47079f2f8eSroot 	0211, 16,
48079f2f8eSroot 	06, 18,
49079f2f8eSroot 	0212, 20,
50079f2f8eSroot 	0213, 22,
51079f2f8eSroot 	0214, 24,
52079f2f8eSroot 	0215, 28,
53079f2f8eSroot 	0216, 36,
54079f2f8eSroot 	0, 0
55079f2f8eSroot };
56079f2f8eSroot 
57079f2f8eSroot int	pagelength = 144 * 11;	/* in Leading units */
58079f2f8eSroot int	pagemod;		/* horizontal page number (for versatec) */
59079f2f8eSroot #define	MODOFF 3672		/* 432 * 8.5 */
60079f2f8eSroot 
61079f2f8eSroot int	esc, lead, back, verd, mcase, railmag;
62079f2f8eSroot int	col, row;
63079f2f8eSroot 
64079f2f8eSroot int	oback, omcase, orailmag, ocol, orow, overd;
65079f2f8eSroot int	opsize = 02;
66079f2f8eSroot 
67079f2f8eSroot struct	achar
68079f2f8eSroot {
69079f2f8eSroot 	char	code;
70079f2f8eSroot 	char	psize;
71079f2f8eSroot 	short	col;
72079f2f8eSroot 	short	row;
73079f2f8eSroot 	char	railmag;
74079f2f8eSroot 	char	verd;
75079f2f8eSroot 	char	back;
76079f2f8eSroot 	char	mcase;
77079f2f8eSroot 	struct	achar *next;
78079f2f8eSroot };
79079f2f8eSroot 
main(argc,argv)80079f2f8eSroot main(argc, argv)
81079f2f8eSroot 	int argc;
82079f2f8eSroot 	char *argv[];
83079f2f8eSroot {
84079f2f8eSroot 	register i;
85079f2f8eSroot 
86079f2f8eSroot 	for(i = 3; i < 15; i++)
87079f2f8eSroot 		close(i);
88079f2f8eSroot 	while (argc > 1 && argv[1][0] == '-') {
89079f2f8eSroot 		switch (argv[1][1]) {
90079f2f8eSroot 			case 'l': {
91079f2f8eSroot 				float f = 144 * atof(argv[1] + 2);
92079f2f8eSroot 				if (f < 144) {
93079f2f8eSroot 					error("bad length");
94079f2f8eSroot 					exit(1);
95079f2f8eSroot 				}
96079f2f8eSroot 				pagelength = f;
97079f2f8eSroot 				break;
98079f2f8eSroot 			}
99079f2f8eSroot 		}
100079f2f8eSroot 		argc--; argv++;
101079f2f8eSroot 	}
102079f2f8eSroot 	out = stdout;
103079f2f8eSroot 	if(argc > 1) {
104079f2f8eSroot 		while(--argc) {
105079f2f8eSroot 			argv++;
106079f2f8eSroot 			if((in=fopen(argv[0], "r")) == NULL)
107079f2f8eSroot 				perror("vsort");
108079f2f8eSroot 			else {
109079f2f8eSroot 				ofile();
110079f2f8eSroot 				fclose(in);
111079f2f8eSroot 			}
112079f2f8eSroot 		}
113079f2f8eSroot 	} else {
114079f2f8eSroot 		in = stdin;
115079f2f8eSroot 		ofile();
116079f2f8eSroot 	}
117079f2f8eSroot 	exit(0);
118079f2f8eSroot }
119079f2f8eSroot 
ofile()120079f2f8eSroot ofile()
121079f2f8eSroot {
122079f2f8eSroot 	register int c;
123079f2f8eSroot 	static int initialized;
124079f2f8eSroot 
125079f2f8eSroot 	while((c = getch()) != -1) {
126079f2f8eSroot 		if(!c)
127079f2f8eSroot 			continue;
128079f2f8eSroot 		if(c & 0200) {		/* escape (left/right) */
129079f2f8eSroot 			esc += (~c) & 0177;
130079f2f8eSroot 			continue;
131079f2f8eSroot 		}
132079f2f8eSroot 		if(esc) {
133079f2f8eSroot 			if(back)
134079f2f8eSroot 				esc = -esc;
135079f2f8eSroot 			col += esc;
136079f2f8eSroot 			esc = 0;
137079f2f8eSroot 		}
138079f2f8eSroot 		if((c & 0377) < 0100)	/*  Purely for efficiency  */
139079f2f8eSroot 			goto normal_char;
140079f2f8eSroot 		switch(c) {
141079f2f8eSroot 
142079f2f8eSroot 		case 0100:
143079f2f8eSroot 			if(initialized++) {
144079f2f8eSroot 				linesflush();
145079f2f8eSroot 				return;
146079f2f8eSroot 			}
147079f2f8eSroot 			row = 0;
148079f2f8eSroot 			col = 0;	esc = 0;
149079f2f8eSroot 			lead = 0;
150079f2f8eSroot 			verd = 0;	back = 0;	mcase = 0;
151079f2f8eSroot 			railmag = 0;
152079f2f8eSroot 			ocol = 0;
153079f2f8eSroot 			orow = 0;
154079f2f8eSroot 			oback = 0;	omcase = 0;
155079f2f8eSroot 			orailmag = 0;
156079f2f8eSroot 			if(loadfont(railmag, cpsize) < 0)
157079f2f8eSroot 				error("init");
158079f2f8eSroot 			putc(0100, out);
159079f2f8eSroot 			break;
160079f2f8eSroot 
161079f2f8eSroot 		case 0101:	/* lower rail */
162079f2f8eSroot 			crail(railmag &= ~01);
163079f2f8eSroot 			break;
164079f2f8eSroot 
165079f2f8eSroot 		case 0102:	/* upper rail */
166079f2f8eSroot 			crail(railmag |= 01);
167079f2f8eSroot 			break;
168079f2f8eSroot 
169079f2f8eSroot 		case 0103:	/* upper mag */
170079f2f8eSroot 			crail(railmag |= 02);
171079f2f8eSroot 			break;
172079f2f8eSroot 
173079f2f8eSroot 		case 0104:	/* lower mag */
174079f2f8eSroot 			crail(railmag &= ~02);
175079f2f8eSroot 			break;
176079f2f8eSroot 
177079f2f8eSroot 		case 0105:	/* lower case */
178079f2f8eSroot 			mcase = 0;
179079f2f8eSroot 			break;
180079f2f8eSroot 
181079f2f8eSroot 		case 0106:	/* upper case */
182079f2f8eSroot 			mcase = 1;
183079f2f8eSroot 			break;
184079f2f8eSroot 
185079f2f8eSroot 		case 0107:	/* escape forward */
186079f2f8eSroot 			back = 0;
187079f2f8eSroot 			break;
188079f2f8eSroot 
189079f2f8eSroot 		case 0110:	/* escape backwards */
190079f2f8eSroot 			back = 1;
191079f2f8eSroot 			break;
192079f2f8eSroot 
193079f2f8eSroot 		case 0111:	/* stop */
194079f2f8eSroot 			break;
195079f2f8eSroot 
196079f2f8eSroot 		case 0112:	/* lead forward */
197079f2f8eSroot 			verd = 0;
198079f2f8eSroot 			break;
199079f2f8eSroot 
200079f2f8eSroot 		case 0113:	/* undefined */
201079f2f8eSroot 			break;
202079f2f8eSroot 
203079f2f8eSroot 		case 0114:	/* lead backward */
204079f2f8eSroot 			verd = 1;
205079f2f8eSroot 			break;
206079f2f8eSroot 
207079f2f8eSroot 		case 0115:	/* undefined */
208079f2f8eSroot 		case 0116:
209079f2f8eSroot 		case 0117:
210079f2f8eSroot 			break;
211079f2f8eSroot 
212079f2f8eSroot 		default:
213079f2f8eSroot 			if((c & 0340) == 0140) {/* leading */
214079f2f8eSroot 				lead = (~c) & 037;
215079f2f8eSroot 				if(verd)
216079f2f8eSroot 					lead = -lead;
217079f2f8eSroot 				if (skipfirst > 0) {
218079f2f8eSroot 					skipfirst--;
219079f2f8eSroot 					continue;
220079f2f8eSroot 				}
221079f2f8eSroot 				row += lead;
222079f2f8eSroot 				if (row >= pagelength)
223079f2f8eSroot 					allflush();
224079f2f8eSroot 				continue;
225079f2f8eSroot 			}
226079f2f8eSroot 			if((c & 0360)== 0120) {	/* size change */
227079f2f8eSroot 				col += stupidadj(c & 017, cpsize);
228079f2f8eSroot 				loadfont(railmag, c & 017);
229079f2f8eSroot 				continue;
230079f2f8eSroot 			}
231079f2f8eSroot 			if(c & 0300)
232079f2f8eSroot 				continue;
233079f2f8eSroot 		normal_char:
234079f2f8eSroot 			c = (c & 077);
235079f2f8eSroot 			stuffc(c);
236079f2f8eSroot 		}
237079f2f8eSroot 	}
238079f2f8eSroot 	linesflush();
239079f2f8eSroot 	putc(0111, out);
240079f2f8eSroot 	putc(0111, out);
241079f2f8eSroot 	putc(0111, out);
242079f2f8eSroot 	putc(0111, out);
243079f2f8eSroot 	putc(0111, out);
244079f2f8eSroot 	putc(0111, out);
245079f2f8eSroot 	putc(0111, out);
246079f2f8eSroot 	putc(0111, out);
247079f2f8eSroot }
248079f2f8eSroot 
249079f2f8eSroot int	peekc;
250079f2f8eSroot 
getch()251079f2f8eSroot getch()
252079f2f8eSroot {
253079f2f8eSroot 	register c;
254079f2f8eSroot 
255079f2f8eSroot 	if(peekc) {
256079f2f8eSroot 		c = peekc;
257079f2f8eSroot 		peekc = 0;
258079f2f8eSroot 		return(c);
259079f2f8eSroot 	}
260079f2f8eSroot 	return(getc(in));
261079f2f8eSroot }
262079f2f8eSroot 
error(s)263079f2f8eSroot error(s)
264079f2f8eSroot 	char *s;
265079f2f8eSroot {
266079f2f8eSroot 
267079f2f8eSroot 	fflush(out);
268079f2f8eSroot 	fprintf(stderr, "vsort: %s\n", s);
269079f2f8eSroot }
270079f2f8eSroot 
crail(nrail)271079f2f8eSroot crail(nrail)
272079f2f8eSroot 	int nrail;
273079f2f8eSroot {
274079f2f8eSroot 
275079f2f8eSroot 	railmag = nrail;
276079f2f8eSroot 	loadfont(nrail, cpsize);
277079f2f8eSroot }
278079f2f8eSroot 
loadfont(fnum,size)279079f2f8eSroot loadfont(fnum, size)
280079f2f8eSroot 	int fnum;
281079f2f8eSroot 	int size;
282079f2f8eSroot {
283079f2f8eSroot 
284079f2f8eSroot 	cpsize = size;
285079f2f8eSroot 	return(0);
286079f2f8eSroot }
287079f2f8eSroot 
stuffc(code)288079f2f8eSroot stuffc(code)
289079f2f8eSroot 	register int code;
290079f2f8eSroot {
291079f2f8eSroot 	register struct achar *ap, **bp;
292079f2f8eSroot 
293079f2f8eSroot 	if (col < 0 || col >= 500*8)
294079f2f8eSroot 		return;
295079f2f8eSroot 	if (afreel) {
296079f2f8eSroot 		ap = afreel;
297079f2f8eSroot 		afreel = ap->next;
298079f2f8eSroot 	} else
299079f2f8eSroot 		ap = (struct achar *)malloc(sizeof (*ap));
300079f2f8eSroot 	ap->row = row;
301079f2f8eSroot 	ap->col = col;
302079f2f8eSroot 	ap->psize = cpsize;
303079f2f8eSroot 	ap->verd = verd;
304079f2f8eSroot 	ap->back = back;
305079f2f8eSroot 	ap->mcase = mcase;
306079f2f8eSroot 	ap->code = code;
307079f2f8eSroot 	ap->railmag = railmag;
308079f2f8eSroot 	bp = &piles[col / 8];
309079f2f8eSroot 	ap->next = *bp;
310079f2f8eSroot 	*bp = ap;
311079f2f8eSroot }
312079f2f8eSroot 
allflush()313079f2f8eSroot allflush()
314079f2f8eSroot {
315079f2f8eSroot 
316079f2f8eSroot 	linesflush();
317079f2f8eSroot 	if (row > orow)
318079f2f8eSroot 		ptlead(row - orow);
319079f2f8eSroot 	row -= pagelength;
320079f2f8eSroot 	orow = row;
321079f2f8eSroot }
322079f2f8eSroot 
323079f2f8eSroot 
linesflush()324079f2f8eSroot linesflush()
325079f2f8eSroot {
326079f2f8eSroot 	register struct achar **ap, *bp, *cp;
327079f2f8eSroot 	static notfirst;
328079f2f8eSroot 
329079f2f8eSroot 	if (notfirst)
330079f2f8eSroot 		putc(0115, out);
331079f2f8eSroot 	orow = 0;
332079f2f8eSroot 	ocol = 0;
333079f2f8eSroot 	notfirst = 1;
334079f2f8eSroot 	for (ap = &piles[0]; ap < &piles[500]; ap++) {
335079f2f8eSroot 		for (bp = *ap; bp; bp = cp) {
336079f2f8eSroot 			sendchar(bp);
337079f2f8eSroot 			cp = bp->next;
338079f2f8eSroot 			bp->next = afreel;
339079f2f8eSroot 			afreel = bp;
340079f2f8eSroot 		}
341079f2f8eSroot 		*ap = 0;
342079f2f8eSroot 	}
343079f2f8eSroot }
344079f2f8eSroot 
sendchar(cp)345079f2f8eSroot sendchar(cp)
346079f2f8eSroot 	register struct achar *cp;
347079f2f8eSroot {
348079f2f8eSroot 	register int i;
349079f2f8eSroot 
350079f2f8eSroot #ifdef DUMPCHAR
351079f2f8eSroot 	dumpchar(cp);
352079f2f8eSroot #endif
353079f2f8eSroot 	if(cp->railmag != orailmag)
354079f2f8eSroot 		ptrail(cp->railmag);
355079f2f8eSroot 	if(cp->psize != opsize)
356079f2f8eSroot 		ptsize(cp->psize);
357079f2f8eSroot 	if(cp->mcase != omcase)
358079f2f8eSroot 		ptmcase();
359079f2f8eSroot 	if(cp->row != orow)
360079f2f8eSroot 		ptlead(cp->row - orow);
361079f2f8eSroot 	if(cp->col != ocol)
362079f2f8eSroot 		ptesc(cp->col - ocol);
363079f2f8eSroot 	if(cp->back != oback)
364079f2f8eSroot 		ptback();
365079f2f8eSroot 	putc(cp->code, out);
366079f2f8eSroot 	orow = cp->row;
367079f2f8eSroot 	orailmag = cp->railmag;
368079f2f8eSroot 	opsize = cp->psize;
369079f2f8eSroot 	omcase = cp->mcase;
370079f2f8eSroot 	ocol = cp->col;
371079f2f8eSroot 	oback = cp->back;
372079f2f8eSroot }
373079f2f8eSroot 
ptrail(rlmg)374079f2f8eSroot ptrail(rlmg)
375079f2f8eSroot 	register int rlmg;
376079f2f8eSroot {
377079f2f8eSroot 
378079f2f8eSroot 	if((rlmg & 01) != (orailmag & 01))
379079f2f8eSroot 		putc((rlmg & 01) ? 0102:0101, out);	/*  rail  */
380079f2f8eSroot 	if((rlmg & 02) != (orailmag & 02))
381079f2f8eSroot 		putc((rlmg & 02) ? 0103:0104, out);	/*  mag  */
382079f2f8eSroot }
383079f2f8eSroot 
ptback()384079f2f8eSroot ptback()
385079f2f8eSroot {
386079f2f8eSroot 
387079f2f8eSroot 	putc(oback ? 0107:0110, out);
388079f2f8eSroot 	oback = !oback;
389079f2f8eSroot }
390079f2f8eSroot 
ptsize(size)391079f2f8eSroot ptsize(size)
392079f2f8eSroot 	register int size;
393079f2f8eSroot {
394079f2f8eSroot 
395079f2f8eSroot 	putc(0120 | (size & 017), out);
396079f2f8eSroot 	ptesc(-stupidadj(size, opsize));
397079f2f8eSroot }
398079f2f8eSroot 
stupidadj(code,lcode)399079f2f8eSroot stupidadj(code, lcode)
400079f2f8eSroot 	register int code;
401079f2f8eSroot 	int lcode;
402079f2f8eSroot {
403079f2f8eSroot 	register struct point_sizes *psp;
404079f2f8eSroot 	register struct point_sizes *lpsp;
405079f2f8eSroot 
406079f2f8eSroot 	psp = point_sizes;
407079f2f8eSroot 	while(psp->real_code != 0) {
408079f2f8eSroot 		if((psp->stupid_code & 017) == code)
409079f2f8eSroot 			break;
410079f2f8eSroot 		psp++;
411079f2f8eSroot 	}
412079f2f8eSroot 	lpsp = point_sizes;
413079f2f8eSroot 	while(lpsp->real_code != 0) {
414079f2f8eSroot 		if((lpsp->stupid_code & 017) == lcode)
415079f2f8eSroot 			break;
416079f2f8eSroot 		lpsp++;
417079f2f8eSroot 	}
418079f2f8eSroot 	code = 0;
419079f2f8eSroot 	if(!(lpsp->stupid_code & 0200) && (psp->stupid_code & 0200))
420079f2f8eSroot 		code = -55;
421079f2f8eSroot 	else
422079f2f8eSroot 		if((lpsp->stupid_code & 0200) && !(psp->stupid_code & 0200))
423079f2f8eSroot 			code = 55;
424079f2f8eSroot 	return(code);
425079f2f8eSroot }
426079f2f8eSroot 
ptmcase()427079f2f8eSroot ptmcase()
428079f2f8eSroot {
429079f2f8eSroot 
430079f2f8eSroot 	putc(omcase ? 0105:0106, out);
431079f2f8eSroot }
432079f2f8eSroot 
ptesc(escc)433079f2f8eSroot ptesc(escc)
434079f2f8eSroot 	register int escc;
435079f2f8eSroot {
436079f2f8eSroot 
437079f2f8eSroot 	if((escc < 0 && !oback ) || (escc >= 0 && oback))
438079f2f8eSroot 		ptback();
439079f2f8eSroot 	escc = abs(escc);
440079f2f8eSroot 	while(escc > 0177) {
441079f2f8eSroot 		putc(0200, out);
442079f2f8eSroot 		escc -= 0177;
443079f2f8eSroot 	}
444079f2f8eSroot 	if(escc)
445079f2f8eSroot 		putc(0200 | ((~escc) & 0177), out);
446079f2f8eSroot }
447079f2f8eSroot 
ptlead(leadd)448079f2f8eSroot ptlead(leadd)
449079f2f8eSroot 	register int leadd;
450079f2f8eSroot {
451079f2f8eSroot 
452079f2f8eSroot 	if (leadd == 0)
453079f2f8eSroot 		return;
454079f2f8eSroot 	if (leadd < 0) {
455079f2f8eSroot 		if (overd == 0)
456079f2f8eSroot 			putc(0114, out), overd = 1;
457079f2f8eSroot 		leadd = -leadd;
458079f2f8eSroot 	} else {
459079f2f8eSroot 		if (overd)
460079f2f8eSroot 			putc(0112, out), overd = 0;
461079f2f8eSroot 	}
462079f2f8eSroot 	if (leadd > 64) {
463079f2f8eSroot 		putc(0116, out);
464079f2f8eSroot 		putc(leadd / 64, out);
465079f2f8eSroot 		leadd %= 64;
466079f2f8eSroot 	}
467079f2f8eSroot 	while (leadd > 037) {
468079f2f8eSroot 		putc(0140, out);
469079f2f8eSroot 		leadd -= 037;
470079f2f8eSroot 	}
471079f2f8eSroot 	if (leadd)
472079f2f8eSroot 		putc(0140 | ((~leadd) & 037), out);
473079f2f8eSroot }
474079f2f8eSroot 
475079f2f8eSroot #ifdef DUMPLINE
dumpchar(cp)476079f2f8eSroot dumpchar(cp)
477079f2f8eSroot register struct achar *cp;
478079f2f8eSroot {
479079f2f8eSroot 
480079f2f8eSroot 	fprintf(stderr,
481079f2f8eSroot "code %o psize %d col %d row %d railmag %d verd %d back %d mcase %d\n",
482079f2f8eSroot 	    cp->code, cp->psize, cp->col, cp->row, cp->railmag, cp->verd,
483079f2f8eSroot 	    cp->back, cp->mcase);
484079f2f8eSroot }
485079f2f8eSroot #endif
486