xref: /original-bsd/old/vfilters/rvsort/rvsort.c (revision 2b5e1aa9)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
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.
11  */
12 
13 #ifndef lint
14 char 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
20 static char sccsid[] = "@(#)rvsort.c	5.2 (Berkeley) 03/08/88";
21 #endif /* not lint */
22 
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 
31 double atof();
32 char *calloc();
33 
34 FILE *in,*out;
35 
36 struct achar *piles[500], *afreel;
37 
38 int skipfirst = 1;	/* skip the first leading so start at top of page */
39 int cpsize = 02;	/*  Funny sizes  */
40 struct 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 
62 int	pagelength = 144 * 11;	/* in Leading units */
63 int	pagemod;		/* horizontal page number (for versatec) */
64 #define	MODOFF 3672		/* 432 * 8.5 */
65 
66 int	esc, lead, back, verd, mcase, railmag;
67 int	col, row;
68 
69 int	oback, omcase, orailmag, ocol, orow, overd;
70 int	opsize = 02;
71 
72 struct	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 
85 main(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 
125 ofile()
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 
254 int	peekc;
255 
256 getch()
257 {
258 	register c;
259 
260 	if(peekc) {
261 		c = peekc;
262 		peekc = 0;
263 		return(c);
264 	}
265 	return(getc(in));
266 }
267 
268 ungetc(c)
269 {
270 	peekc = c;
271 }
272 
273 error(s)
274 	char *s;
275 {
276 
277 	fflush(out);
278 	fprintf(stderr, "vsort: %s\n", s);
279 }
280 
281 crail(nrail)
282 	int nrail;
283 {
284 
285 	railmag = nrail;
286 	loadfont(nrail, cpsize);
287 }
288 
289 loadfont(fnum, size)
290 	int fnum;
291 	int size;
292 {
293 
294 	cpsize = size;
295 	return(0);
296 }
297 
298 stuffc(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 
323 allflush()
324 {
325 
326 	linesflush();
327 	if (row > orow)
328 		ptlead(row - orow);
329 	row -= pagelength;
330 	orow = row;
331 }
332 
333 
334 linesflush()
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 
355 sendchar(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 
384 ptrail(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 
394 ptback()
395 {
396 
397 	putc(oback ? 0107:0110, out);
398 	oback = !oback;
399 }
400 
401 ptsize(size)
402 	register int size;
403 {
404 
405 	putc(0120 | (size & 017), out);
406 	ptesc(-stupidadj(size, opsize));
407 }
408 
409 stupidadj(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 
437 ptmcase()
438 {
439 
440 	putc(omcase ? 0105:0106, out);
441 }
442 
443 ptesc(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 
458 ptlead(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
486 dumpchar(cp)
487 register 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
496