Commit | Line | Data |
---|---|---|
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 |
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) %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 | ||
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 |