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