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