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