home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / tc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  11.4 KB  |  637 lines

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