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

  1. #include "tdef.h"
  2. extern
  3. #include "d.h"
  4. extern
  5. #include "v.h"
  6. #ifdef NROFF
  7. extern
  8. #include "tw.h"
  9. #endif
  10. #include "s.h"
  11. /*
  12. troff4.c
  13.  
  14. number registers, conversion, arithmetic
  15. */
  16.  
  17. extern struct s *frame;
  18.  
  19. extern int ascii;
  20. extern int cbuf[NC];
  21. extern int *cp;
  22. extern int r[NN];
  23. extern int *vlist;
  24. extern int inc[NN];
  25. extern int fmt[NN];
  26. extern int ch;
  27. extern int lgf;
  28. extern int pl;
  29. extern int lastl;
  30. extern int ralss;
  31. extern int totout;
  32. extern int nrbits;
  33. extern int nonumb;
  34. extern int vflag;
  35. extern int noscale;
  36. extern int dfact;
  37. extern int dfactd;
  38. extern int po;
  39. extern int nform;
  40. extern int ll;
  41. extern int in;
  42. extern int font;
  43. extern int bdtab[];
  44. extern int lss;
  45. extern int pts;
  46. extern int fi;
  47. extern int res;
  48. extern int cwidth;
  49. extern int dotT;
  50. extern int ev;
  51. extern int ne;
  52. extern int ad, admod;
  53. extern int print;
  54. extern int ls;
  55. extern int nel, un;
  56. extern int xxx;
  57. int regcnt = NNAMES;
  58.  
  59. setn()
  60. {
  61.     register i,j;
  62.     int f;
  63.  
  64.     f = nform = 0;
  65.     if((i=getch() & CMASK) == '+')f = 1;
  66.         else if(i == '-')f = -1;
  67.             else ch = i;
  68.     if((i=getsn()) == 0)return;
  69.     if((i & 0177) == '.')switch(i>>BYTE){
  70.         case 's': i = pts & 077;    break;
  71.         case 'v': i = lss;        break;
  72.         case 'f': i = font + 1;    break;
  73.         case 'p': i = pl;        break;
  74.         case 't':  i = findt1();    break;
  75.         case 'o': i = po;        break;
  76.         case 'l': i = ll;        break;
  77.         case 'i': i = in;        break;
  78.         case '$': i = frame->nargs;        break;
  79.         case 'A': i = ascii;        break;
  80.         case 'c': i = v.cd;        break;
  81.         case 'n': i = lastl;        break;
  82.         case 'a': i = ralss;        break;
  83.         case 'h': i = dip->hnl;    break;
  84.         case 'd':
  85.             if(dip != d)i = dip->dnl; else i = v.nl;
  86.             break;
  87.         case 'u': i = fi;        break;
  88.         case 'j': i = ad + 2*admod;    break;
  89.         case 'w': i = cwidth;        break;
  90.         case 'x': i = nel;    break;
  91.         case 'y': i = un;        break;
  92.         case 'T': i = dotT;        break; /*-Tterm used in nroff*/
  93.         case 'V': i = VERT;        break;
  94.         case 'H': i = HOR;        break;
  95.         case 'k': i = ne;        break;
  96.         case 'P': i = print;        break;
  97.         case 'L': i = ls;        break;
  98.         case 'R': i = NN - regcnt;    break;
  99.         case 'z': i = dip->curd;
  100.             cbuf[0] = i & BMASK;
  101.             cbuf[1] = (i >> BYTE) & BMASK;
  102.             cbuf[2] = 0;
  103.             cp = cbuf;
  104.             return;
  105. #ifndef NROFF
  106.         case 'b': i = bdtab[font];        break;
  107. #endif
  108.  
  109.         default:
  110.             goto s0;
  111.     }
  112.     else{
  113. s0:
  114.         if((j=findr(i)) == -1)i = 0;
  115.         else{
  116.             i = (vlist[j] = (vlist[j] + inc[j]*f));
  117.             nform = fmt[j];
  118.         }
  119.     }
  120.     setn1(i);
  121.     cp = cbuf;
  122. }
  123. setn1(i)
  124. int i;
  125. {
  126.     extern int wrc();
  127.  
  128.     cp = cbuf;
  129.     nrbits = 0;
  130.     fnumb(i,wrc);
  131.     *cp = 0;
  132.     cp = cbuf;
  133. }
  134. findr(i)
  135. int i;
  136. {
  137.     register j;
  138.     static int numerr;
  139.  
  140.     if(i == 0)return(-1);
  141.     for(j=0;j<NN;j++){
  142.         if(i == r[j])break;
  143.     }
  144.     if(j != NN)return(j);
  145.     for(j=0; j<NN; j++){
  146.         if(r[j] == 0){
  147.             r[j] = i;
  148.             regcnt++;
  149.             break;
  150.         }
  151.     }
  152.     if(j==NN){
  153.         if(!numerr)prstrfl("Too many number registers.\n");
  154.         if(++numerr > 1)done2(04); else edone(04);
  155.     }
  156.     return(j);
  157. }
  158. fnumb(i,f)
  159. int i, (*f)();
  160. {
  161.     register j;
  162.  
  163.     j = 0;
  164.     if(i < 0){
  165.         j = (*f)('-' | nrbits);
  166.         i = -i;
  167.     }
  168.     switch(nform){
  169.         default:
  170.         case '1':
  171.         case 0: return(decml(i,f) + j);
  172.         case 'i':
  173.         case 'I': return(roman(i,f) + j);
  174.         case 'a':
  175.         case 'A': return(abc(i,f) + j);
  176.     }
  177. }
  178. decml(i,f)
  179. int i, (*f)();
  180. {
  181.     register j,k;
  182.  
  183.     k = 0;
  184.     nform--;
  185.     if((j=i/10) || (nform > 0))k = decml(j,f);
  186.     return(k + (*f)((i%10 + '0') | nrbits));
  187. }
  188. roman(i,f)
  189. int i, (*f)();
  190. {
  191.  
  192.     if(!i)return((*f)('0' | nrbits));
  193.     if(nform == 'i')return(roman0(i,f,"ixcmz","vldw"));
  194.     else return(roman0(i,f,"IXCMZ","VLDW"));
  195. }
  196. roman0(i,f,onesp,fivesp)
  197. int i, (*f)();
  198. char *onesp, *fivesp;
  199. {
  200.     register q, rem, k;
  201.  
  202.     k = 0;
  203.     if(!i)return(0);
  204.     k = roman0(i/10,f,onesp+1,fivesp+1);
  205.     q = (i=i%10)/5;
  206.     rem = i%5;
  207.     if(rem == 4){
  208.         k += (*f)(*onesp | nrbits);
  209.         if(q)i = *(onesp+1);
  210.             else i = *fivesp;
  211.         return(k += (*f)(i | nrbits));
  212.     }
  213.     if(q)k += (*f)(*fivesp | nrbits);
  214.     while(--rem >= 0)
  215.         k += (*f)(*onesp | nrbits);
  216.     return(k);
  217. }
  218. abc(i,f)
  219. int i, (*f)();
  220. {
  221.     if(!i)return((*f)('0' | nrbits));
  222.     else return(abc0(i-1,f));
  223. }
  224. abc0(i,f)
  225. int i, (*f)();
  226. {
  227.     register j, k;
  228.  
  229.     k = 0;
  230.     if(j=i/26)k = abc0(j-1,f);
  231.     return(k + (*f)((i%26 + nform) | nrbits));
  232. }
  233. wrc(i)
  234. int i;
  235. {
  236.     if(cp >= &cbuf[NC])return(0);
  237.     *cp++ = i;
  238.     return(1);
  239. }
  240. atoi(){
  241.     extern long atoi0();
  242.  
  243.     return((int)atoi0());
  244. }
  245. long atoi0()
  246. {
  247.     register ii, k, cnt;
  248.     long i, acc;
  249.     extern long ckph();
  250.  
  251.     i = 0; acc = 0;
  252.     nonumb = 0;
  253.     cnt = -1;
  254. a0:
  255.     cnt++;
  256.     switch((ii=getch()) & CMASK){
  257.         default:
  258.             ch = ii;
  259.             if(cnt)break;
  260.         case '+':
  261.             i = ckph();
  262.             if(nonumb)break;
  263.             acc += i;
  264.             goto a0;
  265.         case '-':
  266.             i = ckph();
  267.             if(nonumb)break;
  268.             acc -= i;
  269.             goto a0;
  270.         case '*':
  271.             i = ckph();
  272.             if(nonumb)break;
  273.             acc *= i;
  274.             goto a0;
  275.         case '/':
  276.             i = ckph();
  277.             if(nonumb)break;
  278.             if(i == 0){
  279.                 prstrfl("Divide by zero.\n");
  280.                 acc = 0;
  281.             }else acc /= i;
  282.             goto a0;
  283.         case '%':
  284.             i = ckph();
  285.             if(nonumb)break;
  286.             acc %= i;
  287.             goto a0;
  288.         case '&':    /*and*/
  289.             i = ckph();
  290.             if(nonumb)break;
  291.             if((acc > 0) && (i > 0))acc = 1; else acc = 0;
  292.             goto a0;
  293.         case ':':    /*or*/
  294.             i = ckph();
  295.             if(nonumb)break;
  296.             if((acc > 0) || (i > 0))acc = 1; else acc = 0;
  297.             goto a0;
  298.         case '=':
  299.             if(((ii=getch()) & CMASK) != '=')ch = ii;
  300.             i = ckph();
  301.             if(nonumb){acc = 0; break;}
  302.             if(i == acc)acc = 1;
  303.             else acc = 0;
  304.             goto a0;
  305.         case '>':
  306.             k = 0;
  307.             if(((ii=getch()) & CMASK) == '=')k++; else ch =ii;
  308.             i = ckph();
  309.             if(nonumb){acc = 0; break;}
  310.             if(acc > (i - k))acc = 1; else acc = 0;
  311.             goto a0;
  312.         case '<':
  313.             k = 0;
  314.             if(((ii=getch()) & CMASK) == '=')k++; else ch =ii;
  315.             i = ckph();
  316.             if(nonumb){acc = 0; break;}
  317.             if(acc < (i + k))acc = 1; else acc = 0;
  318.             goto a0;
  319.         case ')': break;
  320.         case '(':
  321.             acc = atoi0();
  322.             goto a0;
  323.     }
  324.     return(acc);
  325. }
  326. long ckph(){
  327.     register i;
  328.     long j;
  329.     extern long atoi0();
  330.     extern long atoi1();
  331.  
  332.     if(((i = getch()) & CMASK) == '(')j = atoi0();
  333.     else{
  334.         ch = i;
  335.         j = atoi1();
  336.     }
  337.     return(j);
  338. }
  339. long atoi1()
  340. {
  341.     register i, j, digits;
  342.     long acc;
  343.     int neg, abs, field;
  344.  
  345.     neg = abs = field = digits = 0;
  346.     acc = 0;
  347. a0:
  348.     switch((i = getch()) & CMASK){
  349.         default:
  350.             ch = i;
  351.             break;
  352.         case '+':
  353.             goto a0;
  354.         case '-':
  355.             neg = 1;
  356.             goto a0;
  357.         case '|':
  358.             abs = 1 + neg;
  359.             neg = 0;
  360.             goto a0;
  361.     }
  362. a1:
  363.     while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){
  364.         field++;
  365.         digits++;
  366.         acc = 10*acc + j;
  367.     }
  368.     if((i & CMASK) == '.'){
  369.         field++;
  370.         digits = 0;
  371.         goto a1;
  372.     }
  373.     ch = i;
  374.     if(!field)goto a2;
  375.     switch((i = getch()) & CMASK){
  376.         case 'u':
  377.             i = j = 1;
  378.             break;
  379.         case 'v':    /*VSs - vert spacing*/
  380.             j = lss;
  381.             i = 1;
  382.             break;
  383.         case 'm':    /*Ems*/
  384.             j = EM;
  385.             i = 1;
  386.             break;
  387.         case 'n':    /*Ens*/
  388.             j = EM;
  389. #ifndef NROFF
  390.             i = 2;
  391. #endif
  392. #ifdef NROFF
  393.             i = 1;    /*Same as Ems in NROFF*/
  394. #endif
  395.             break;
  396.         case 'p':    /*Points*/
  397.             j = INCH;
  398.             i = 72;
  399.             break;
  400.         case 'i':    /*Inches*/
  401.             j = INCH;
  402.             i = 1;
  403.             break;
  404.         case 'c':    /*Centimeters*/
  405.             j = INCH*50;
  406.             i = 127;
  407.             break;
  408.         case 'P':    /*Picas*/
  409.             j = INCH;
  410.             i = 6;
  411.             break;
  412.         default:
  413.             j = dfact;
  414.             ch = i;
  415.             i = dfactd;
  416.     }
  417.     if(neg) acc = -acc;
  418.     if(!noscale){
  419.         acc = (acc*j)/i;
  420.     }
  421.     if((field != digits) && (digits > 0))while(digits--)acc /= 10;
  422.     if(abs){
  423.         if(dip != d)j = dip->dnl; else j = v.nl;
  424.         if(!vflag)j = v.hp;
  425.         if(abs == 2)j = -j;
  426.         acc -= j;
  427.     }
  428. a2:
  429.     nonumb = !field;
  430.     return(acc);
  431. }
  432. caserr(){
  433.     register i,j;
  434.  
  435.     lgf++;
  436.     while(!skip() && (i=getrq()) ){
  437.         for(j=NNAMES; j<NN; j++){  /*NNAMES predefined names*/
  438.             if(i == r[j])break;
  439.         }
  440.         if(j!=NN){
  441.             r[j]=vlist[j]=inc[j]=fmt[j]=0;
  442.             regcnt--;
  443.         }
  444.     }
  445. }
  446. casenr(){
  447.     register i, j;
  448.  
  449.     lgf++;
  450.     skip();
  451.     if((i = findr(getrq())) == -1)goto rtn;
  452.     skip();
  453.     j = inumb(&vlist[i]);
  454.     if(nonumb)goto rtn;
  455.     vlist[i] = j;
  456.     skip();
  457.     j = atoi();
  458.     if(nonumb)goto rtn;
  459.     inc[i] = j;
  460. rtn:
  461.     return;
  462. }
  463. caseaf(){
  464.     register i, j, k;
  465.  
  466.     lgf++;
  467.     if(skip() || !(i = getrq()) || skip())return;
  468.     k = 0;
  469.     if(!alph(j=getch())){
  470.         ch = j;
  471.         while(((j = getch() & CMASK) >= '0') &&
  472.             (j <= '9'))k++;
  473.     }
  474.     if(!k)k=j;
  475.     fmt[findr(i)] = k & BMASK;
  476. }
  477. vnumb(i)
  478. int *i;
  479. {
  480.     vflag++;
  481.     dfact = lss;
  482.     res = VERT;
  483.     return(inumb(i));
  484. }
  485. hnumb(i)
  486. int *i;
  487. {
  488.     dfact = EM;
  489.     res = HOR;
  490.     return(inumb(i));
  491. }
  492. inumb(n)
  493. int *n;
  494. {
  495.     register i, j, f;
  496.  
  497.     f = 0;
  498.     if(n){
  499.     if((j = (i = getch()) & CMASK) == '+')f = 1;
  500.         else if(j == '-')f = -1;
  501.             else ch = i;
  502.     }
  503.     i = atoi();
  504.     if(n && f)i = *n + f*i;
  505.     i = quant(i,res);
  506.     vflag = 0;
  507.     res = dfactd = dfact = 1;
  508.     if(nonumb)i = 0;
  509.     return(i);
  510. }
  511. quant(n,m)
  512. int n, m;
  513. {
  514.     register i, neg;
  515.  
  516.     neg = 0;
  517.     if(n<0){
  518.         neg++;
  519.         n = -n;
  520.     }
  521.     i = n/m;
  522.     if((n - m*i) > (m/2))i += 1;
  523.     i *= m;
  524.     if(neg)i = -i;
  525.     return(i);
  526. }
  527.