|
|
1.1 root 1: # include <stdio.h>
2: /*
3: * vsort - Sort troff output for versatec to reduce amount of reverse leading
4: */
5:
6: #define cycle for(;;)
7: #define NULL 0
8:
9: #define INTR 2
10: #define QUIT 3
11: #define HUP 1
12: #define BROKENPIPE 13
13:
14: double atof();
15:
16: FILE *inbuf,*outbuf;
17:
18: int skmagic = 1; /* skip the first leading so start at top of page */
19: int cpsize = 02; /* Funny sizes */
20: struct point_sizes
21: {
22: int stupid_code;
23: int real_code;
24: } point_sizes[]
25: {
26: 010, 6,
27: 0, 7,
28: 01, 8,
29: 07, 9,
30: 02, 10,
31: 03, 11,
32: 04, 12,
33: 05, 14,
34: 0211, 16,
35: 06, 18,
36: 0212, 20,
37: 0213, 22,
38: 0214, 24,
39: 0215, 28,
40: 0216, 36,
41: 0, 0
42: };
43:
44: int overflow = 144 * 11;
45: int pagemod;
46: #define MODOFF 3672 /* 432 * 8.5 */
47:
48: int esc, lead, back, verd, mcase, railmag;
49: int col, row;
50: int pstart 0; /* Means a startline is pending */
51:
52: int oback, omcase, orailmag, ocol;
53: int opsize 02;
54:
55: struct lstate
56: {
57: int row;
58: int col;
59: int psize;
60: char railmag;
61: char verd;
62: char back;
63: char mcase;
64: };
65:
66: struct line
67: {
68: struct line *nextp;
69: struct line *lastp;
70: int len;
71: struct lstate start;
72: struct lstate end;
73: char *codep;
74: };
75:
76: struct line *head;
77: struct line *tail;
78: struct line cline { -1,-1,-1,-1};
79:
80: #define TBUFLEN 1024
81: char *codep;
82: char tbuf[TBUFLEN];
83:
84: #ifdef MONITORING
85: extern etext();
86: int monbuf[1000];
87: #endif
88:
89: main(argc, argv)
90: int argc;
91: char *argv[];
92: {
93: register i;
94:
95: #ifndef TESTING
96: signal(BROKENPIPE, 1);
97: #endif
98:
99: for(i = 3; i < 15; i++)
100: close(i);
101: #ifdef MONITORING
102: monitor(2,etext,monbuf,sizeof monbuf/2,0);
103: #endif
104: if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'l') {
105: float f = 144 * atof(argv[1] + 2);
106: if (f < 144) {
107: error("bad length");
108: exit(1);
109: }
110: overflow = f;
111: argc--, argv++;
112: }
113: outbuf = stdout;
114: if(argc > 1)
115: {
116: while(--argc)
117: {
118: argv++;
119: process(argv[0]);
120: }
121: }
122: else
123: {
124: inbuf = stdin;
125: ofile();
126: }
127: #ifdef MONITORING
128: monitor(0);
129: #endif
130: done();
131: }
132:
133:
134: process(name)
135: char *name;
136: {
137: if((inbuf=fopen(name, "r")) == NULL)
138: error("cannot open data file");
139: ofile();
140: }
141:
142: ofile()
143: {
144: register int c;
145: static int initialized;
146:
147: while((c = getch()) != -1) {
148: if(!c)
149: continue;
150: if(c & 0200)
151: {
152: if(!pstart)
153: stuffc(c);
154: esc += (~c) & 0177;
155: continue;
156: }
157: if(esc)
158: {
159: if(back)
160: esc = -esc;
161: col += esc;
162: esc = 0;
163: }
164: if((c & 0377) < 0100) /* Purely for efficiency */
165: goto normal_char;
166: switch(c) {
167: case 0100:
168: if(initialized++)
169: goto out;
170: row = 0;
171: col = 0; esc = 0;
172: lead = 0;
173: verd = 0; back = 0; mcase = 0;
174: railmag = 0;
175: ocol = 0;
176: oback = 0; omcase = 0;
177: orailmag = 0;
178: if(loadfont(railmag, cpsize) < 0)
179: error("init");
180: startline();
181: putc(0100, outbuf); /* Dont stuff it guys */
182: break;
183: case 0101: /* lower rail */
184: crail(railmag =& ~01);
185: if(!pstart)
186: stuffc(c);
187: break;
188: case 0102: /* upper rail */
189: crail(railmag =| 01);
190: if(!pstart)
191: stuffc(c);
192: break;
193: case 0103: /* upper mag */
194: crail(railmag =| 02);
195: if(!pstart)
196: stuffc(c);
197: break;
198: case 0104: /* lower mag */
199: crail(railmag =& ~02);
200: if(!pstart)
201: stuffc(c);
202: break;
203: case 0105: /* lower case */
204: mcase = 0;
205: if(!pstart)
206: stuffc(c);
207: break;
208: case 0106: /* upper case */
209: mcase = 0100;
210: if(!pstart)
211: stuffc(c);
212: break;
213: case 0107: /* escape forward */
214: back = 0;
215: if(!pstart)
216: stuffc(c);
217: break;
218: case 0110: /* escape backwards */
219: back = 1;
220: if(!pstart)
221: stuffc(c);
222: break;
223: case 0111: /* stop */
224: stuffc(c);
225: break;
226: case 0112: /* lead forward */
227: verd = 0;
228: break;
229: case 0113: /* undefined */
230: break;
231: case 0114: /* lead backward */
232: verd = 1;
233: break;
234: case 0115: /* undefined */
235: case 0116:
236: case 0117:
237: break;
238: default:
239: if((c & 0340) == 0140) /* leading */
240: {
241: termline();
242: lead = (~c) & 037;
243: if(verd)
244: lead = -lead;
245: if (skmagic > 0) {
246: skmagic--;
247: ptlead(lead);
248: continue;
249: }
250: row += lead;
251: if (row >= overflow) {
252: if (pagemod == 3) {
253: allflush();
254: col %= MODOFF;
255: pagemod = 0;
256: } else {
257: pagemod++;
258: col += MODOFF;
259: row -= overflow;
260: }
261: }
262: if (row >= overflow)
263: write(2, "URK\n", 4);
264: /*
265: if (row > overflow)
266: miniflush();
267: */
268: if (row < 0) {
269: if (pagemod) {
270: pagemod--;
271: col -= MODOFF;
272: row += overflow;
273: }
274: }
275: if (row < 0)
276: write(2, "URK2\n", 5);
277: pstart++;
278: continue;
279: }
280: if((c & 0360) == 0120) /* size change */
281: {
282: if(!pstart)
283: stuffc(c);
284: col += stupidadj(c & 017, cpsize);
285: loadfont(railmag, c & 017);
286: continue;
287: }
288: if(c & 0300)
289: continue;
290: normal_char:
291: c = (c & 077);
292: stuffc(c);
293: }
294: }
295: out:
296: termline();
297: allflush();
298: fclose(inbuf);
299: }
300:
301: done() {
302: termline();
303: allflush();
304: exit();
305: }
306:
307: int peekc;
308: getch() {
309: register c;
310: if(peekc) {
311: c = peekc;
312: peekc = 0;
313: return(c);
314: }
315: return(getc(inbuf));
316: }
317:
318: ungetc(c) {
319: peekc = c;
320: }
321:
322:
323: error(s)
324: char *s;
325: {
326:
327: fflush(outbuf);
328: fprintf(stderr, "Vsort: %s\n", s);
329: }
330:
331: crail(nrail)
332: register int nrail;
333: {
334: register int psize;
335:
336: psize = cpsize;
337: loadfont(nrail, psize);
338: }
339:
340: loadfont(fnum, size)
341: register int fnum;
342: register int size;
343: {
344:
345: cpsize = size;
346: return(0);
347: }
348:
349: startline()
350: {
351:
352: if(pstart != 0) {
353: cline.start.row = row;
354: return;
355: }
356: cline.len = 0;
357: cline.start.row = row;
358: cline.start.col = col;
359: cline.start.psize = cpsize;
360: cline.start.mcase = mcase;
361: cline.start.back = back;
362: cline.start.verd = verd;
363: cline.start.railmag = railmag;
364: codep = tbuf;
365: }
366:
367: termline()
368: {
369: register struct line *linep;
370: register char *allp;
371: register char *cp;
372: int i;
373:
374: if(pstart != 0)
375: return;
376: if((allp = calloc(sizeof *linep,1)) == -1)
377: error("alloc");
378: linep = allp;
379: linep->end.row = row;
380: linep->end.col = col;
381: linep->end.psize = cpsize;
382: linep->end.mcase = mcase;
383: linep->end.back = back;
384: linep->end.verd = verd;
385: linep->end.railmag = railmag;
386: linep->start.row = cline.start.row;
387: linep->start.col = cline.start.col;
388: linep->start.psize = cline.start.psize;
389: linep->start.mcase = cline.start.mcase;
390: linep->start.back = cline.start.back;
391: linep->start.verd = cline.start.verd;
392: linep->start.railmag = cline.start.railmag;
393: linep->len = cline.len;
394: if((allp = calloc(cline.len,1)) == -1)
395: error("alloc");
396: linep->codep = allp;
397: cp = tbuf;
398: for(i = 0; i < cline.len; i++)
399: *allp++ = *cp++;
400: sortin(linep);
401: }
402:
403: sortin(linep)
404: register struct line *linep;
405: {
406: register struct line *clp;
407:
408: if((clp = tail) == NULL) {
409: head = tail = linep;
410: linep->lastp = linep->nextp = NULL;
411: return;
412: }
413: while(clp != NULL && clp->start.row > linep->start.row)
414: clp = clp->lastp;
415: if(clp == tail) {
416: linep->lastp = tail;
417: linep->nextp = NULL;
418: tail->nextp = linep;
419: tail = linep;
420: } else
421: if(clp == NULL) /* goes at head of list */ {
422: linep->lastp = NULL;
423: linep->nextp = head;
424: head->lastp = linep;
425: head = linep;
426: } else {
427: linep->lastp = clp;
428: linep->nextp = clp->nextp;
429: clp->nextp->lastp = linep;
430: clp->nextp = linep;
431: }
432: }
433:
434: stuffc(code)
435: register int code;
436: {
437:
438: if(pstart != 0) {
439: pstart = 0;
440: startline();
441: }
442: if(cline.len > TBUFLEN) {
443: termline();
444: startline();
445: }
446: *codep++ = code;
447: cline.len++;
448: }
449:
450: miniflush()
451: {
452:
453: sendline();
454: }
455:
456: allflush()
457: {
458:
459: while(head != NULL)
460: sendline();
461: sendline();
462: fflush(outbuf);
463: }
464:
465: sendline()
466: {
467: register char *cp;
468: register struct line *linep;
469: register int i;
470: int drow;
471:
472: if((linep = head) == NULL) {
473: while(row >= overflow) {
474: /* fprintf(stderr, "spitting %d\n", overflow - row); */
475: if (overflow - row)
476: ptlead(overflow - row);
477: updatelist(overflow);
478: }
479: return;
480: }
481: adjparms(linep);
482: cp = linep->codep;
483: for(i = 0; i < linep->len; i++)
484: putc(*cp++, outbuf);
485: setparms(linep);
486: if(linep->nextp != NULL)
487: drow = linep->nextp->start.row;
488: else
489: drow = overflow;
490: head = linep->nextp;
491: cfree(linep->codep);
492: cfree(linep);
493: if(head == NULL)
494: tail = NULL;
495: else
496: head->lastp = NULL;
497: ptlead(drow - row);
498: row = drow;
499: /* updatelist(drow); */
500: }
501:
502: adjparms(linep)
503: register struct line *linep;
504: {
505:
506: if(linep->start.railmag != orailmag)
507: ptrail(linep->start.railmag);
508: if(linep->start.psize != opsize)
509: ptsize(linep->start.psize);
510: if(linep->start.mcase != omcase)
511: ptmcase();
512: if(linep->start.row != row) /* lead forward */
513: {
514: ptlead(linep->start.row - row);
515: row = linep->start.row;
516: /* updatelist(linep->start.row); */
517: }
518: if(linep->start.col != ocol)
519: ptesc(linep->start.col-ocol);
520: if(linep->start.back != oback)
521: ptback();
522: }
523:
524: ptrail(rlmg)
525: register int rlmg;
526: {
527:
528: if((rlmg & 01) != (orailmag & 01))
529: putc((rlmg & 01) ? 0102:0101, outbuf); /* rail */
530: if((rlmg & 02) != (orailmag & 02))
531: putc((rlmg & 02) ? 0103:0104, outbuf); /* mag */
532: }
533:
534: ptback()
535: {
536:
537: putc(oback ? 0107:0110, outbuf);
538: oback = !oback;
539: }
540:
541: ptsize(size)
542: register int size;
543: {
544:
545: putc(0120 | (size & 017), outbuf);
546: ptesc(-stupidadj(size, opsize));
547: }
548:
549: stupidadj(code, lcode)
550: register int code;
551: int lcode;
552: {
553: register struct point_sizes *psp;
554: register struct point_sizes *lpsp;
555:
556: psp = point_sizes;
557: while(psp->real_code != 0) {
558: if((psp->stupid_code & 017) == code)
559: break;
560: psp++;
561: }
562: lpsp = point_sizes;
563: while(lpsp->real_code != 0) {
564: if((lpsp->stupid_code & 017) == lcode)
565: break;
566: lpsp++;
567: }
568: code = 0;
569: if(!(lpsp->stupid_code & 0200) && (psp->stupid_code & 0200))
570: code = -55;
571: else
572: if((lpsp->stupid_code & 0200) && !(psp->stupid_code & 0200))
573: code = 55;
574: return(code);
575: }
576:
577: ptmcase()
578: {
579:
580: putc(omcase ? 0105:0106, outbuf);
581: }
582:
583: ptesc(escc)
584: register int escc;
585: {
586:
587: if((escc < 0 && !oback ) || (escc >= 0 && oback))
588: ptback();
589: escc = abs(escc);
590: while(escc > 0177) {
591: putc(0200, outbuf);
592: escc -= 0177;
593: }
594: if(escc)
595: putc(0200 | ((~escc) & 0177), outbuf);
596: }
597:
598: ptlead(leadd)
599: register int leadd;
600: {
601:
602: while(leadd > 037) {
603: putc(0140, outbuf);
604: leadd -= 037;
605: }
606: if(leadd)
607: putc(0140 | ((~leadd) & 037), outbuf);
608: }
609:
610: setparms(linep)
611: register struct line *linep;
612: {
613:
614: orailmag = linep->end.railmag;
615: opsize = linep->end.psize;
616: omcase = linep->end.mcase;
617: ocol = linep->end.col;
618: oback = linep->end.back;
619: }
620:
621: updatelist(drow)
622: register int drow;
623: {
624: register struct line *clp;
625:
626: for(clp = head; clp != NULL; clp = clp->nextp)
627: clp->start.row -= drow;
628: row -= drow;
629: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.