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