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.4 (Berkeley) 06/01/90"; 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 ungetc(c) 264 { 265 peekc = c; 266 } 267 268 error(s) 269 char *s; 270 { 271 272 fflush(out); 273 fprintf(stderr, "vsort: %s\n", s); 274 } 275 276 crail(nrail) 277 int nrail; 278 { 279 280 railmag = nrail; 281 loadfont(nrail, cpsize); 282 } 283 284 loadfont(fnum, size) 285 int fnum; 286 int size; 287 { 288 289 cpsize = size; 290 return(0); 291 } 292 293 stuffc(code) 294 register int code; 295 { 296 register struct achar *ap, **bp; 297 298 if (col < 0 || col >= 500*8) 299 return; 300 if (afreel) { 301 ap = afreel; 302 afreel = ap->next; 303 } else 304 ap = (struct achar *)malloc(sizeof (*ap)); 305 ap->row = row; 306 ap->col = col; 307 ap->psize = cpsize; 308 ap->verd = verd; 309 ap->back = back; 310 ap->mcase = mcase; 311 ap->code = code; 312 ap->railmag = railmag; 313 bp = &piles[col / 8]; 314 ap->next = *bp; 315 *bp = ap; 316 } 317 318 allflush() 319 { 320 321 linesflush(); 322 if (row > orow) 323 ptlead(row - orow); 324 row -= pagelength; 325 orow = row; 326 } 327 328 329 linesflush() 330 { 331 register struct achar **ap, *bp, *cp; 332 static notfirst; 333 334 if (notfirst) 335 putc(0115, out); 336 orow = 0; 337 ocol = 0; 338 notfirst = 1; 339 for (ap = &piles[0]; ap < &piles[500]; ap++) { 340 for (bp = *ap; bp; bp = cp) { 341 sendchar(bp); 342 cp = bp->next; 343 bp->next = afreel; 344 afreel = bp; 345 } 346 *ap = 0; 347 } 348 } 349 350 sendchar(cp) 351 register struct achar *cp; 352 { 353 register int i; 354 355 #ifdef DUMPCHAR 356 dumpchar(cp); 357 #endif 358 if(cp->railmag != orailmag) 359 ptrail(cp->railmag); 360 if(cp->psize != opsize) 361 ptsize(cp->psize); 362 if(cp->mcase != omcase) 363 ptmcase(); 364 if(cp->row != orow) 365 ptlead(cp->row - orow); 366 if(cp->col != ocol) 367 ptesc(cp->col - ocol); 368 if(cp->back != oback) 369 ptback(); 370 putc(cp->code, out); 371 orow = cp->row; 372 orailmag = cp->railmag; 373 opsize = cp->psize; 374 omcase = cp->mcase; 375 ocol = cp->col; 376 oback = cp->back; 377 } 378 379 ptrail(rlmg) 380 register int rlmg; 381 { 382 383 if((rlmg & 01) != (orailmag & 01)) 384 putc((rlmg & 01) ? 0102:0101, out); /* rail */ 385 if((rlmg & 02) != (orailmag & 02)) 386 putc((rlmg & 02) ? 0103:0104, out); /* mag */ 387 } 388 389 ptback() 390 { 391 392 putc(oback ? 0107:0110, out); 393 oback = !oback; 394 } 395 396 ptsize(size) 397 register int size; 398 { 399 400 putc(0120 | (size & 017), out); 401 ptesc(-stupidadj(size, opsize)); 402 } 403 404 stupidadj(code, lcode) 405 register int code; 406 int lcode; 407 { 408 register struct point_sizes *psp; 409 register struct point_sizes *lpsp; 410 411 psp = point_sizes; 412 while(psp->real_code != 0) { 413 if((psp->stupid_code & 017) == code) 414 break; 415 psp++; 416 } 417 lpsp = point_sizes; 418 while(lpsp->real_code != 0) { 419 if((lpsp->stupid_code & 017) == lcode) 420 break; 421 lpsp++; 422 } 423 code = 0; 424 if(!(lpsp->stupid_code & 0200) && (psp->stupid_code & 0200)) 425 code = -55; 426 else 427 if((lpsp->stupid_code & 0200) && !(psp->stupid_code & 0200)) 428 code = 55; 429 return(code); 430 } 431 432 ptmcase() 433 { 434 435 putc(omcase ? 0105:0106, out); 436 } 437 438 ptesc(escc) 439 register int escc; 440 { 441 442 if((escc < 0 && !oback ) || (escc >= 0 && oback)) 443 ptback(); 444 escc = abs(escc); 445 while(escc > 0177) { 446 putc(0200, out); 447 escc -= 0177; 448 } 449 if(escc) 450 putc(0200 | ((~escc) & 0177), out); 451 } 452 453 ptlead(leadd) 454 register int leadd; 455 { 456 457 if (leadd == 0) 458 return; 459 if (leadd < 0) { 460 if (overd == 0) 461 putc(0114, out), overd = 1; 462 leadd = -leadd; 463 } else { 464 if (overd) 465 putc(0112, out), overd = 0; 466 } 467 if (leadd > 64) { 468 putc(0116, out); 469 putc(leadd / 64, out); 470 leadd %= 64; 471 } 472 while (leadd > 037) { 473 putc(0140, out); 474 leadd -= 037; 475 } 476 if (leadd) 477 putc(0140 | ((~leadd) & 037), out); 478 } 479 480 #ifdef DUMPLINE 481 dumpchar(cp) 482 register struct achar *cp; 483 { 484 485 fprintf(stderr, 486 "code %o psize %d col %d row %d railmag %d verd %d back %d mcase %d\n", 487 cp->code, cp->psize, cp->col, cp->row, cp->railmag, cp->verd, 488 cp->back, cp->mcase); 489 } 490 #endif 491