1 static char *sccsid = "@(#)tc.c 4.2 (Berkeley) 07/06/81"; 2 /* 3 * Simulate typesetter on 4014 4 */ 5 6 #include <signal.h> 7 #include <stdio.h> 8 9 #define oput(c) if (pgskip==0) putchar(c); else (c); 10 #define MAXY 3071 11 #define US 037 12 #define GS 035 13 #define ESC 033 14 #define FF 014 15 #define DBL 0200 16 17 int pl = 11*144; 18 int mpy = 1; 19 int div = 1; 20 char *ap; 21 int ch; 22 int nonumb; 23 int psize = 10; 24 int dfact = 1; 25 int esc; 26 int escd; 27 int verd; 28 int esct; 29 int osize = 02; 30 int size = 02; 31 int rx; 32 int xx; 33 int yy = MAXY+62+48; 34 int leadtot = -31; 35 int ohy = -1; 36 int ohx = -1; 37 int oxb = -1; 38 int oly = -1; 39 int olx = -1; 40 int tflag; 41 int railmag; 42 int lead; 43 int skip; 44 int pgskip; 45 int ksize = ';'; 46 int mcase; 47 int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217}; 48 int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18}; 49 int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'}; 50 int first = 1; 51 int alpha; 52 extern char *asctab[128]; 53 extern char *spectab[128]; 54 int erase = 1; 55 int (*sigint)(); 56 int (*sigquit)(); 57 58 main(argc,argv) 59 int argc; 60 char **argv; 61 { 62 register i, j; 63 register char *k; 64 extern ex(); 65 66 while((--argc > 0) && ((++argv)[0][0]=='-')){ 67 switch(argv[0][1]){ 68 case 'p': 69 ap = &argv[0][2]; 70 dfact = 72; 71 if(i = atoi())pl = i/3; 72 continue; 73 case 't': 74 tflag++; 75 continue; 76 case 's': 77 ap = &argv[0][2]; 78 dfact = 1; 79 pgskip = atoi(); 80 continue; 81 default: 82 dfact = 1; 83 ap = &argv[0][1]; 84 if(i = atoi())mpy = i; 85 if(i = atoi())div = i; 86 continue; 87 } 88 } 89 if(argc){ 90 if (freopen(argv[0], "r", stdin) == NULL) { 91 fprintf(stderr, "tc: cannot open %s\n", argv[0]); 92 exit(1); 93 } 94 } 95 sigint = signal(SIGINT, ex); 96 sigquit = signal(SIGQUIT, SIG_IGN); 97 while((i = getchar()) != EOF){ 98 if(!i)continue; 99 if(i & 0200){ 100 esc += (~i) & 0177; 101 continue; 102 } 103 if(esc){ 104 if(escd)esc = -esc; 105 esct += esc; 106 xx += (esc*mpy + rx)/div; 107 rx = (esc*mpy + rx)%div; 108 sendpt(); 109 esc = 0; 110 } 111 switch(i){ 112 case 0100: /*init*/ 113 escd = verd = mcase = railmag = xx = 0; 114 yy = MAXY + 48; 115 leadtot = -31; 116 ohy = oxb = oly = ohx = olx = -1; 117 oput(US); 118 fflush(stdout); 119 if(!first && !tflag)kwait(); 120 if(first){ 121 first = 0; 122 yy += 62; 123 } 124 init(); 125 continue; 126 case 0101: /*lower rail*/ 127 railmag &= ~01; 128 continue; 129 case 0102: /*upper rail*/ 130 railmag |= 01; 131 continue; 132 case 0103: /*upper mag*/ 133 railmag |= 02; 134 continue; 135 case 0104: /*lower mag*/ 136 railmag &= ~02; 137 continue; 138 case 0105: /*lower case*/ 139 mcase = 0; 140 continue; 141 case 0106: /*upper case*/ 142 mcase = 0100; 143 continue; 144 case 0107: /*escape forward*/ 145 escd = 0; 146 continue; 147 case 0110: /*escape backward*/ 148 escd = 1; 149 continue; 150 case 0111: /*stop*/ 151 continue; 152 case 0112: /*lead forward*/ 153 verd = 0; 154 continue; 155 case 0113: /*undefined*/ 156 continue; 157 case 0114: /*lead backward*/ 158 verd = 1; 159 continue; 160 case 0115: /*undefined*/ 161 case 0116: 162 case 0117: 163 continue; 164 } 165 if((i & 0340) == 0140){ /*leading*/ 166 lead = (~i) & 037; 167 if(verd)lead = -lead; 168 if((leadtot += lead) > pl){ 169 leadtot = lead; 170 oput(US); 171 fflush(stdout); 172 if(!tflag)kwait(); 173 yy = MAXY; 174 if(pgskip)--pgskip; 175 init(); 176 continue; 177 } 178 if(skip)continue; 179 if((yy -= (lead<<1)) < 0){ 180 skip++; 181 yy = 0; 182 }else sendpt(); 183 continue; 184 } 185 if((i & 0360) == 0120){ /*size change*/ 186 i &= 017; 187 for(j = 0; i != (stab[j] & 017); j++); 188 osize = size; 189 size = stab[j]; 190 psize = rtab[j]; 191 ksize = ktab[j]; 192 oput(ESC); 193 oput(ksize); 194 i = 0; 195 if(!(osize & DBL) && (size & DBL))i = -55; 196 else if((osize & DBL) && !(size & DBL))i = 55; 197 if(escd)i = -i; 198 esc += i; 199 continue; 200 } 201 if(i & 0300)continue; 202 i = (i & 077) | mcase; 203 if(railmag != 03)k = asctab[i]; 204 else k = spectab[i]; 205 if(alpha)sendpt(); 206 if(*k!='\0'){ 207 oput(US); 208 while(*k & 0377)oput(*k++); 209 alpha++; 210 continue; 211 }else{ 212 if(railmag != 03){ 213 switch(i){ 214 case 0124: lig("fi"); break; 215 case 0125: lig("fl"); break; 216 case 0126: lig("ff"); break; 217 case 0130: lig("ffl"); break; 218 case 0131: lig("ffi"); break; 219 default: continue; 220 } 221 } 222 continue; 223 } 224 } 225 ex(); 226 } 227 lig(x) 228 char *x; 229 { 230 register i, j; 231 register char *k; 232 233 j = 0; 234 k = x; 235 oput(US); 236 oput(*k++); 237 i = psize * 8 * mpy / (div * 6); /* 8/36 em */ 238 while(*k){ 239 xx += i; 240 j += i; 241 sendpt(); 242 oput(US); 243 oput(*k++); 244 } 245 xx -= j; 246 sendpt(); 247 } 248 init(){ 249 250 fflush(stdout); 251 if(erase){ 252 oput(ESC); 253 oput(FF); 254 }else erase = 1; 255 oput(ESC); 256 oput(ksize); 257 /*delay about a second*/ 258 /* let the system do it... 259 for(i = 960; i > 0; i--)oput(GS); 260 */ 261 skip = 0; 262 sendpt(); 263 } 264 ex(){ 265 yy = MAXY; 266 xx = 0; 267 sendpt(); 268 oput(ESC); 269 oput(';'); 270 oput(US); 271 fflush(stdout); 272 exit(0); 273 } 274 kwait(){ 275 char buf[128]; char *bptr; char c; 276 if(pgskip) return; 277 next: 278 bptr=buf; 279 while((c=readch())&&(c!='\n')) *bptr++=c; 280 *bptr=0; 281 if(bptr!=buf){ 282 bptr = buf; 283 if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;} 284 else switch(*bptr++){ 285 case 'e': 286 erase = 0; 287 goto next; 288 case 's': 289 ap = &buf[1]; 290 dfact = 1; 291 pgskip = atoi() + 1; 292 goto next; 293 default: 294 fputs("?\n", stderr); 295 goto next; 296 } 297 } 298 else if (c==0) ex(); 299 else return; 300 } 301 callunix(line) 302 char line[]; 303 { 304 int rc, status, unixpid; 305 if( (unixpid=fork())==0 ) { 306 signal(SIGINT,sigint); signal(SIGQUIT,sigquit); 307 close(0); dup(2); 308 execl("/bin/sh", "-sh", "-c", line, 0); 309 exit(255); 310 } 311 else if(unixpid == -1) 312 return; 313 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); 314 while( (rc = wait(&status)) != unixpid && rc != -1 ) ; 315 signal(SIGINT,ex); signal(SIGQUIT,sigquit); 316 } 317 } 318 readch(){ 319 char c; 320 if (read(2,&c,1)<1) c=0; 321 return(c); 322 } 323 sendpt(){ 324 int hy,xb,ly,hx,lx; 325 326 oput(GS); 327 hy = ((yy>>7) & 037); 328 xb = ((xx & 03) + ((yy<<2) & 014) & 017); 329 ly = ((yy>>2) & 037); 330 hx = ((xx>>7) & 037); 331 lx = ((xx>>2) & 037); 332 if(hy != ohy)oput(hy | 040); 333 if(xb != oxb)oput(xb | 0140); 334 if((ly != oly) || (hx != ohx) || (xb != oxb)) 335 oput(ly | 0140); 336 if(hx != ohx)oput(hx | 040); 337 oput(lx | 0100); 338 ohy = hy; 339 oxb = xb; 340 oly = ly; 341 ohx = hx; 342 olx = lx; 343 alpha = 0; 344 return; 345 } 346 atoi() 347 { 348 register i, j, acc; 349 int field, digits; 350 long dd; 351 long tscale(); 352 353 field = digits = acc = 0; 354 a1: 355 while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){ 356 field++; 357 digits++; 358 acc = 10*acc + j; 359 } 360 if(i == '.'){ 361 field++; 362 digits = 0; 363 goto a1; 364 } 365 if(!(ch = i))ch = 'x'; 366 dd = tscale(acc); 367 acc = dd; 368 if((field != digits) && (digits > 0)){ 369 j = 1; 370 while(digits--)j *= 10; 371 acc = dd/j; 372 } 373 nonumb = !field; 374 ch = 0; 375 return(acc); 376 } 377 long tscale(n) 378 int n; 379 { 380 register i, j; 381 382 switch(i = getch()){ 383 case 'u': 384 j = 1; 385 break; 386 case 'p': /*Points*/ 387 j = 6; 388 break; 389 case 'i': /*Inches*/ 390 j = 432; 391 break; 392 case 'c': /*Centimeters; should be 170.0787*/ 393 j = 170; 394 break; 395 case 'P': /*Picas*/ 396 j = 72; 397 break; 398 default: 399 j = dfact; 400 ch = i; 401 } 402 return((long)n*j); 403 } 404 getch(){ 405 register i; 406 407 if(ch){ 408 i = ch; 409 ch = 0; 410 return(i); 411 } 412 return(*ap++); 413 } 414 415 char *asctab[128] = { 416 "\0", /*blank*/ 417 "h", /*h*/ 418 "t", /*t*/ 419 "n", /*n*/ 420 "m", /*m*/ 421 "l", /*l*/ 422 "i", /*i*/ 423 "z", /*z*/ 424 "s", /*s*/ 425 "d", /*d*/ 426 "b", /*b*/ 427 "x", /*x*/ 428 "f", /*f*/ 429 "j", /*j*/ 430 "u", /*u*/ 431 "k", /*k*/ 432 "\0", /*blank*/ 433 "p", /*p*/ 434 "-", /*_ 3/4 em dash*/ 435 ";", /*;*/ 436 "\0", /*blank*/ 437 "a", /*a*/ 438 "_", /*rule*/ 439 "c", /*c*/ 440 "`", /*` open*/ 441 "e", /*e*/ 442 "\'", /*' close*/ 443 "o", /*o*/ 444 "\0", /*1/4*/ 445 "r", /*r*/ 446 "\0", /*1/2*/ 447 "v", /*v*/ 448 "-", /*- hyphen*/ 449 "w", /*w*/ 450 "q", /*q*/ 451 "/", /*/*/ 452 ".", /*.*/ 453 "g", /*g*/ 454 "\0", /*3/4*/ 455 ",", /*,*/ 456 "&", /*&*/ 457 "y", /*y*/ 458 "\0", /*blank*/ 459 "%", /*%*/ 460 "\0", /*blank*/ 461 "Q", /*Q*/ 462 "T", /*T*/ 463 "O", /*O*/ 464 "H", /*H*/ 465 "N", /*N*/ 466 "M", /*M*/ 467 "L", /*L*/ 468 "R", /*R*/ 469 "G", /*G*/ 470 "I", /*I*/ 471 "P", /*P*/ 472 "C", /*C*/ 473 "V", /*V*/ 474 "E", /*E*/ 475 "Z", /*Z*/ 476 "D", /*D*/ 477 "B", /*B*/ 478 "S", /*S*/ 479 "Y", /*Y*/ 480 "\0", /*blank*/ 481 "F", /*F*/ 482 "X", /*X*/ 483 "A", /*A*/ 484 "W", /*W*/ 485 "J", /*J*/ 486 "U", /*U*/ 487 "K", /*K*/ 488 "0", /*0*/ 489 "1", /*1*/ 490 "2", /*2*/ 491 "3", /*3*/ 492 "4", /*4*/ 493 "5", /*5*/ 494 "6", /*6*/ 495 "7", /*7*/ 496 "8", /*8*/ 497 "9", /*9*/ 498 "*", /***/ 499 "-", /*minus*/ 500 "", /*fi*/ 501 "", /*fl*/ 502 "", /*ff*/ 503 "\033\016Z\bM\033\017", /*cent sign*/ 504 "", /*ffl*/ 505 "", /*ffi*/ 506 "(", /*(*/ 507 ")", /*)*/ 508 "[", /*[*/ 509 "]", /*]*/ 510 "\033\016J\033\017", /*degree*/ 511 "\033\016M\b_\033\017", /*dagger*/ 512 "=", /*=*/ 513 "\033\016O\b&\033\017", /*registered*/ 514 ":", /*:*/ 515 "+", /*+*/ 516 "\0", /*blank*/ 517 "!", /*!*/ 518 "\033\016O\b~\033\017", /*bullet*/ 519 "?", /*?*/ 520 "\'", /*foot mark*/ 521 "|", /*|*/ 522 "\0", /*blank*/ 523 "\033\016O\b#\033\017", /*copyright*/ 524 "\033\016L\033\017", /*square*/ 525 "$" }; /*$*/ 526 527 char *spectab[128] = { 528 "\0", /*blank*/ 529 "\033\016(\bM\033\017", /*psi*/ 530 "\033\016o\b_\033\017", /*theta*/ 531 "v\b)", /*nu*/ 532 "\033\016V\b,\033\017", /*mu*/ 533 "\033\016)\b?\033\017", /*lambda*/ 534 "\033\016I\033\017", /*iota*/ 535 "S\b\033\016Z\033\017", /*zeta*/ 536 "o\b\'", /*sigma*/ 537 "o\b\033\0165\033\017", /*delta*/ 538 "\033\016b\033\017", /*beta*/ 539 "\033\016e\bc\033\017", /*xi*/ 540 "j\b\033\016C\033\017", /*eta*/ 541 "\033\016O\bM\033\017", /*phi*/ 542 "\033\016(\033\017", /*upsilon*/ 543 "\033\016k\033\017", /*kappa*/ 544 "\0", /*blank*/ 545 "T\b\033\016S\033\017", /*pi*/ 546 "@", /*at-sign*/ 547 "\033\016U\033\017", /*down arrow*/ 548 "\0", /*blank*/ 549 "\033\016A\033\017", /*alpha*/ 550 "|", /*or*/ 551 "l\b/", /*chi*/ 552 "\"", /*"*/ 553 "\033\016E\033\017", /*epsilon*/ 554 "=", /*=*/ 555 "\033\016O\033\017", /*omicron*/ 556 "\033\016[\033\017", /*left arrow*/ 557 "\033\016R\033\017", /*rho*/ 558 "\033\016Y\033\017", /*up arrow*/ 559 "\033\016N\033\017", /*tau*/ 560 "_", /*underrule*/ 561 "\\", /*\*/ 562 "I\b\033\016(\033\017", /*Psi*/ 563 "\033\016O\bJ\033\017", /*bell system sign*/ 564 "\033\016W\bX\033\017", /*infinity*/ 565 "`\b/", /*gamma*/ 566 "\033\016X\bF\033\017", /*improper superset*/ 567 "\033\016A\033\017", /*proportional to*/ 568 "\033\016\\\b]\033\017", /*right hand*/ 569 "\033\016W\033\017", /*omega*/ 570 "\0", /*blank*/ 571 "\033\016G\033\017", /*gradient*/ 572 "\0", /*blank*/ 573 "I\033\016\bO\033\017", /*Phi*/ 574 "O\b=", /*Theta*/ 575 "O\b_", /*Omega*/ 576 "\033\016V\033\017", /*cup (union)*/ 577 "\033\016@\033\017", /*root en*/ 578 "s", /*terminal sigma*/ 579 "\033\016)\bK\033\017", /*Lambda*/ 580 "-", /*minus*/ 581 "\033\016S\bK\033\017", /*Gamma*/ 582 "\033\016i\033\017", /*integral sign*/ 583 "\033\016t\b'\033\017", /*Pi*/ 584 "\033\016Z\033\017", /*subset of*/ 585 "\033\016X\033\017", /*superset of*/ 586 "\033\016T\033\017", /*approximates*/ 587 "o\b`", /*partial derivative*/ 588 "\033\016H\033\017", /*Delta*/ 589 "\033\016I\b'\033\017", /*square root*/ 590 ">\b\033\016F\b@\033\017", /*Sigma*/ 591 "\033\016T\bF\033\017", /*approx =*/ 592 "\0", /*blank*/ 593 ">", /*>*/ 594 "\033\016_\bF\b@\033\017", /*Xi*/ 595 "<", /*<*/ 596 "/", /*slash (longer)*/ 597 "\033\016C\033\017", /*cap (intersection)*/ 598 "\033\016y\033\017", /*Upsilon*/ 599 "\033\016|\033\017", /*not*/ 600 "|", /*right ceiling (rt of ")*/ 601 "|", /*left top (of big curly)*/ 602 "|", /*bold vertical*/ 603 "|", /*left center of big curly bracket*/ 604 "|", /*left bottom*/ 605 "|", /*right top*/ 606 "|", /*right center of big curly bracket*/ 607 "|", /*right bot*/ 608 "|", /*right floor (rb of ")*/ 609 "|", /*left floor (left bot of big sq bract)*/ 610 "|", /*left ceiling (lt of ")*/ 611 "\033\016=\033\017", /*multiply*/ 612 "\033\016+\033\017", /*divide*/ 613 "+\b_", /*plus-minus*/ 614 "\033\016$\033\017", /*<=*/ 615 "\033\016^\033\017", /*>=*/ 616 "=\b_", /*identically equal*/ 617 "\033\016*\033\017", /*not equal*/ 618 "{", /*{*/ 619 "}", /*}*/ 620 "\'", /*' acute accent*/ 621 "`", /*` grave accent*/ 622 "^", /*^*/ 623 "#", /*sharp*/ 624 "\033\016|\b[\033\017", /*left hand*/ 625 "\033\016c\b_\033\017", /*member of*/ 626 "~", /*~*/ 627 "\033\016O\b/\033\017", /*empty set*/ 628 "\0", /*blank*/ 629 "\033\016%\bM\033\017", /*dbl dagger*/ 630 "|", /*box rule*/ 631 "*", /*asterisk*/ 632 "\033\016Z\bF\033\017", /*improper subset*/ 633 "\033\016O\033\017", /*circle*/ 634 "\0", /*blank*/ 635 "+", /*eqn plus*/ 636 "\033\016]\033\017", /*right arrow*/ 637 "g\b\033\016C\033\017" }; /*section mark*/ 638