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