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