home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / sed / sed1.c < prev   
Encoding:
C/C++ Source or Header  |  1979-02-16  |  10.3 KB  |  718 lines

  1. #include    <stdio.h>
  2. #include "sed.h"
  3.  
  4. char    *trans[040]  = {
  5.     "\\01",
  6.     "\\02",
  7.     "\\03",
  8.     "\\04",
  9.     "\\05",
  10.     "\\06",
  11.     "\\07",
  12.     "<-",
  13.     ">-",
  14.     "\n",
  15.     "\\13",
  16.     "\\14",
  17.     "\\15",
  18.     "\\16",
  19.     "\\17",
  20.     "\\20",
  21.     "\\21",
  22.     "\\22",
  23.     "\\23",
  24.     "\\24",
  25.     "\\25",
  26.     "\\26",
  27.     "\\27",
  28.     "\\30",
  29.     "\\31",
  30.     "\\32",
  31.     "\\33",
  32.     "\\34",
  33.     "\\35",
  34.     "\\36",
  35.     "\\37"
  36. };
  37. char    rub[] = {"\177"};
  38.  
  39. execute(file)
  40. char *file;
  41. {
  42.     register char *p1, *p2;
  43.     register union reptr    *ipc;
  44.     int    c;
  45.     char    *execp;
  46.  
  47.     if (file) {
  48.         if ((f = open(file, 0)) < 0) {
  49.             fprintf(stderr, "Can't open %s\n", file);
  50.         }
  51.     } else
  52.         f = 0;
  53.  
  54.     ebp = ibuf;
  55.     cbp = ibuf;
  56.  
  57.     if(pending) {
  58.         ipc = pending;
  59.         pending = 0;
  60.         goto yes;
  61.     }
  62.  
  63.     for(;;) {
  64.         if((execp = gline(linebuf)) == badp) {
  65.             close(f);
  66.             return;
  67.         }
  68.         spend = execp;
  69.  
  70.         for(ipc = ptrspace; ipc->command; ) {
  71.  
  72.             p1 = ipc->ad1;
  73.             p2 = ipc->ad2;
  74.  
  75.             if(p1) {
  76.  
  77.                 if(ipc->inar) {
  78.                     if(*p2 == CEND) {
  79.                         p1 = 0;
  80.                     } else if(*p2 == CLNUM) {
  81.                         c = p2[1];
  82.                         if(lnum > tlno[c]) {
  83.                             ipc->inar = 0;
  84.                             if(ipc->negfl)
  85.                                 goto yes;
  86.                             ipc++;
  87.                             continue;
  88.                         }
  89.                         if(lnum == tlno[c]) {
  90.                             ipc->inar = 0;
  91.                         }
  92.                     } else if(match(p2, 0)) {
  93.                         ipc->inar = 0;
  94.                     }
  95.                 } else if(*p1 == CEND) {
  96.                     if(!dolflag) {
  97.                         if(ipc->negfl)
  98.                             goto yes;
  99.                         ipc++;
  100.                         continue;
  101.                     }
  102.  
  103.                 } else if(*p1 == CLNUM) {
  104.                     c = p1[1];
  105.                     if(lnum != tlno[c]) {
  106.                         if(ipc->negfl)
  107.                             goto yes;
  108.                         ipc++;
  109.                         continue;
  110.                     }
  111.                     if(p2)
  112.                         ipc->inar = 1;
  113.                 } else if(match(p1, 0)) {
  114.                     if(p2)
  115.                         ipc->inar = 1;
  116.                 } else {
  117.                     if(ipc->negfl)
  118.                         goto yes;
  119.                     ipc++;
  120.                     continue;
  121.                 }
  122.             }
  123.  
  124.             if(ipc->negfl) {
  125.                 ipc++;
  126.                 continue;
  127.             }
  128.     yes:
  129.             command(ipc);
  130.  
  131.             if(delflag)
  132.                 break;
  133.  
  134.             if(jflag) {
  135.                 jflag = 0;
  136.                 if((ipc = ipc->lb1) == 0) {
  137.                     ipc = ptrspace;
  138.                     break;
  139.                 }
  140.             } else
  141.                 ipc++;
  142.  
  143.         }
  144.         if(!nflag && !delflag) {
  145.             for(p1 = linebuf; p1 < spend; p1++)
  146.                 putc(*p1, stdout);
  147.             putc('\n', stdout);
  148.         }
  149.  
  150.         if(aptr > abuf) {
  151.             arout();
  152.         }
  153.  
  154.         delflag = 0;
  155.  
  156.     }
  157. }
  158. match(expbuf, gf)
  159. char    *expbuf;
  160. {
  161.     register char    *p1, *p2, c;
  162.  
  163.     if(gf) {
  164.         if(*expbuf)    return(0);
  165.         p1 = linebuf;
  166.         p2 = genbuf;
  167.         while(*p1++ = *p2++);
  168.         locs = p1 = loc2;
  169.     } else {
  170.         p1 = linebuf;
  171.         locs = 0;
  172.     }
  173.  
  174.     p2 = expbuf;
  175.     if(*p2++) {
  176.         loc1 = p1;
  177.         if(*p2 == CCHR && p2[1] != *p1)
  178.             return(0);
  179.         return(advance(p1, p2));
  180.     }
  181.  
  182.     /* fast check for first character */
  183.  
  184.     if(*p2 == CCHR) {
  185.         c = p2[1];
  186.         do {
  187.             if(*p1 != c)
  188.                 continue;
  189.             if(advance(p1, p2)) {
  190.                 loc1 = p1;
  191.                 return(1);
  192.             }
  193.         } while(*p1++);
  194.         return(0);
  195.     }
  196.  
  197.     do {
  198.         if(advance(p1, p2)) {
  199.             loc1 = p1;
  200.             return(1);
  201.         }
  202.     } while(*p1++);
  203.     return(0);
  204. }
  205. advance(alp, aep)
  206. char    *alp, *aep;
  207. {
  208.     register char *lp, *ep, *curlp;
  209.     char    c;
  210.     char *bbeg;
  211.     int    ct;
  212.  
  213. /*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep);    /*DEBUG*/
  214.  
  215.     lp = alp;
  216.     ep = aep;
  217.     for (;;) switch (*ep++) {
  218.  
  219.     case CCHR:
  220.         if (*ep++ == *lp++)
  221.             continue;
  222.         return(0);
  223.  
  224.     case CDOT:
  225.         if (*lp++)
  226.             continue;
  227.         return(0);
  228.  
  229.     case CNL:
  230.     case CDOL:
  231.         if (*lp == 0)
  232.             continue;
  233.         return(0);
  234.  
  235.     case CEOF:
  236.         loc2 = lp;
  237.         return(1);
  238.  
  239.     case CCL:
  240.         c = *lp++ & 0177;
  241.         if(ep[c>>3] & bittab[c & 07]) {
  242.             ep += 16;
  243.             continue;
  244.         }
  245.         return(0);
  246.  
  247.     case CBRA:
  248.         braslist[*ep++] = lp;
  249.         continue;
  250.  
  251.     case CKET:
  252.         braelist[*ep++] = lp;
  253.         continue;
  254.  
  255.     case CBACK:
  256.         bbeg = braslist[*ep];
  257.         ct = braelist[*ep++] - bbeg;
  258.  
  259.         if(ecmp(bbeg, lp, ct)) {
  260.             lp += ct;
  261.             continue;
  262.         }
  263.         return(0);
  264.  
  265.     case CBACK|STAR:
  266.         bbeg = braslist[*ep];
  267.         ct = braelist[*ep++] - bbeg;
  268.         curlp = lp;
  269.         while(ecmp(bbeg, lp, ct))
  270.             lp += ct;
  271.  
  272.         while(lp >= curlp) {
  273.             if(advance(lp, ep))    return(1);
  274.             lp -= ct;
  275.         }
  276.         return(0);
  277.  
  278.  
  279.     case CDOT|STAR:
  280.         curlp = lp;
  281.         while (*lp++);
  282.         goto star;
  283.  
  284.     case CCHR|STAR:
  285.         curlp = lp;
  286.         while (*lp++ == *ep);
  287.         ep++;
  288.         goto star;
  289.  
  290.     case CCL|STAR:
  291.         curlp = lp;
  292.         do {
  293.             c = *lp++ & 0177;
  294.         } while(ep[c>>3] & bittab[c & 07]);
  295.         ep += 16;
  296.         goto star;
  297.  
  298.     star:
  299.         if(--lp == curlp) {
  300.             continue;
  301.         }
  302.  
  303.         if(*ep == CCHR) {
  304.             c = ep[1];
  305.             do {
  306.                 if(*lp != c)
  307.                     continue;
  308.                 if(advance(lp, ep))
  309.                     return(1);
  310.             } while(lp-- > curlp);
  311.             return(0);
  312.         }
  313.  
  314.         if(*ep == CBACK) {
  315.             c = *(braslist[ep[1]]);
  316.             do {
  317.                 if(*lp != c)
  318.                     continue;
  319.                 if(advance(lp, ep))
  320.                     return(1);
  321.             } while(lp-- > curlp);
  322.             return(0);
  323.         }
  324.  
  325.         do {
  326.             if(lp == locs)    break;
  327.             if (advance(lp, ep))
  328.                 return(1);
  329.         } while (lp-- > curlp);
  330.         return(0);
  331.  
  332.     default:
  333.         fprintf(stderr, "RE botch, %o\n", *--ep);
  334.     }
  335. }
  336. substitute(ipc)
  337. union reptr    *ipc;
  338. {
  339.     if(match(ipc->re1, 0) == 0)    return(0);
  340.  
  341.     sflag = 1;
  342.     dosub(ipc->rhs);
  343.  
  344.     if(ipc->gfl) {
  345.         while(*loc2) {
  346.             if(match(ipc->re1, 1) == 0) break;
  347.             dosub(ipc->rhs);
  348.         }
  349.     }
  350.     return(1);
  351. }
  352.  
  353. dosub(rhsbuf)
  354. char    *rhsbuf;
  355. {
  356.     register char *lp, *sp, *rp;
  357.     int c;
  358.  
  359.     lp = linebuf;
  360.     sp = genbuf;
  361.     rp = rhsbuf;
  362.     while (lp < loc1)
  363.         *sp++ = *lp++;
  364.     while(c = *rp++) {
  365.         if (c == '&') {
  366.             sp = place(sp, loc1, loc2);
  367.             continue;
  368.         } else if (c&0200 && (c &= 0177) >= '1' && c < NBRA+'1') {
  369.             sp = place(sp, braslist[c-'1'], braelist[c-'1']);
  370.             continue;
  371.         }
  372.         *sp++ = c&0177;
  373.         if (sp >= &genbuf[LBSIZE])
  374.             fprintf(stderr, "output line too long.\n");
  375.     }
  376.     lp = loc2;
  377.     loc2 = sp - genbuf + linebuf;
  378.     while (*sp++ = *lp++)
  379.         if (sp >= &genbuf[LBSIZE]) {
  380.             fprintf(stderr, "Output line too long.\n");
  381.         }
  382.     lp = linebuf;
  383.     sp = genbuf;
  384.     while (*lp++ = *sp++);
  385.     spend = lp-1;
  386. }
  387. char    *place(asp, al1, al2)
  388. char    *asp, *al1, *al2;
  389. {
  390.     register char *sp, *l1, *l2;
  391.  
  392.     sp = asp;
  393.     l1 = al1;
  394.     l2 = al2;
  395.     while (l1 < l2) {
  396.         *sp++ = *l1++;
  397.         if (sp >= &genbuf[LBSIZE])
  398.             fprintf(stderr, "Output line too long.\n");
  399.     }
  400.     return(sp);
  401. }
  402.  
  403. command(ipc)
  404. union reptr    *ipc;
  405. {
  406.     register int    i;
  407.     register char    *p1, *p2, *p3;
  408.     char    *execp;
  409.  
  410.  
  411.     switch(ipc->command) {
  412.  
  413.         case ACOM:
  414.             *aptr++ = ipc;
  415.             if(aptr >= &abuf[ABUFSIZE]) {
  416.                 fprintf(stderr, "Too many appends after line %ld\n",
  417.                     lnum);
  418.             }
  419.             *aptr = 0;
  420.             break;
  421.  
  422.         case CCOM:
  423.             delflag = 1;
  424.             if(!ipc->inar || dolflag) {
  425.                 for(p1 = ipc->re1; *p1; )
  426.                     putc(*p1++, stdout);
  427.                 putc('\n', stdout);
  428.             }
  429.             break;
  430.         case DCOM:
  431.             delflag++;
  432.             break;
  433.         case CDCOM:
  434.             p1 = p2 = linebuf;
  435.  
  436.             while(*p1 != '\n') {
  437.                 if(*p1++ == 0) {
  438.                     delflag++;
  439.                     return;
  440.                 }
  441.             }
  442.  
  443.             p1++;
  444.             while(*p2++ = *p1++);
  445.             spend = p2-1;
  446.             jflag++;
  447.             break;
  448.  
  449.         case EQCOM:
  450.             fprintf(stdout, "%ld\n", lnum);
  451.             break;
  452.  
  453.         case GCOM:
  454.             p1 = linebuf;
  455.             p2 = holdsp;
  456.             while(*p1++ = *p2++);
  457.             spend = p1-1;
  458.             break;
  459.  
  460.         case CGCOM:
  461.             *spend++ = '\n';
  462.             p1 = spend;
  463.             p2 = holdsp;
  464.             while(*p1++ = *p2++)
  465.                 if(p1 >= lbend)
  466.                     break;
  467.             spend = p1-1;
  468.             break;
  469.  
  470.         case HCOM:
  471.             p1 = holdsp;
  472.             p2 = linebuf;
  473.             while(*p1++ = *p2++);
  474.             hspend = p1-1;
  475.             break;
  476.  
  477.         case CHCOM:
  478.             *hspend++ = '\n';
  479.             p1 = hspend;
  480.             p2 = linebuf;
  481.             while(*p1++ = *p2++)
  482.                 if(p1 >= hend)
  483.                     break;
  484.             hspend = p1-1;
  485.             break;
  486.  
  487.         case ICOM:
  488.             for(p1 = ipc->re1; *p1; )
  489.                 putc(*p1++, stdout);
  490.             putc('\n', stdout);
  491.             break;
  492.  
  493.         case BCOM:
  494.             jflag = 1;
  495.             break;
  496.  
  497.         case LCOM:
  498.             p1 = linebuf;
  499.             p2 = genbuf;
  500.             genbuf[72] = 0;
  501.             while(*p1)
  502.                 if(*p1 >= 040) {
  503.                     if(*p1 == 0177) {
  504.                         p3 = rub;
  505.                         while(*p2++ = *p3++)
  506.                             if(p2 >= lcomend) {
  507.                                 *p2 = '\\';
  508.                                 fprintf(stdout, "%s\n", genbuf);
  509.                                 p2 = genbuf;
  510.                             }
  511.                         p2--;
  512.                         p1++;
  513.                         continue;
  514.                     }
  515.                     *p2++ = *p1++;
  516.                     if(p2 >= lcomend) {
  517.                         *p2 = '\\';
  518.                         fprintf(stdout, "%s\n", genbuf);
  519.                         p2 = genbuf;
  520.                     }
  521.                 } else {
  522.                     p3 = trans[*p1-1];
  523.                     while(*p2++ = *p3++)
  524.                         if(p2 >= lcomend) {
  525.                             *p2 = '\\';
  526.                             fprintf(stdout, "%s\n", genbuf);
  527.                             p2 = genbuf;
  528.                         }
  529.                     p2--;
  530.                     p1++;
  531.                 }
  532.             *p2 = 0;
  533.             fprintf(stdout, "%s\n", genbuf);
  534.             break;
  535.  
  536.         case NCOM:
  537.             if(!nflag) {
  538.                 for(p1 = linebuf; p1 < spend; p1++)
  539.                     putc(*p1, stdout);
  540.                 putc('\n', stdout);
  541.             }
  542.  
  543.             if(aptr > abuf)
  544.                 arout();
  545.             if((execp = gline(linebuf)) == badp) {
  546.                 pending = ipc;
  547.                 delflag = 1;
  548.                 break;
  549.             }
  550.             spend = execp;
  551.  
  552.             break;
  553.         case CNCOM:
  554.             if(aptr > abuf)
  555.                 arout();
  556.             *spend++ = '\n';
  557.             if((execp = gline(spend)) == badp) {
  558.                 pending = ipc;
  559.                 delflag = 1;
  560.                 break;
  561.             }
  562.             spend = execp;
  563.             break;
  564.  
  565.         case PCOM:
  566.             for(p1 = linebuf; p1 < spend; p1++)
  567.                 putc(*p1, stdout);
  568.             putc('\n', stdout);
  569.             break;
  570.         case CPCOM:
  571.     cpcom:
  572.             for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
  573.                 putc(*p1++, stdout);
  574.             putc('\n', stdout);
  575.             break;
  576.  
  577.         case QCOM:
  578.             if(!nflag) {
  579.                 for(p1 = linebuf; p1 < spend; p1++)
  580.                     putc(*p1, stdout);
  581.                 putc('\n', stdout);
  582.             }
  583.             if(aptr > abuf)    arout();
  584.             fclose(stdout);
  585.             exit(0);
  586.         case RCOM:
  587.  
  588.             *aptr++ = ipc;
  589.             if(aptr >= &abuf[ABUFSIZE])
  590.                 fprintf(stderr, "Too many reads after line%ld\n",
  591.                     lnum);
  592.  
  593.             *aptr = 0;
  594.  
  595.             break;
  596.  
  597.         case SCOM:
  598.             i = substitute(ipc);
  599.             if(ipc->pfl && i)
  600.                 if(ipc->pfl == 1) {
  601.                     for(p1 = linebuf; p1 < spend; p1++)
  602.                         putc(*p1, stdout);
  603.                     putc('\n', stdout);
  604.                 }
  605.                 else
  606.                     goto cpcom;
  607.             if(i && ipc->fcode)
  608.                 goto wcom;
  609.             break;
  610.  
  611.         case TCOM:
  612.             if(sflag == 0)    break;
  613.             sflag = 0;
  614.             jflag = 1;
  615.             break;
  616.  
  617.         wcom:
  618.         case WCOM:
  619.             fprintf(ipc->fcode, "%s\n", linebuf);
  620.             break;
  621.         case XCOM:
  622.             p1 = linebuf;
  623.             p2 = genbuf;
  624.             while(*p2++ = *p1++);
  625.             p1 = holdsp;
  626.             p2 = linebuf;
  627.             while(*p2++ = *p1++);
  628.             spend = p2 - 1;
  629.             p1 = genbuf;
  630.             p2 = holdsp;
  631.             while(*p2++ = *p1++);
  632.             hspend = p2 - 1;
  633.             break;
  634.  
  635.         case YCOM:
  636.             p1 = linebuf;
  637.             p2 = ipc->re1;
  638.             while(*p1 = p2[*p1])    p1++;
  639.             break;
  640.     }
  641.  
  642. }
  643.  
  644. char    *
  645. gline(addr)
  646. char    *addr;
  647. {
  648.     register char    *p1, *p2;
  649.     register    c;
  650.     p1 = addr;
  651.     p2 = cbp;
  652.     for (;;) {
  653.         if (p2 >= ebp) {
  654.             if ((c = read(f, ibuf, 512)) <= 0) {
  655.                 return(badp);
  656.             }
  657.             p2 = ibuf;
  658.             ebp = ibuf+c;
  659.         }
  660.         if ((c = *p2++) == '\n') {
  661.             if(p2 >=  ebp) {
  662.                 if((c = read(f, ibuf, 512)) <= 0) {
  663.                     close(f);
  664.                     if(eargc == 0)
  665.                             dolflag = 1;
  666.                 }
  667.  
  668.                 p2 = ibuf;
  669.                 ebp = ibuf + c;
  670.             }
  671.             break;
  672.         }
  673.         if(c)
  674.         if(p1 < lbend)
  675.             *p1++ = c;
  676.     }
  677.     lnum++;
  678.     *p1 = 0;
  679.     cbp = p2;
  680.  
  681.     return(p1);
  682. }
  683. ecmp(a, b, count)
  684. char    *a, *b;
  685. {
  686.     while(count--)
  687.         if(*a++ != *b++)    return(0);
  688.     return(1);
  689. }
  690.  
  691. arout()
  692. {
  693.     register char    *p1;
  694.     FILE    *fi;
  695.     char    c;
  696.     int    t;
  697.  
  698.     aptr = abuf - 1;
  699.     while(*++aptr) {
  700.         if((*aptr)->command == ACOM) {
  701.             for(p1 = (*aptr)->re1; *p1; )
  702.                 putc(*p1++, stdout);
  703.             putc('\n', stdout);
  704.         } else {
  705.             if((fi = fopen((*aptr)->re1, "r")) == NULL)
  706.                 continue;
  707.             while((t = getc(fi)) != EOF) {
  708.                 c = t;
  709.                 putc(c, stdout);
  710.             }
  711.             fclose(fi);
  712.         }
  713.     }
  714.     aptr = abuf;
  715.     *aptr = 0;
  716. }
  717.  
  718.