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