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

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include "tdef.h"
  4. extern
  5. #include "d.h"
  6. extern
  7. #include "v.h"
  8. #ifdef NROFF
  9. extern
  10. #include "tw.h"
  11. #endif
  12. #include "s.h"
  13. #include <setjmp.h>
  14. jmp_buf sjbuf;
  15. #include    <sgtty.h>
  16. /*
  17. troff1.c
  18.  
  19. consume options, initialization, main loop,
  20. input routines, escape function calling
  21. */
  22.  
  23. extern struct s *frame, *stk, *nxf;
  24. extern struct s *ejl, *litlev;
  25. extern filep ip;
  26. extern filep offset;
  27. extern filep nextb;
  28.  
  29.  
  30. extern int stdi;
  31. extern int waitf;
  32. extern int nofeed;
  33. extern int quiet;
  34. extern int ptid;
  35. extern int ascii;
  36. extern int npn;
  37. extern int xflg;
  38. extern int stop;
  39. extern char ibuf[IBUFSZ];
  40. extern char xbuf[IBUFSZ];
  41. extern char *ibufp;
  42. extern char *xbufp;
  43. extern char *eibuf;
  44. extern char *xeibuf;
  45. extern int cbuf[NC];
  46. extern int *cp;
  47. extern int *vlist;
  48. extern int nx;
  49. extern int mflg;
  50. extern int ch;
  51. extern int pto;
  52. extern int pfrom;
  53. extern int cps;
  54. extern int chbits;
  55. extern int ibf;
  56. extern int ttyod;
  57. extern struct sgttyb ttys;
  58. extern int iflg;
  59. extern int init;
  60. extern int rargc;
  61. extern char **argp;
  62. extern char trtab[256];
  63. extern int lgf;
  64. extern int copyf;
  65. extern int eschar;
  66. extern int ch0;
  67. extern int cwidth;
  68. extern int nlflg;
  69. extern int *ap;
  70. extern int donef;
  71. extern int nflush;
  72. extern int nchar;
  73. extern int rchar;
  74. extern int nfo;
  75. extern int ifile;
  76. extern int fc;
  77. extern int padc;
  78. extern int tabc;
  79. extern int dotc;
  80. extern int raw;
  81. extern int tabtab[NTAB];
  82. extern char nextf[];
  83. extern int nfi;
  84. #ifdef NROFF
  85. extern char termtab[];
  86. extern int tti;
  87. #endif
  88. extern int ifl[NSO];
  89. extern int ifi;
  90. extern int pendt;
  91. extern int flss;
  92. extern int fi;
  93. extern int lg;
  94. extern char ptname[];
  95. extern int print;
  96. extern int nonumb;
  97. extern int pnlist[];
  98. extern int *pnp;
  99. extern int nb;
  100. extern int trap;
  101. extern int tflg;
  102. extern int ejf;
  103. extern int lit;
  104. extern int cc;
  105. extern int c2;
  106. extern int spread;
  107. extern int gflag;
  108. extern int oline[];
  109. extern int *olinep;
  110. extern int dpn;
  111. extern int noscale;
  112. extern char *unlkp;
  113. extern int pts;
  114. extern int level;
  115. extern int ttysave;
  116. extern int tdelim;
  117. extern int dotT;
  118. extern int tabch, ldrch;
  119. extern int eqflg;
  120. extern no_out;
  121. extern int hflg;
  122. #ifndef NROFF
  123. extern char codetab[];
  124. extern int spbits;
  125. #endif
  126. extern int xxx;
  127. int stopmesg;
  128. filep ipl[NSO];
  129. long offl[NSO];
  130. long ioff;
  131. char *ttyp;
  132. extern struct contab {
  133.     int rq;
  134.     union {
  135.         int (*f)();
  136.         unsigned mx;
  137.     }x;
  138. }contab[NM];
  139. int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31};
  140. #ifndef NROFF
  141. int acctf;
  142. #endif
  143.  
  144. main(argc,argv)
  145. int argc;
  146. char **argv;
  147. {
  148.     char *p, *q;
  149.     register i, j;
  150.     extern catch(), fpecatch(), kcatch();
  151.  
  152.     signal(SIGHUP,catch);
  153.     if(signal(SIGINT,catch) == SIG_IGN){
  154.         signal(SIGHUP,SIG_IGN);
  155.         signal(SIGINT,SIG_IGN);
  156.         signal(SIGQUIT,SIG_IGN);
  157.     }
  158.     signal(SIGFPE,fpecatch);
  159.     signal(SIGPIPE,catch);
  160.     signal(SIGTERM,kcatch);
  161.     init1(argv[0][0]);
  162. options:
  163.     while(--argc > 0 && (++argv)[0][0]=='-')
  164.         switch(argv[0][1]){
  165.  
  166.         case 0:
  167.             goto start;
  168.         case 'i':
  169.             stdi++;
  170.             continue;
  171.         case 'q':
  172.             quiet++;
  173.             if(gtty(0, &ttys) >= 0)
  174.                 ttysave = ttys.sg_flags;
  175.             continue;
  176.         case 'n':
  177.             npn = cnum(&argv[0][2]);
  178.             continue;
  179.         case 'p':
  180.             xflg = 0;
  181.             cps = cnum(&argv[0][2]);
  182.             continue;
  183.         case 'S':
  184.             stopmesg++;
  185.             continue;
  186.         case 's':
  187.             if(!(stop = cnum(&argv[0][2])))stop++;
  188.             continue;
  189.         case 'r':
  190.             vlist[findr(argv[0][2])] = cnum(&argv[0][3]);
  191.             continue;
  192.         case 'm':
  193.             p = &nextf[nfi];
  194.             q = &argv[0][2];
  195.             while((*p++ = *q++) != 0);
  196.             mflg++;
  197.             continue;
  198.         case 'o':
  199.             getpn(&argv[0][2]);
  200.             continue;
  201. #ifdef NROFF
  202.         case 'h':
  203.             hflg++;
  204.             continue;
  205.         case 'z':
  206.             no_out++;
  207.             continue;
  208.         case 'e':
  209.             eqflg++;
  210.             continue;
  211.         case 'T':
  212.             p = &termtab[tti];
  213.             q = &argv[0][2];
  214.             if(!((*q) & 0177))continue;
  215.             while((*p++ = *q++) != 0);
  216.             dotT++;
  217.             continue;
  218. #endif
  219. #ifndef NROFF
  220.         case 'z':
  221.             no_out++;
  222.         case 'a':
  223.             ascii = 1;
  224.             nofeed++;
  225.         case 't':
  226.             ptid = 1;
  227.             continue;
  228.         case 'w':
  229.             waitf = 1;
  230.             continue;
  231.         case 'f':
  232.             nofeed++;
  233.             continue;
  234.         case 'x':
  235.             xflg = 0;
  236.             continue;
  237.         case 'b':
  238.             if(open(ptname,1) < 0)prstr("Busy.\n");
  239.             else prstr("Available.\n");
  240.             done3(0);
  241.         case 'g':
  242.             stop = ptid = gflag = 1;
  243.             dpn = 0;
  244.             continue;
  245. #endif
  246.         default:
  247.             pto = cnum(&argv[0][1]);
  248.             continue;
  249.         }
  250.  
  251.     if(argv[0][0] == '+'){
  252.         pfrom = cnum(&argv[0][1]);
  253.         print = 0;
  254.         if(argc > 0)goto options;
  255.     }
  256.  
  257. start:
  258.     argp = argv;
  259.     rargc = argc;
  260.     init2();
  261.     setjmp(sjbuf);
  262. loop:
  263.     copyf = lgf = nb = nflush = nlflg = 0;
  264.     if(ip && (rbf0(ip)==0) && ejf && (frame->pframe <= ejl)){
  265.         nflush++;
  266.         trap = 0;
  267.         eject((struct s *)0);
  268.         goto loop;
  269.     }
  270.     i = getch();
  271.     if(pendt)goto lt;
  272.     if(lit && (frame <= litlev)){
  273.         lit--;
  274.         goto lt;
  275.     }
  276.     if((j = (i & CMASK)) == XPAR){
  277.         copyf++;
  278.         tflg++;
  279.         for(;(i & CMASK) != '\n';)pchar(i = getch());
  280.         tflg = 0;
  281.         copyf--;
  282.         goto loop;
  283.     }
  284.     if((j == cc) || (j == c2)){
  285.         if(j == c2)nb++;
  286.         copyf++;
  287.         while(((j=((i=getch()) & CMASK)) == ' ') ||
  288.             (j == '\t'));
  289.         ch = i;
  290.         copyf--;
  291.         control(getrq(),1);
  292.         flushi();
  293.         goto loop;
  294.     }
  295. lt:
  296.     ch = i;
  297.     text();
  298.     goto loop;
  299. }
  300. catch(){
  301. /*
  302.     prstr("Interrupt\n");
  303. */
  304.     done3(01);
  305. }
  306. fpecatch(){
  307.     prstrfl("Floating Exception.\n");
  308.     signal(SIGFPE,fpecatch);
  309. }
  310. kcatch(){
  311.     signal(SIGTERM,SIG_IGN);
  312.     done3(01);
  313. }
  314. #ifndef NROFF
  315. acctg() {
  316.     static char *acct_file = "/usr/adm/tracct";
  317.     acctf = open(acct_file,1);
  318.     setuid(getuid());
  319. }
  320. #endif
  321. init1(a)
  322. char a;
  323. {
  324.     register char *p;
  325.     char *mktemp();
  326.     register i;
  327.  
  328. #ifndef NROFF
  329.     acctg();/*open troff actg file while mode 4755*/
  330. #endif
  331.     p = mktemp("/tmp/taXXXXX");
  332.     if(a == 'a')p = &p[5];
  333.     if((close(creat(p, 0600))) < 0){
  334.         prstr("Cannot create temp file.\n");
  335.         exit(-1);
  336.     }
  337.     ibf = open(p, 2);
  338.     for(i=256; --i;)trtab[i]=i;
  339.     trtab[UNPAD] = ' ';
  340.     mchbits();
  341.     if(a != 'a')unlkp = p;
  342. }
  343. init2()
  344. {
  345.     register i,j;
  346.     extern int block;
  347.     extern char *setbrk();
  348.     extern char *ttyname();
  349.  
  350.     ttyod = 2;
  351.     if(((ttyp=ttyname(j=0)) != (char *)0) ||
  352.        ((ttyp=ttyname(j=1)) != (char *)0) ||
  353.        ((ttyp=ttyname(j=2)) != (char *)0)
  354.       );else ttyp = "notty";
  355.     iflg = j;
  356.     if(ascii)mesg(0);
  357.  
  358.     if((!ptid) && (!waitf)){
  359.         if((ptid = open(ptname,1)) < 0){
  360.             prstr("Typesetter busy.\n");
  361.             done3(-2);
  362.         }
  363.     }
  364.     ptinit();
  365.     for(i=NEV; i--;)write(ibf, (char *)&block, EVS*sizeof(int));
  366.     olinep = oline;
  367.     ibufp = eibuf = ibuf;
  368.     v.hp = init = 0;
  369.     ioff = 0;
  370.     v.nl = -1;
  371.     cvtime();
  372.     frame = stk = (struct s *)setbrk(DELTA);
  373.     dip = &d[0];
  374.     nxf = frame + 1;
  375.     nx = mflg;
  376. }
  377. cvtime(){
  378.  
  379.     long tt;
  380.     register i;
  381.  
  382.     time(&tt);
  383.     tt -= 3600*ZONE;    /*5hrs for EST*/
  384.     v.dy = (tt/86400L) + 1;
  385.     v.dw = (v.dy + 3)%7 + 1;
  386.     for(v.yr=70;; v.yr++){
  387.         if((v.yr)%4)ms[1]=28;else ms[1]=29;
  388.         for(i=0;i<12;){
  389.             if(v.dy<=ms[i]){
  390.                 v.mo = i+1;
  391.                 return;
  392.             }
  393.             v.dy -= ms[i++];
  394.         }
  395.     }
  396. }
  397. cnum(a)
  398. char *a;
  399. {
  400.     register i;
  401.  
  402.     ibufp = a;
  403.     eibuf = MAXPTR;
  404.     i = atoi();
  405.     ch = 0;
  406.     return(i);
  407. }
  408. mesg(f)
  409. int f;
  410. {
  411.     static int mode;
  412.  
  413.     if(!f){
  414.         stat(ttyp,cbuf);
  415.         mode = ((struct stat *)(cbuf))->st_mode;
  416.         chmod(ttyp,mode & ~022);
  417.     }else{
  418.         chmod(ttyp,mode);
  419.     }
  420. }
  421. prstrfl(s)
  422. char *s;
  423. {
  424.     flusho();
  425.     prstr(s);
  426. }
  427. prstr(s)
  428. char *s;
  429. {
  430.     register i;
  431.     register char *j;
  432.  
  433.     j = s;
  434.     for(i=0;*s;i++)s++;
  435.     write(ttyod,j,i);
  436. }
  437. control(a,b)
  438. int a,b;
  439. {
  440.     register i,j;
  441.     extern filep boff();
  442.  
  443.     i = a;
  444.     if((i == 0) || ((j = findmn(i)) == -1))return(0);
  445.     if(contab[j].rq & MMASK){
  446.         nxf->nargs = 0;
  447.         if(b)collect();
  448.         flushi();
  449.         return(pushi(((filep)contab[j].x.mx)<<BLKBITS));
  450.     }else{
  451.         if(!b)return(0);
  452.         return((*contab[j].x.f)(0));
  453.     }
  454. }
  455.  
  456. getrq(){
  457.     register i,j;
  458.  
  459.     if(((i=getach()) == 0) ||
  460.        ((j=getach()) == 0))goto rtn;
  461.     i = PAIR(i,j);
  462. rtn:
  463.     return(i);
  464. }
  465. getch(){
  466.     register int i, j, k;
  467.  
  468.     level++;
  469. g0:
  470.     if(ch){
  471.         if(((i = ch) & CMASK) == '\n')nlflg++;
  472.         ch = 0;
  473.         level--;
  474.         return(i);
  475.     }
  476.  
  477.     if(nlflg){
  478.         level--;
  479.         return('\n');
  480.     }
  481.  
  482.     if((k = (i = getch0()) & CMASK) != ESC){
  483.         if(i & MOT)goto g2;
  484.         if(k == FLSS){
  485.             copyf++; raw++;
  486.             i = getch0();
  487.             if(!fi)flss = i;
  488.             copyf--; raw--;
  489.             goto g0;
  490.         }
  491.         if(k == RPT){
  492.             setrpt();
  493.             goto g0;
  494.         }
  495.         if(!copyf){
  496.             if((k == 'f') && lg && !lgf){
  497.                 i = getlg(i);
  498.                 goto g2;
  499.             }
  500.             if((k == fc) || (k == tabch) || (k == ldrch)){
  501.                 if((i=setfield(k)) == 0)goto g0; else goto g2;
  502.             }
  503.             if(k == 010){
  504.                 i = makem(-width(' ' | chbits));
  505.                 goto g2;
  506.             }
  507.         }
  508.         goto g2;
  509.     }
  510.     k = (j = getch0()) & CMASK;
  511.     if(j & MOT){
  512.         i = j;
  513.         goto g2;
  514.     }
  515. /*
  516.     if(k == tdelim){
  517.         i = TDELIM;
  518.         tdelim = IMP;
  519.         goto g2;
  520.     }
  521. */
  522.     switch(k){
  523.  
  524.         case '\n':    /*concealed newline*/
  525.             goto g0;
  526.         case 'n':    /*number register*/
  527.             setn();
  528.             goto g0;
  529.         case '*':    /*string indicator*/
  530.             setstr();
  531.             goto g0;
  532.         case '$':    /*argument indicator*/
  533.             seta();
  534.             goto g0;
  535.         case '{':    /*LEFT*/
  536.             i = LEFT;
  537.             goto gx;
  538.         case '}':    /*RIGHT*/
  539.             i = RIGHT;
  540.             goto gx;
  541.         case '"':    /*comment*/
  542.             while(((i=getch0()) & CMASK ) != '\n');
  543.             goto g2;
  544.         case ESC:    /*double backslash*/
  545.             i = eschar;
  546.             goto gx;
  547.         case 'e':    /*printable version of current eschar*/
  548.             i = PRESC;
  549.             goto gx;
  550.         case ' ':    /*unpaddable space*/
  551.             i = UNPAD;
  552.             goto gx;
  553.         case '|':    /*narrow space*/
  554.             i = NARSP;
  555.             goto gx;
  556.         case '^':    /*half of narrow space*/
  557.             i = HNSP;
  558.             goto gx;
  559.         case '\'':    /*\(aa*/
  560.             i = 0222;
  561.             goto gx;
  562.         case '`':    /*\(ga*/
  563.             i = 0223;
  564.             goto gx;
  565.         case '_':    /*\(ul*/
  566.             i = 0224;
  567.             goto gx;
  568.         case '-':    /*current font minus*/
  569.             i = 0210;
  570.             goto gx;
  571.         case '&':    /*filler*/
  572.             i = FILLER;
  573.             goto gx;
  574.         case 'c':    /*to be continued*/
  575.             i = CONT;
  576.             goto gx;
  577.         case ':':    /*lem's char*/
  578.             i = COLON;
  579.             goto gx;
  580.         case '!':    /*transparent indicator*/
  581.             i = XPAR;
  582.             goto gx;
  583.         case 't':    /*tab*/
  584.             i = '\t';
  585.             goto g2;
  586.         case 'a':    /*leader (SOH)*/
  587.             i = LEADER;
  588.             goto g2;
  589.         case '%':    /*ohc*/
  590.             i = OHC;
  591.             goto g2;
  592.         case '.':    /*.*/
  593.             i = '.';
  594.         gx:
  595.             i = (j & ~CMASK) | i;
  596.             goto g2;
  597.     }
  598.     if(!copyf)
  599.         switch(k){
  600.  
  601.             case 'p':    /*spread*/
  602.                 spread++;
  603.                 goto g0;
  604.             case '(':    /*special char name*/
  605.                 if((i=setch()) == 0)goto g0;
  606.                 break;
  607.             case 's':    /*size indicator*/
  608.                 setps();
  609.                 goto g0;
  610.             case 'f':    /*font indicator*/
  611.                 setfont(0);
  612.                 goto g0;
  613.             case 'w':    /*width function*/
  614.                 setwd();
  615.                 goto g0;
  616.             case 'v':    /*vert mot*/
  617.                 if(i = vmot())break;
  618.                 goto g0;
  619.             case 'h':     /*horiz mot*/
  620.                 if(i = hmot())break;
  621.                 goto g0;
  622.             case 'z':    /*zero with char*/
  623.                 i = setz();
  624.                 break;
  625.             case 'l':    /*hor line*/
  626.                 setline();
  627.                 goto g0;
  628.             case 'L':    /*vert line*/
  629.                 setvline();
  630.                 goto g0;
  631.             case 'b':    /*bracket*/
  632.                 setbra();
  633.                 goto g0;
  634.             case 'o':    /*overstrike*/
  635.                 setov();
  636.                 goto g0;
  637.             case 'k':    /*mark hor place*/
  638.                 if((i=findr(getsn())) == -1)goto g0;
  639.                 vlist[i] = v.hp;
  640.                 goto g0;
  641.             case 'j':    /*mark output hor place*/
  642.                 if(!(i=getach()))goto g0;
  643.                 i = (i<<BYTE) | JREG;
  644.                 break;
  645.             case '0':    /*number space*/
  646.                 i = makem(width('0' | chbits));
  647.                 break;
  648.             case 'x':    /*extra line space*/
  649.                 if(i = xlss())break;
  650.                 goto g0;
  651.             case 'u':    /*half em up*/
  652.             case 'r':    /*full em up*/
  653.             case 'd':    /*half em down*/
  654.                 i = sethl(k);
  655.                 break;
  656.             default:
  657.                 i = j;
  658.         }
  659.     else{
  660.         ch0 = j;
  661.         i = eschar;
  662.     }
  663. g2:
  664.     if((i & CMASK) == '\n'){
  665.         nlflg++;
  666.         v.hp = 0;
  667.         if(ip == 0)v.cd++;
  668.     }
  669.     if(!--level){
  670.         j = width(i);
  671.         v.hp += j;
  672.         cwidth = j;
  673.     }
  674.     return(i);
  675. }
  676. char ifilt[32] = {0,001,002,003,0,005,006,007,010,011,012};
  677. getch0(){
  678.     register int i, j;
  679.  
  680.     if(ch0){i=ch0; ch0=0; return(i);}
  681.     if(nchar){nchar--; return(rchar);}
  682.  
  683. again:
  684.     if(cp){
  685.         if((i = *cp++) == 0){
  686.             cp = 0;
  687.             goto again;
  688.         }
  689.     }else if(ap){
  690.         if((i = *ap++) == 0){
  691.             ap = 0;
  692.             goto again;
  693.         }
  694.     }else if(ip){
  695.         if(ip == -1)i = rdtty();
  696.         else i = rbf();
  697.     }else{
  698.         if(donef)done(0);
  699.         if(nx || ((ibufp >= eibuf) && (ibufp != MAXPTR))){
  700.             if(nfo)goto g1;
  701.         g0:
  702.             if(nextfile()){
  703.                 if(ip)goto again;
  704.                 if(ibufp < eibuf)goto g2;
  705.             }
  706.         g1:
  707.             nx = 0;
  708.             if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0;
  709.             ibufp = ibuf;
  710.             eibuf = ibuf + j;
  711.             if(ip)goto again;
  712.         }
  713.     g2:
  714.         i = *ibufp++ & 0177;
  715.         ioff++;
  716.         if(i >= 040)goto g4; else i = ifilt[i];
  717.     }
  718.     if(raw)return(i);
  719.     if((j = i & CMASK) == IMP)goto again;
  720.     if((i == 0) && !init)goto again;
  721. g4:
  722.     if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370))
  723. #ifndef NROFF
  724.         if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits;
  725.         else
  726. #endif
  727.         i |= chbits;
  728.     if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC;
  729.     return(i);
  730. }
  731. nextfile(){
  732.     register char *p;
  733.  
  734. n0:
  735.     if(ifile)close(ifile);
  736.     if(nx){
  737.         p = nextf;
  738.         if(*p != 0)goto n1;
  739.     }
  740.     if(ifi > 0){
  741.         if(popf())goto n0; /*popf error*/
  742.         return(1); /*popf ok*/
  743.     }
  744.     if(rargc-- <= 0)goto n2;
  745.     p = (argp++)[0];
  746. n1:
  747.     if((p[0] == '-') && (p[1] == 0)){
  748.         ifile = 0;
  749.     }else if((ifile=open(p,0)) < 0){
  750.         prstr("Cannot open ");
  751.         prstr(p);
  752.         prstr("\n");
  753.         nfo -= mflg;
  754.         done(02);
  755.     }
  756.     nfo++;
  757.     v.cd = 0;
  758.     ioff = 0;
  759.     return(0);
  760. n2:
  761.     if((nfo -= mflg) && !stdi)done(0);
  762.     nfo++;
  763.     v.cd = ifile =  stdi = mflg = 0;
  764.     ioff = 0;
  765.     return(0);
  766. }
  767. popf(){
  768.     register i;
  769.     register char *p, *q;
  770.     extern char *ttyname();
  771.  
  772.     ioff = offl[--ifi];
  773.     ip = ipl[ifi];
  774.     if((ifile = ifl[ifi]) == 0){
  775.         p = xbuf;
  776.         q = ibuf;
  777.         ibufp = xbufp;
  778.         eibuf = xeibuf;
  779.         while(q < eibuf)*q++ = *p++;
  780.         return(0);
  781.     }
  782.     if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < 0) ||
  783.        ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1);
  784.     eibuf = ibuf + i;
  785.     ibufp = ibuf;
  786.     if(ttyname(ifile) == (char *)0)
  787.         if((ibufp = ibuf + (int)(ioff & (IBUFSZ-1)))  >= eibuf)return(1);
  788.     return(0);
  789. }
  790. flushi(){
  791.     if(nflush)return;
  792.     ch = 0;
  793.     if((ch0 & CMASK) == '\n')nlflg++;
  794.     ch0 = 0;
  795.     copyf++;
  796.     while(!nlflg){
  797.         if(donef && (frame == stk))break;
  798.         getch();
  799.     }
  800.     copyf--;
  801.     v.hp = 0;
  802. }
  803. getach(){
  804.     register i;
  805.  
  806.     lgf++;
  807.     if(((i = getch()) & MOT) ||
  808.         ((i&CMASK) == ' ') ||
  809.         ((i&CMASK) == '\n')||
  810.         (i & 0200)){
  811.             ch = i;
  812.             i = 0;
  813.     }
  814.     lgf--;
  815.     return(i & 0177);
  816. }
  817. casenx(){
  818.     lgf++;
  819.     skip();
  820.     getname();
  821.     nx++;
  822.     nextfile();
  823.     nlflg++;
  824.     ip = 0;
  825.     ap = 0;
  826.     nchar = pendt = 0;
  827.     frame = stk;
  828.     nxf = frame + 1;
  829. }
  830. getname(){
  831.     register int i, j, k;
  832.  
  833.     lgf++;
  834.     for(k=0; k < (NS-1); k++){
  835.         if(((j=(i=getch()) & CMASK) <= ' ') ||
  836.             (j > 0176))break;
  837.         nextf[k] = j;
  838.     }
  839.     nextf[k] = 0;
  840.     ch = i;
  841.     lgf--;
  842.     return(nextf[0]);
  843. }
  844. caseso(){
  845.     register i;
  846.     register char *p, *q;
  847.  
  848.     lgf++;
  849.     nextf[0] = 0;
  850.     if(skip() || !getname() || ((i=open(nextf,0)) <0) || (ifi >= NSO)) {
  851.         prstr("can't open file ");
  852.         prstr(nextf);
  853.         prstr("\n");
  854.         done(02);
  855.     }
  856.     flushi();
  857.     ifl[ifi] = ifile;
  858.     ifile = i;
  859.     offl[ifi] = ioff;
  860.     ioff = 0;
  861.     ipl[ifi] = ip;
  862.     ip = 0;
  863.     nx++;
  864.     nflush++;
  865.     if(!ifl[ifi++]){
  866.         p = ibuf;
  867.         q = xbuf;
  868.         xbufp = ibufp;
  869.         xeibuf = eibuf;
  870.         while(p < eibuf)*q++ = *p++;
  871.     }
  872. }
  873.  
  874. casecf(){    /* copy file without change */
  875.     int fd, i, n;
  876.     char buf[512];
  877.  
  878.     flusho();
  879.     lgf++;
  880.     nextf[0] = 0;
  881.     if(skip() || !getname() || ((fd=open(nextf,0)) <0) || (ifi >= NSO)) {
  882.         prstr("can't open file ");
  883.         prstr(nextf);
  884.         prstr("\n");
  885.         done(02);
  886.     }
  887.     while ((n = read(fd, buf, 512)) > 0)
  888.         for (i = 0; i < n; i++)
  889.             oput(buf[i]);
  890.     flusho();
  891.     close(fd);
  892. }
  893. getpn(a)
  894. char *a;
  895. {
  896.     register i, neg;
  897.     long atoi1();
  898.  
  899.     if((*a & 0177) == 0)return;
  900.     neg = 0;
  901.     ibufp = a;
  902.     eibuf = MAXPTR;
  903.     noscale++;
  904.     while((i = getch() & CMASK) != 0)switch(i){
  905.         case '+':
  906.         case ',':
  907.             continue;
  908.         case '-':
  909.             neg = MOT;
  910.             goto d2;
  911.         default:
  912.             ch = i;
  913.         d2:
  914.             i = atoi1();
  915.             if(nonumb)goto fini;
  916.             else{
  917.                 *pnp++ = i | neg;
  918.                 neg = 0;
  919.                 if(pnp >= &pnlist[NPN-2]){
  920.                     prstr("Too many page numbers\n");
  921.                     done3(-3);
  922.                 }
  923.             }
  924.         }
  925. fini:
  926.     if(neg)*pnp++ = -2;
  927.     *pnp = -1;
  928.     ch = noscale = print = 0;
  929.     pnp = pnlist;
  930.     if(*pnp != -1)chkpn();
  931. }
  932. setrpt(){
  933.     register i, j;
  934.  
  935.     copyf++;raw++;
  936.     i = getch0();
  937.     copyf--;raw--;
  938.     if((i < 0) ||
  939.        (((j = getch0()) & CMASK) == RPT))return;
  940.     rchar = j;
  941.     nchar = i & BMASK;
  942. }
  943.