home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / troff / n3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  10.5 KB  |  666 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. /*
  13. troff3.c
  14.  
  15. macro and string routines, storage allocation
  16. */
  17.  
  18. unsigned blist[NBLIST];
  19. extern struct s *frame, *stk, *nxf;
  20. extern filep ip;
  21. extern filep offset;
  22. extern filep nextb;
  23. extern char *enda;
  24.  
  25. extern int ch;
  26. extern int ibf;
  27. extern int lgf;
  28. extern int copyf;
  29. extern int ch0;
  30. extern int app;
  31. extern int ds;
  32. extern int nlflg;
  33. extern int *argtop;
  34. extern int *ap;
  35. extern int nchar;
  36. extern int pendt;
  37. extern int rchar;
  38. extern int dilev;
  39. extern int nonumb;
  40. extern int lt;
  41. extern int nrbits;
  42. extern int nform;
  43. extern int fmt[];
  44. extern int oldmn;
  45. extern int newmn;
  46. extern int macerr;
  47. extern filep apptr;
  48. extern int diflg;
  49. extern filep woff;
  50. extern filep roff;
  51. extern int wbfi;
  52. extern int po;
  53. extern int *cp;
  54. extern int xxx;
  55. int pagech = '%';
  56. int strflg;
  57. extern struct contab {
  58.     int rq;
  59.     union {
  60.         int (*f)();
  61.         unsigned mx;
  62.     }x;
  63. }contab[NM];
  64. int wbuf[BLK];
  65. int rbuf[BLK];
  66.  
  67. caseig(){
  68.     register i;
  69.  
  70.     offset = 0;
  71.     if((i = copyb()) != '.')control(i,1);
  72. }
  73. casern(){
  74.     register i,j;
  75.  
  76.     lgf++;
  77.     skip();
  78.     if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
  79.     skip();
  80.     clrmn(findmn(j=getrq()));
  81.     if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
  82. }
  83. caserm(){
  84.     lgf++;
  85.     while(!skip()){
  86.         clrmn(findmn(getrq()));
  87.     }
  88. }
  89. caseas(){
  90.     app++;
  91.     caseds();
  92. }
  93. caseds(){
  94.     ds++;
  95.     casede();
  96. }
  97. caseam(){
  98.     app++;
  99.     casede();
  100. }
  101. casede(){
  102.     register i, req;
  103.     register filep savoff;
  104.     extern filep finds();
  105.  
  106.     if(dip != d)wbfl();
  107.     req = '.';
  108.     lgf++;
  109.     skip();
  110.     if((i=getrq())==0)goto de1;
  111.     if((offset=finds(i)) == 0)goto de1;
  112.     if(ds)copys();
  113.         else req = copyb();
  114.     wbfl();
  115.     clrmn(oldmn);
  116.     if(newmn)contab[newmn].rq = i | MMASK;
  117.     if(apptr){
  118.         savoff = offset;
  119.         offset = apptr;
  120.         wbt(IMP);
  121.         offset = savoff;
  122.     }
  123.     offset = dip->op;
  124.     if(req != '.')control(req,1);
  125. de1:
  126.     ds = app = 0;
  127.     return;
  128. }
  129. findmn(i)
  130. int i;
  131. {
  132.     register j;
  133.  
  134.     for(j=0;j<NM;j++){
  135.         if(i == (contab[j].rq & ~MMASK))break;
  136.     }
  137.     if(j==NM)j = -1;
  138.     return(j);
  139. }
  140. clrmn(i)
  141. int i;
  142. {
  143.     extern filep boff();
  144.     if(i >= 0){
  145.         if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
  146.         contab[i].rq = 0;
  147.         contab[i].x.mx = 0;
  148.     }
  149. }
  150. filep finds(mn)
  151. int mn;
  152. {
  153.     register i;
  154.     extern filep boff();
  155.     register filep savip;
  156.     extern filep alloc();
  157.     extern filep incoff();
  158.  
  159.     oldmn = findmn(mn);
  160.     newmn = 0;
  161.     apptr = (filep)0;
  162.     if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
  163.             savip = ip;
  164.             ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
  165.             oldmn = -1;
  166.             while((i=rbf()) != 0);
  167.             apptr = ip;
  168.             if(!diflg)ip = incoff(ip);
  169.             nextb = ip;
  170.             ip = savip;
  171.     }else{
  172.         for(i=0;i<NM;i++){
  173.             if(contab[i].rq == 0)break;
  174.         }
  175.         if((i==NM) ||
  176.            (nextb = alloc()) == 0){
  177.             app = 0;
  178.             if(macerr++ > 1)done2(02);
  179.             prstr("Too many string/macro names.\n");
  180.             edone(04);
  181.             return(offset = 0);
  182.         }
  183.             contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
  184.         if(!diflg){
  185.             newmn = i;
  186.             if(oldmn == -1)contab[i].rq = -1;
  187.         }else{
  188.             contab[i].rq = mn | MMASK;
  189.         }
  190.     }
  191.  
  192.     app = 0;
  193.     return(offset = nextb);
  194. }
  195. skip(){
  196.     register i;
  197.  
  198.     while(((i=getch()) & CMASK) == ' ');
  199.     ch=i;
  200.     return(nlflg);
  201. }
  202. copyb()
  203. {
  204.     register i, j, k;
  205.     int ii, req, state;
  206.     filep savoff;
  207.  
  208.     if(skip() || !(j=getrq()))j = '.';
  209.     req = j;
  210.     k = j>>BYTE;
  211.     j &= BMASK;
  212.     copyf++;
  213.     flushi();
  214.     nlflg = 0;
  215.     state = 1;
  216.     while(1){
  217.         i = (ii = getch()) & CMASK;
  218.         if(state == 3){
  219.             if(i == k)break;
  220.             if(!k){
  221.                 ch = ii;
  222.                 i = getach();
  223.                 ch = ii;
  224.                 if(!i)break;
  225.             }
  226.             state = 0;
  227.             goto c0;
  228.         }
  229.         if(i == '\n'){
  230.             state = 1;
  231.             nlflg = 0;
  232.             goto c0;
  233.         }
  234.         if((state == 1) && (i == '.')){
  235.             state++;
  236.             savoff = offset;
  237.             goto c0;
  238.         }
  239.         if((state == 2) && (i == j)){
  240.             state++;
  241.             goto c0;
  242.         }
  243.         state = 0;
  244. c0:
  245.         if(offset)wbf(ii);
  246.     }
  247.     if(offset){
  248.         wbfl();
  249.         offset = savoff;
  250.         wbt(0);
  251.     }
  252.     copyf--;
  253.     return(req);
  254. }
  255. copys()
  256. {
  257.     register i;
  258.  
  259.     copyf++;
  260.     if(skip())goto c0;
  261.     if(((i=getch()) & CMASK) != '"')wbf(i);
  262.     while(((i=getch()) & CMASK) != '\n')wbf(i);
  263. c0:
  264.     wbt(0);
  265.     copyf--;
  266. }
  267. filep alloc()
  268. {
  269.     register i;
  270.     extern filep boff();
  271.     filep j;
  272.  
  273.     for(i=0;i<NBLIST;i++){
  274.         if(blist[i] == 0)break;
  275.     }
  276.     if(i==NBLIST){
  277.         j = 0;
  278.     }else{
  279.         blist[i] = -1;
  280.         if((j = boff(i)) < NEV*EVS)j = 0;
  281.     }
  282.     return(nextb = j);
  283. }
  284. ffree(i)
  285. filep i;
  286. {
  287.     register j;
  288.  
  289.     while((blist[j = blisti(i)]) != -1){
  290.         i = ((filep)blist[j])<<BLKBITS;
  291.         blist[j] = 0;
  292.     }
  293.     blist[j] = 0;
  294. }
  295. filep boff(i)
  296. int i;
  297. {
  298.     return(((filep)i)*BLK + NEV*EVS);
  299. }
  300. wbt(i)
  301. int i;
  302. {
  303.     wbf(i);
  304.     wbfl();
  305. }
  306. wbf(i)
  307. int i;
  308. {
  309.     register j;
  310.  
  311.     if(!offset)return;
  312.     if(!woff){
  313.         woff = offset;
  314.         wbfi = 0;
  315.     }
  316.     wbuf[wbfi++] = i;
  317.     if(!((++offset) & (BLK-1))){
  318.         wbfl();
  319.         if(blist[j = blisti(--offset)] == -1){
  320.             if(alloc() == 0){
  321.                 prstr("Out of temp file space.\n");
  322.                 done2(01);
  323.             }
  324.             blist[j] = (unsigned)(nextb>>BLKBITS);
  325.         }
  326.         offset = ((filep)blist[j])<<BLKBITS;
  327.     }
  328.     if(wbfi >= BLK)wbfl();
  329. }
  330. wbfl(){
  331.     if(woff == 0)return;
  332.     lseek(ibf, ((long)woff) * sizeof(int), 0);
  333.     write(ibf, (char *)wbuf, wbfi * sizeof(int));
  334.     if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
  335.     woff = 0;
  336. }
  337. blisti(i)
  338. filep i;
  339. {
  340.     return((i-NEV*EVS)/(BLK));
  341. }
  342. rbf(){
  343.     register i;
  344.     extern filep incoff();
  345.  
  346.     if((i=rbf0(ip)) == 0){
  347.         if(!app)i = popi();
  348.     }else{
  349.         ip = incoff(ip);
  350.     }
  351.     return(i);
  352. }
  353. rbf0(p)
  354. filep p;
  355. {
  356.     register filep i;
  357.  
  358.     if((i = (p & (~(BLK-1)))) != roff){
  359.         roff = i;
  360.         lseek(ibf, ((long)roff) * sizeof(int), 0);
  361.         if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
  362.     }
  363.     return(rbuf[p & (BLK-1)]);
  364. }
  365. filep incoff(p)
  366. filep p;
  367. {
  368.     register i;
  369.     register filep j;
  370.     if(!((j = (++p)) & (BLK-1))){
  371.         if((i = blist[blisti(--p)]) == -1){
  372.             prstr("Bad storage allocation.\n");
  373.             done2(-5);
  374.         }
  375.         j = ((filep)i)<<BLKBITS;
  376.     }
  377.     return(j);
  378. }
  379. popi(){
  380.     register struct s *p;
  381.  
  382.     if(frame == stk)return(0);
  383.     if(strflg)strflg--;
  384.     p = nxf = frame;
  385.     p->nargs = 0;
  386.     frame = p->pframe;
  387.     ip = p->pip;
  388.     nchar = p->pnchar;
  389.     rchar = p->prchar;
  390.     pendt = p->ppendt;
  391.     ap = p->pap;
  392.     cp = p->pcp;
  393.     ch0 = p->pch0;
  394.     return(p->pch);
  395. }
  396. pushi(newip)
  397. filep newip;
  398. {
  399.     register struct s *p;
  400.     extern char *setbrk();
  401.  
  402.     if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA);
  403.     p = nxf;
  404.     p->pframe = frame;
  405.     p->pip = ip;
  406.     p->pnchar = nchar;
  407.     p->prchar = rchar;
  408.     p->ppendt = pendt;
  409.     p->pap = ap;
  410.     p->pcp = cp;
  411.     p->pch0 = ch0;
  412.     p->pch = ch;
  413.     cp = ap = 0;
  414.     nchar = rchar = pendt = ch0 = ch = 0;
  415.     frame = nxf;
  416.     if(nxf->nargs == 0) nxf += 1;
  417.         else nxf = (struct s *)argtop;
  418.     return(ip = newip);
  419. }
  420. char *setbrk(x)
  421. int x;
  422. {
  423.     register char *i;
  424.     char *sbrk();
  425.  
  426.     if((i = sbrk(x)) == MAXPTR){
  427.         prstrfl("Core limit reached.\n");
  428.         edone(0100);
  429.     }else{
  430.         enda = i + x;
  431.     }
  432.     return(i);
  433. }
  434. getsn(){
  435.     register i;
  436.  
  437.     if((i=getach()) == 0)return(0);
  438.     if(i == '(')return(getrq());
  439.         else return(i);
  440. }
  441. setstr(){
  442.     register i;
  443.  
  444.     lgf++;
  445.     if(((i=getsn()) == 0) ||
  446.        ((i=findmn(i)) == -1) ||
  447.        !(contab[i].rq & MMASK)){
  448.         lgf--;
  449.         return(0);
  450.     }else{
  451.         if((enda-2) < (char *)nxf)setbrk(DELTA);
  452.         nxf->nargs = 0;
  453.         strflg++;
  454.         lgf--;
  455.         return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
  456.     }
  457. }
  458. collect()
  459. {
  460.     register i;
  461.     register int *strp;
  462.     int *lim;
  463.     int **argpp, **argppend;
  464.     int quote;
  465.     struct s *savnxf;
  466.  
  467.     copyf++;
  468.     nxf->nargs = 0;
  469.     savnxf = nxf;
  470.     if(skip())goto rtn;
  471.     lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf));
  472.     strflg = 0;
  473.     if((argppend =
  474.         (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + (sizeof(struct s)-1))
  475.         > (int **)enda)setbrk(DELTA);
  476.     strp = (int *)argppend;
  477.     for(i=8; i>=0; i--)argpp[i] = 0;
  478.     while((argpp != argppend) && (!skip())){
  479.         *argpp++ = strp;
  480.         quote = 0;
  481.         if(((i = getch()) & CMASK) == '"')quote++;
  482.             else ch = i;
  483.         while(1){
  484.             i = getch();
  485.             if( nlflg ||
  486.               ((!quote) && ((i & CMASK) == ' ')))break;
  487.             if(quote && ((i & CMASK) == '"') &&
  488.               (((i=getch()) & CMASK) != '"')){
  489.                 ch = i;
  490.                 break;
  491.             }
  492.             *strp++ = i;
  493.             if(strflg && (strp >= lim)){
  494.                 prstrfl("Macro argument too long.\n");
  495.                 copyf--;
  496.                 edone(004);
  497.             }
  498.             if((enda-4) <= (char *)strp)setbrk(DELTA);
  499.         }
  500.         *strp++ = 0;
  501.     }
  502.     nxf = savnxf;
  503.     nxf->nargs = argpp -(int **)(nxf + 1);
  504.     argtop = strp;
  505. rtn:
  506.     copyf--;
  507. }
  508. seta()
  509. {
  510.     register i;
  511.  
  512.     if(((i = (getch() & CMASK) - '0') > 0) &&
  513.         (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
  514. }
  515. caseda(){
  516.     app++;
  517.     casedi();
  518. }
  519. casedi(){
  520.     register i, j;
  521.     register *k;
  522.  
  523.     lgf++;
  524.     if(skip() || ((i=getrq()) == 0)){
  525.         if(dip != d)wbt(0);
  526.         if(dilev > 0){
  527.             v.dn = dip->dnl;
  528.             v.dl = dip->maxl;
  529.             dip = &d[--dilev];
  530.             offset = dip->op;
  531.         }
  532.         goto rtn;
  533.     }
  534.     if(++dilev == NDI){
  535.         --dilev;
  536.         prstr("Cannot divert.\n");
  537.         edone(02);
  538.     }
  539.     if(dip != d)wbt(0);
  540.     diflg++;
  541.     dip = &d[dilev];
  542.     dip->op = finds(i);
  543.     dip->curd = i;
  544.     clrmn(oldmn);
  545.     k = (int *)&dip->dnl;
  546.     for(j=0; j<10; j++)k[j] = 0;    /*not op and curd*/
  547. rtn:
  548.     app = 0;
  549.     diflg = 0;
  550. }
  551. casedt(){
  552.     lgf++;
  553.     dip->dimac = dip->ditrap = dip->ditf = 0;
  554.     skip();
  555.     dip->ditrap = vnumb((int *)0);
  556.     if(nonumb)return;
  557.     skip();
  558.     dip->dimac = getrq();
  559. }
  560. casetl(){
  561.     register i, j;
  562.     int w1, w2, w3, delim;
  563.     filep begin;
  564.     extern width(), pchar();
  565.  
  566.     dip->nls = 0;
  567.     skip();
  568.     if(dip != d)wbfl();
  569.     if((offset = begin = alloc()) == 0)return;
  570.     if((delim = getch()) & MOT){
  571.         ch = delim;
  572.         delim = '\'';
  573.     }else delim &= CMASK;
  574.     if(!nlflg)
  575.         while(((i = getch()) & CMASK) != '\n'){
  576.             if((i & CMASK) == delim)i = IMP;
  577.             wbf(i);
  578.         }
  579.     wbf(IMP);wbf(IMP);wbt(0);
  580.  
  581.     w1 = hseg(width,begin);
  582.     w2 = hseg(width,(filep)0);
  583.     w3 = hseg(width,(filep)0);
  584.     offset = dip->op;
  585. #ifdef NROFF
  586.     if(!offset)horiz(po);
  587. #endif
  588.     hseg(pchar,begin);
  589.     if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
  590.     hseg(pchar,(filep)0);
  591.     if(w3){
  592.         horiz(lt-w1-w2-w3-j);
  593.         hseg(pchar,(filep)0);
  594.     }
  595.     newline(0);
  596.     if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
  597.     else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
  598.     ffree(begin);
  599. }
  600. casepc(){
  601.     pagech = chget(IMP);
  602. }
  603. hseg(f,p)
  604. int (*f)();
  605. filep p;
  606. {
  607.     register acc, i;
  608.     static filep q;
  609.  
  610.     acc = 0;
  611.     if(p)q = p;
  612.     while(1){
  613.         i = rbf0(q);
  614.         q = incoff(q);
  615.         if(!i || (i == IMP))return(acc);
  616.         if((i & CMASK) == pagech){
  617.             nrbits = i & ~CMASK;
  618.             nform = fmt[findr('%')];
  619.             acc += fnumb(v.pn,f);
  620.         }else acc += (*f)(i);
  621.     }
  622. }
  623. casepm(){
  624.     register i, k;
  625.     register char *p;
  626.     int xx, cnt, kk, tot;
  627.     filep j;
  628.     char *kvt();
  629.     char pmline[10];
  630.  
  631.     kk = cnt = 0;
  632.     tot = !skip();
  633.     for(i = 0; i<NM; i++){
  634.         if(!((xx = contab[i].rq) & MMASK))continue;
  635.         p = pmline;
  636.         j = (((filep)contab[i].x.mx)<<BLKBITS);
  637.         k = 1;
  638.         while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
  639.         cnt++;
  640.         kk += k;
  641.         if(!tot){
  642.             *p++ = xx & 0177;
  643.             if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
  644.             *p++ = ' ';
  645.             kvt(k,p);
  646.             prstr(pmline);
  647.         }
  648.     }
  649.     if(tot || (cnt > 1)){
  650.         kvt(kk,pmline);
  651.         prstr(pmline);
  652.     }
  653. }
  654. char *kvt(k,p)
  655. int k;
  656. char *p;
  657. {
  658.     if(k>=100)*p++ = k/100 + '0';
  659.     if(k>=10)*p++ = (k%100)/10 + '0';
  660.     *p++ = k%10 + '0';
  661.     *p++ = '\n';
  662.     *p = 0;
  663.     return(p);
  664. }
  665. dummy(){}
  666.