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

  1. #include <stdio.h>
  2. #include "sed.h"
  3.  
  4. struct label    *labtab = ltab;
  5. char    CGMES[]    = "command garbled: %s\n";
  6. char    TMMES[]    = "Too much text: %s\n";
  7. char    LTL[]    = "Label too long: %s\n";
  8. char    AD0MES[]    = "No addresses allowed: %s\n";
  9. char    AD1MES[]    = "Only one address allowed: %s\n";
  10. char    bittab[]  = {
  11.         1,
  12.         2,
  13.         4,
  14.         8,
  15.         16,
  16.         32,
  17.         64,
  18.         128
  19.     };
  20.  
  21. main(argc, argv)
  22. char    *argv[];
  23. {
  24.  
  25.     eargc = argc;
  26.     eargv = argv;
  27.  
  28.     badp = &bad;
  29.     aptr = abuf;
  30.     lab = labtab + 1;    /* 0 reserved for end-pointer */
  31.     rep = ptrspace;
  32.     rep->ad1 = respace;
  33.     lbend = &linebuf[LBSIZE];
  34.     hend = &holdsp[LBSIZE];
  35.     lcomend = &genbuf[71];
  36.     ptrend = &ptrspace[PTRSIZE];
  37.     reend = &respace[RESIZE];
  38.     labend = &labtab[LABSIZE];
  39.     lnum = 0;
  40.     pending = 0;
  41.     depth = 0;
  42.     spend = linebuf;
  43.     hspend = holdsp;
  44.     fcode[0] = stdout;
  45.     nfiles = 1;
  46.  
  47.     if(eargc == 1)
  48.         exit(0);
  49.  
  50.  
  51.     while (--eargc > 0 && (++eargv)[0][0] == '-')
  52.         switch (eargv[0][1]) {
  53.  
  54.         case 'n':
  55.             nflag++;
  56.             continue;
  57.  
  58.         case 'f':
  59.             if(eargc-- <= 0)    exit(2);
  60.  
  61.             if((fin = fopen(*++eargv, "r")) == NULL) {
  62.                 fprintf(stderr, "Cannot open pattern-file: %s\n", *eargv);
  63.                 exit(2);
  64.             }
  65.  
  66.             fcomp();
  67.             fclose(fin);
  68.             continue;
  69.  
  70.         case 'e':
  71.             eflag++;
  72.             fcomp();
  73.             eflag = 0;
  74.             continue;
  75.  
  76.         case 'g':
  77.             gflag++;
  78.             continue;
  79.  
  80.         default:
  81.             fprintf(stdout, "Unknown flag: %c\n", eargv[0][1]);
  82.             continue;
  83.         }
  84.  
  85.  
  86.     if(compfl == 0) {
  87.         eargv--;
  88.         eargc++;
  89.         eflag++;
  90.         fcomp();
  91.         eargv++;
  92.         eargc--;
  93.         eflag = 0;
  94.     }
  95.  
  96.     if(depth) {
  97.         fprintf(stderr, "Too many {'s");
  98.         exit(2);
  99.     }
  100.  
  101.     labtab->address = rep;
  102.  
  103.     dechain();
  104.  
  105. /*    abort();    /*DEBUG*/
  106.  
  107.     if(eargc <= 0)
  108.         execute((char *)NULL);
  109.     else while(--eargc >= 0) {
  110.         execute(*eargv++);
  111.     }
  112.     fclose(stdout);
  113.     exit(0);
  114. }
  115. fcomp()
  116. {
  117.  
  118.     register char    *p, *op, *tp;
  119.     char    *address();
  120.     union reptr    *pt, *pt1;
  121.     int    i;
  122.     struct label    *lpt;
  123.  
  124.     compfl = 1;
  125.     op = lastre;
  126.  
  127.     if(rline(linebuf) < 0)    return;
  128.     if(*linebuf == '#') {
  129.         if(linebuf[1] == 'n')
  130.             nflag = 1;
  131.     }
  132.     else {
  133.         cp = linebuf;
  134.         goto comploop;
  135.     }
  136.  
  137.     for(;;) {
  138.         if(rline(linebuf) < 0)    break;
  139.  
  140.         cp = linebuf;
  141.  
  142. comploop:
  143. /*    fprintf(stdout, "cp: %s\n", cp);    /*DEBUG*/
  144.         while(*cp == ' ' || *cp == '\t')    cp++;
  145.         if(*cp == '\0' || *cp == '#')        continue;
  146.         if(*cp == ';') {
  147.             cp++;
  148.             goto comploop;
  149.         }
  150.  
  151.         p = address(rep->ad1);
  152.         if(p == badp) {
  153.             fprintf(stderr, CGMES, linebuf);
  154.             exit(2);
  155.         }
  156.  
  157.         if(p == rep->ad1) {
  158.             if(op)
  159.                 rep->ad1 = op;
  160.             else {
  161.                 fprintf(stderr, "First RE may not be null\n");
  162.                 exit(2);
  163.             }
  164.         } else if(p == 0) {
  165.             p = rep->ad1;
  166.             rep->ad1 = 0;
  167.         } else {
  168.             op = rep->ad1;
  169.             if(*cp == ',' || *cp == ';') {
  170.                 cp++;
  171.                 if((rep->ad2 = p) > reend) {
  172.                     fprintf(stderr, TMMES, linebuf);
  173.                     exit(2);
  174.                 }
  175.                 p = address(rep->ad2);
  176.                 if(p == badp || p == 0) {
  177.                     fprintf(stderr, CGMES, linebuf);
  178.                     exit(2);
  179.                 }
  180.                 if(p == rep->ad2)
  181.                     rep->ad2 = op;
  182.                 else
  183.                     op = rep->ad2;
  184.  
  185.             } else
  186.                 rep->ad2 = 0;
  187.         }
  188.  
  189.         if(p > reend) {
  190.             fprintf(stderr, "Too much text: %s\n", linebuf);
  191.             exit(2);
  192.         }
  193.  
  194.         while(*cp == ' ' || *cp == '\t')    cp++;
  195.  
  196. swit:
  197.         switch(*cp++) {
  198.  
  199.             default:
  200.                 fprintf(stderr, "Unrecognized command: %s\n", linebuf);
  201.                 exit(2);
  202.  
  203.             case '!':
  204.                 rep->negfl = 1;
  205.                 goto swit;
  206.  
  207.             case '{':
  208.                 rep->command = BCOM;
  209.                 rep->negfl = !(rep->negfl);
  210.                 cmpend[depth++] = &rep->lb1;
  211.                 if(++rep >= ptrend) {
  212.                     fprintf(stderr, "Too many commands: %s\n", linebuf);
  213.                     exit(2);
  214.                 }
  215.                 rep->ad1 = p;
  216.                 if(*cp == '\0')    continue;
  217.  
  218.                 goto comploop;
  219.  
  220.             case '}':
  221.                 if(rep->ad1) {
  222.                     fprintf(stderr, AD0MES, linebuf);
  223.                     exit(2);
  224.                 }
  225.  
  226.                 if(--depth < 0) {
  227.                     fprintf(stderr, "Too many }'s\n");
  228.                     exit(2);
  229.                 }
  230.                 *cmpend[depth] = rep;
  231.  
  232.                 rep->ad1 = p;
  233.                 continue;
  234.  
  235.             case '=':
  236.                 rep->command = EQCOM;
  237.                 if(rep->ad2) {
  238.                     fprintf(stderr, AD1MES, linebuf);
  239.                     exit(2);
  240.                 }
  241.                 break;
  242.  
  243.             case ':':
  244.                 if(rep->ad1) {
  245.                     fprintf(stderr, AD0MES, linebuf);
  246.                     exit(2);
  247.                 }
  248.  
  249.                 while(*cp++ == ' ');
  250.                 cp--;
  251.  
  252.  
  253.                 tp = lab->asc;
  254.                 while((*tp++ = *cp++))
  255.                     if(tp >= &(lab->asc[8])) {
  256.                         fprintf(stderr, LTL, linebuf);
  257.                         exit(2);
  258.                     }
  259.                 *--tp = '\0';
  260.  
  261.                 if(lpt = search(lab)) {
  262.                     if(lpt->address) {
  263.                         fprintf(stderr, "Duplicate labels: %s\n", linebuf);
  264.                         exit(2);
  265.                     }
  266.                 } else {
  267.                     lab->chain = 0;
  268.                     lpt = lab;
  269.                     if(++lab >= labend) {
  270.                         fprintf(stderr, "Too many labels: %s\n", linebuf);
  271.                         exit(2);
  272.                     }
  273.                 }
  274.                 lpt->address = rep;
  275.                 rep->ad1 = p;
  276.  
  277.                 continue;
  278.  
  279.             case 'a':
  280.                 rep->command = ACOM;
  281.                 if(rep->ad2) {
  282.                     fprintf(stderr, AD1MES, linebuf);
  283.                     exit(2);
  284.                 }
  285.                 if(*cp == '\\')    cp++;
  286.                 if(*cp++ != '\n') {
  287.                     fprintf(stderr, CGMES, linebuf);
  288.                     exit(2);
  289.                 }
  290.                 rep->re1 = p;
  291.                 p = text(rep->re1);
  292.                 break;
  293.             case 'c':
  294.                 rep->command = CCOM;
  295.                 if(*cp == '\\')    cp++;
  296.                 if(*cp++ != ('\n')) {
  297.                     fprintf(stderr, CGMES, linebuf);
  298.                     exit(2);
  299.                 }
  300.                 rep->re1 = p;
  301.                 p = text(rep->re1);
  302.                 break;
  303.             case 'i':
  304.                 rep->command = ICOM;
  305.                 if(rep->ad2) {
  306.                     fprintf(stderr, AD1MES, linebuf);
  307.                     exit(2);
  308.                 }
  309.                 if(*cp == '\\')    cp++;
  310.                 if(*cp++ != ('\n')) {
  311.                     fprintf(stderr, CGMES, linebuf);
  312.                     exit(2);
  313.                 }
  314.                 rep->re1 = p;
  315.                 p = text(rep->re1);
  316.                 break;
  317.  
  318.             case 'g':
  319.                 rep->command = GCOM;
  320.                 break;
  321.  
  322.             case 'G':
  323.                 rep->command = CGCOM;
  324.                 break;
  325.  
  326.             case 'h':
  327.                 rep->command = HCOM;
  328.                 break;
  329.  
  330.             case 'H':
  331.                 rep->command = CHCOM;
  332.                 break;
  333.  
  334.             case 't':
  335.                 rep->command = TCOM;
  336.                 goto jtcommon;
  337.  
  338.             case 'b':
  339.                 rep->command = BCOM;
  340. jtcommon:
  341.                 while(*cp++ == ' ');
  342.                 cp--;
  343.  
  344.                 if(*cp == '\0') {
  345.                     if(pt = labtab->chain) {
  346.                         while(pt1 = pt->lb1)
  347.                             pt = pt1;
  348.                         pt->lb1 = rep;
  349.                     } else
  350.                         labtab->chain = rep;
  351.                     break;
  352.                 }
  353.                 tp = lab->asc;
  354.                 while((*tp++ = *cp++))
  355.                     if(tp >= &(lab->asc[8])) {
  356.                         fprintf(stderr, LTL, linebuf);
  357.                         exit(2);
  358.                     }
  359.                 cp--;
  360.                 *--tp = '\0';
  361.  
  362.                 if(lpt = search(lab)) {
  363.                     if(lpt->address) {
  364.                         rep->lb1 = lpt->address;
  365.                     } else {
  366.                         pt = lpt->chain;
  367.                         while(pt1 = pt->lb1)
  368.                             pt = pt1;
  369.                         pt->lb1 = rep;
  370.                     }
  371.                 } else {
  372.                     lab->chain = rep;
  373.                     lab->address = 0;
  374.                     if(++lab >= labend) {
  375.                         fprintf(stderr, "Too many labels: %s\n", linebuf);
  376.                         exit(2);
  377.                     }
  378.                 }
  379.                 break;
  380.  
  381.             case 'n':
  382.                 rep->command = NCOM;
  383.                 break;
  384.  
  385.             case 'N':
  386.                 rep->command = CNCOM;
  387.                 break;
  388.  
  389.             case 'p':
  390.                 rep->command = PCOM;
  391.                 break;
  392.  
  393.             case 'P':
  394.                 rep->command = CPCOM;
  395.                 break;
  396.  
  397.             case 'r':
  398.                 rep->command = RCOM;
  399.                 if(rep->ad2) {
  400.                     fprintf(stderr, AD1MES, linebuf);
  401.                     exit(2);
  402.                 }
  403.                 if(*cp++ != ' ') {
  404.                     fprintf(stderr, CGMES, linebuf);
  405.                     exit(2);
  406.                 }
  407.                 rep->re1 = p;
  408.                 p = text(rep->re1);
  409.                 break;
  410.  
  411.             case 'd':
  412.                 rep->command = DCOM;
  413.                 break;
  414.  
  415.             case 'D':
  416.                 rep->command = CDCOM;
  417.                 rep->lb1 = ptrspace;
  418.                 break;
  419.  
  420.             case 'q':
  421.                 rep->command = QCOM;
  422.                 if(rep->ad2) {
  423.                     fprintf(stderr, AD1MES, linebuf);
  424.                     exit(2);
  425.                 }
  426.                 break;
  427.  
  428.             case 'l':
  429.                 rep->command = LCOM;
  430.                 break;
  431.  
  432.             case 's':
  433.                 rep->command = SCOM;
  434.                 seof = *cp++;
  435.                 rep->re1 = p;
  436.                 p = compile(rep->re1);
  437.                 if(p == badp) {
  438.                     fprintf(stderr, CGMES, linebuf);
  439.                     exit(2);
  440.                 }
  441.                 if(p == rep->re1) {
  442.                     rep->re1 = op;
  443.                 } else {
  444.                     op = rep->re1;
  445.                 }
  446.  
  447.                 if((rep->rhs = p) > reend) {
  448.                     fprintf(stderr, TMMES, linebuf);
  449.                     exit(2);
  450.                 }
  451.  
  452.                 if((p = compsub(rep->rhs)) == badp) {
  453.                     fprintf(stderr, CGMES, linebuf);
  454.                     exit(2);
  455.                 }
  456.                 if(*cp == 'g') {
  457.                     cp++;
  458.                     rep->gfl++;
  459.                 } else if(gflag)
  460.                     rep->gfl++;
  461.  
  462.                 if(*cp == 'p') {
  463.                     cp++;
  464.                     rep->pfl = 1;
  465.                 }
  466.  
  467.                 if(*cp == 'P') {
  468.                     cp++;
  469.                     rep->pfl = 2;
  470.                 }
  471.  
  472.                 if(*cp == 'w') {
  473.                     cp++;
  474.                     if(*cp++ !=  ' ') {
  475.                         fprintf(stderr, CGMES, linebuf);
  476.                         exit(2);
  477.                     }
  478.                     if(nfiles >= 10) {
  479.                         fprintf(stderr, "Too many files in w commands\n");
  480.                         exit(2);
  481.                     }
  482.  
  483.                     text(fname[nfiles]);
  484.                     for(i = nfiles - 1; i >= 0; i--)
  485.                         if(cmp(fname[nfiles],fname[i]) == 0) {
  486.                             rep->fcode = fcode[i];
  487.                             goto done;
  488.                         }
  489.                     if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
  490.                         fprintf(stderr, "cannot open %s\n", fname[nfiles]);
  491.                         exit(2);
  492.                     }
  493.                     fcode[nfiles++] = rep->fcode;
  494.                 }
  495.                 break;
  496.  
  497.             case 'w':
  498.                 rep->command = WCOM;
  499.                 if(*cp++ != ' ') {
  500.                     fprintf(stderr, CGMES, linebuf);
  501.                     exit(2);
  502.                 }
  503.                 if(nfiles >= 10){
  504.                     fprintf(stderr, "Too many files in w commands\n");
  505.                     exit(2);
  506.                 }
  507.  
  508.                 text(fname[nfiles]);
  509.                 for(i = nfiles - 1; i >= 0; i--)
  510.                     if(cmp(fname[nfiles], fname[i]) == 0) {
  511.                         rep->fcode = fcode[i];
  512.                         goto done;
  513.                     }
  514.  
  515.                 if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
  516.                     fprintf(stderr, "Cannot create %s\n", fname[nfiles]);
  517.                     exit(2);
  518.                 }
  519.                 fcode[nfiles++] = rep->fcode;
  520.                 break;
  521.  
  522.             case 'x':
  523.                 rep->command = XCOM;
  524.                 break;
  525.  
  526.             case 'y':
  527.                 rep->command = YCOM;
  528.                 seof = *cp++;
  529.                 rep->re1 = p;
  530.                 p = ycomp(rep->re1);
  531.                 if(p == badp) {
  532.                     fprintf(stderr, CGMES, linebuf);
  533.                     exit(2);
  534.                 }
  535.                 if(p > reend) {
  536.                     fprintf(stderr, TMMES, linebuf);
  537.                     exit(2);
  538.                 }
  539.                 break;
  540.  
  541.         }
  542. done:
  543.         if(++rep >= ptrend) {
  544.             fprintf(stderr, "Too many commands, last: %s\n", linebuf);
  545.             exit(2);
  546.         }
  547.  
  548.         rep->ad1 = p;
  549.  
  550.         if(*cp++ != '\0') {
  551.             if(cp[-1] == ';')
  552.                 goto comploop;
  553.             fprintf(stderr, CGMES, linebuf);
  554.             exit(2);
  555.         }
  556.  
  557.     }
  558.     rep->command = 0;
  559.     lastre = op;
  560. }
  561. char    *compsub(rhsbuf)
  562. char    *rhsbuf;
  563. {
  564.     register char    *p, *q;
  565.  
  566.     p = rhsbuf;
  567.     q = cp;
  568.     for(;;) {
  569.         if((*p = *q++) == '\\') {
  570.             *p = *q++;
  571.             if(*p > numbra + '0' && *p <= '9')
  572.                 return(badp);
  573.             *p++ |= 0200;
  574.             continue;
  575.         }
  576.         if(*p == seof) {
  577.             *p++ = '\0';
  578.             cp = q;
  579.             return(p);
  580.         }
  581.         if(*p++ == '\0') {
  582.             return(badp);
  583.         }
  584.  
  585.     }
  586. }
  587.  
  588. char *compile(expbuf)
  589. char    *expbuf;
  590. {
  591.     register c;
  592.     register char *ep, *sp;
  593.     char    neg;
  594.     char *lastep, *cstart;
  595.     int cclcnt;
  596.     int    closed;
  597.     char    bracket[NBRA], *bracketp;
  598.  
  599.     if(*cp == seof) {
  600.         cp++;
  601.         return(expbuf);
  602.     }
  603.  
  604.     ep = expbuf;
  605.     lastep = 0;
  606.     bracketp = bracket;
  607.     closed = numbra = 0;
  608.     sp = cp;
  609.     if (*sp == '^') {
  610.         *ep++ = 1;
  611.         sp++;
  612.     } else {
  613.         *ep++ = 0;
  614.     }
  615.     for (;;) {
  616.         if (ep >= &expbuf[ESIZE]) {
  617.             cp = sp;
  618.             return(badp);
  619.         }
  620.         if((c = *sp++) == seof) {
  621.             if(bracketp != bracket) {
  622.                 cp = sp;
  623.                 return(badp);
  624.             }
  625.             cp = sp;
  626.             *ep++ = CEOF;
  627.             return(ep);
  628.         }
  629.         if(c != '*')
  630.             lastep = ep;
  631.         switch (c) {
  632.  
  633.         case '\\':
  634.             if((c = *sp++) == '(') {
  635.                 if(numbra >= NBRA) {
  636.                     cp = sp;
  637.                     return(badp);
  638.                 }
  639.                 *bracketp++ = numbra;
  640.                 *ep++ = CBRA;
  641.                 *ep++ = numbra++;
  642.                 continue;
  643.             }
  644.             if(c == ')') {
  645.                 if(bracketp <= bracket) {
  646.                     cp = sp;
  647.                     return(badp);
  648.                 }
  649.                 *ep++ = CKET;
  650.                 *ep++ = *--bracketp;
  651.                 closed++;
  652.                 continue;
  653.             }
  654.  
  655.             if(c >= '1' && c <= '9') {
  656.                 if((c -= '1') >= closed)
  657.                     return(badp);
  658.     
  659.                 *ep++ = CBACK;
  660.                 *ep++ = c;
  661.                 continue;
  662.             }
  663.             if(c == '\n') {
  664.                 cp = sp;
  665.                 return(badp);
  666.             }
  667.             if(c == 'n') {
  668.                 c = '\n';
  669.             }
  670.             goto defchar;
  671.  
  672.         case '\0':
  673.             continue;
  674.         case '\n':
  675.             cp = sp;
  676.             return(badp);
  677.  
  678.         case '.':
  679.             *ep++ = CDOT;
  680.             continue;
  681.  
  682.         case '*':
  683.             if (lastep == 0)
  684.                 goto defchar;
  685.             if(*lastep == CKET) {
  686.                 cp = sp;
  687.                 return(badp);
  688.             }
  689.             *lastep |= STAR;
  690.             continue;
  691.  
  692.         case '$':
  693.             if (*sp != seof)
  694.                 goto defchar;
  695.             *ep++ = CDOL;
  696.             continue;
  697.  
  698.         case '[':
  699.             if(&ep[17] >= &expbuf[ESIZE]) {
  700.                 fprintf(stderr, "RE too long: %s\n", linebuf);
  701.                 exit(2);
  702.             }
  703.  
  704.             *ep++ = CCL;
  705.  
  706.             neg = 0;
  707.             if((c = *sp++) == '^') {
  708.                 neg = 1;
  709.                 c = *sp++;
  710.             }
  711.  
  712.             cstart = sp;
  713.             do {
  714.                 if(c == '\0') {
  715.                     fprintf(stderr, CGMES, linebuf);
  716.                     exit(2);
  717.                 }
  718.                 if (c=='-' && sp>cstart && *sp!=']') {
  719.                     for (c = sp[-2]; c<*sp; c++)
  720.                         ep[c>>3] |= bittab[c&07];
  721.                 }
  722.                 if(c == '\\') {
  723.                     switch(c = *sp++) {
  724.                         case 'n':
  725.                             c = '\n';
  726.                             break;
  727.                     }
  728.                 }
  729.  
  730.                 ep[c >> 3] |= bittab[c & 07];
  731.             } while((c = *sp++) != ']');
  732.  
  733.             if(neg)
  734.                 for(cclcnt = 0; cclcnt < 16; cclcnt++)
  735.                     ep[cclcnt] ^= -1;
  736.             ep[0] &= 0376;
  737.  
  738.             ep += 16;
  739.  
  740.             continue;
  741.  
  742.         defchar:
  743.         default:
  744.             *ep++ = CCHR;
  745.             *ep++ = c;
  746.         }
  747.     }
  748. }
  749. rline(lbuf)
  750. char    *lbuf;
  751. {
  752.     register char    *p, *q;
  753.     register    t;
  754.     static char    *saveq;
  755.  
  756.     p = lbuf - 1;
  757.  
  758.     if(eflag) {
  759.         if(eflag > 0) {
  760.             eflag = -1;
  761.             if(eargc-- <= 0)
  762.                 exit(2);
  763.             q = *++eargv;
  764.             while(*++p = *q++) {
  765.                 if(*p == '\\') {
  766.                     if((*++p = *q++) == '\0') {
  767.                         saveq = 0;
  768.                         return(-1);
  769.                     } else
  770.                         continue;
  771.                 }
  772.                 if(*p == '\n') {
  773.                     *p = '\0';
  774.                     saveq = q;
  775.                     return(1);
  776.                 }
  777.             }
  778.             saveq = 0;
  779.             return(1);
  780.         }
  781.         if((q = saveq) == 0)    return(-1);
  782.  
  783.         while(*++p = *q++) {
  784.             if(*p == '\\') {
  785.                 if((*++p = *q++) == '0') {
  786.                     saveq = 0;
  787.                     return(-1);
  788.                 } else
  789.                     continue;
  790.             }
  791.             if(*p == '\n') {
  792.                 *p = '\0';
  793.                 saveq = q;
  794.                 return(1);
  795.             }
  796.         }
  797.         saveq = 0;
  798.         return(1);
  799.     }
  800.  
  801.     while((t = getc(fin)) != EOF) {
  802.         *++p = t;
  803.         if(*p == '\\') {
  804.             t = getc(fin);
  805.             *++p = t;
  806.         }
  807.         else if(*p == '\n') {
  808.             *p = '\0';
  809.             return(1);
  810.         }
  811.     }
  812.     *++p = '\0';
  813.     return(-1);
  814. }
  815.  
  816. char    *address(expbuf)
  817. char    *expbuf;
  818. {
  819.     register char    *rcp;
  820.     long    lno;
  821.  
  822.     if(*cp == '$') {
  823.         cp++;
  824.         *expbuf++ = CEND;
  825.         *expbuf++ = CEOF;
  826.         return(expbuf);
  827.     }
  828.  
  829.     if(*cp == '/') {
  830.         seof = '/';
  831.         cp++;
  832.         return(compile(expbuf));
  833.     }
  834.  
  835.     rcp = cp;
  836.     lno = 0;
  837.  
  838.     while(*rcp >= '0' && *rcp <= '9')
  839.         lno = lno*10 + *rcp++ - '0';
  840.  
  841.     if(rcp > cp) {
  842.         *expbuf++ = CLNUM;
  843.         *expbuf++ = nlno;
  844.         tlno[nlno++] = lno;
  845.         if(nlno >= NLINES) {
  846.             fprintf(stderr, "Too many line numbers\n");
  847.             exit(2);
  848.         }
  849.         *expbuf++ = CEOF;
  850.         cp = rcp;
  851.         return(expbuf);
  852.     }
  853.     return(0);
  854. }
  855. cmp(a, b)
  856. char    *a,*b;
  857. {
  858.     register char    *ra, *rb;
  859.  
  860.     ra = a - 1;
  861.     rb = b - 1;
  862.  
  863.     while(*++ra == *++rb)
  864.         if(*ra == '\0')    return(0);
  865.     return(1);
  866. }
  867.  
  868. char    *text(textbuf)
  869. char    *textbuf;
  870. {
  871.     register char    *p, *q;
  872.  
  873.     p = textbuf;
  874.     q = cp;
  875.     while(*q == '\t' || *q == ' ')    q++;
  876.     for(;;) {
  877.  
  878.         if((*p = *q++) == '\\')
  879.             *p = *q++;
  880.         if(*p == '\0') {
  881.             cp = --q;
  882.             return(++p);
  883.         }
  884.         if(*p == '\n') {
  885.             while(*q == '\t' || *q == ' ')    q++;
  886.         }
  887.         p++;
  888.     }
  889. }
  890.  
  891.  
  892. struct label    *search(ptr)
  893. struct label    *ptr;
  894. {
  895.     struct label    *rp;
  896.  
  897.     rp = labtab;
  898.     while(rp < ptr) {
  899.         if(cmp(rp->asc, ptr->asc) == 0)
  900.             return(rp);
  901.         rp++;
  902.     }
  903.  
  904.     return(0);
  905. }
  906.  
  907.  
  908. dechain()
  909. {
  910.     struct label    *lptr;
  911.     union reptr    *rptr, *trptr;
  912.  
  913.     for(lptr = labtab; lptr < lab; lptr++) {
  914.  
  915.         if(lptr->address == 0) {
  916.             fprintf(stderr, "Undefined label: %s\n", lptr->asc);
  917.             exit(2);
  918.         }
  919.  
  920.         if(lptr->chain) {
  921.             rptr = lptr->chain;
  922.             while(trptr = rptr->lb1) {
  923.                 rptr->lb1 = lptr->address;
  924.                 rptr = trptr;
  925.             }
  926.             rptr->lb1 = lptr->address;
  927.         }
  928.     }
  929. }
  930.  
  931. char *ycomp(expbuf)
  932. char    *expbuf;
  933. {
  934.     register char    c, *ep, *tsp;
  935.     char    *sp;
  936.  
  937.     ep = expbuf;
  938.     sp = cp;
  939.     for(tsp = cp; *tsp != seof; tsp++) {
  940.         if(*tsp == '\\')
  941.             tsp++;
  942.         if(*tsp == '\n')
  943.             return(badp);
  944.     }
  945.     tsp++;
  946.  
  947.     while((c = *sp++ & 0177) != seof) {
  948.         if(c == '\\' && *sp == 'n') {
  949.             sp++;
  950.             c = '\n';
  951.         }
  952.         if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
  953.             ep[c] = '\n';
  954.             tsp++;
  955.         }
  956.         if(ep[c] == seof || ep[c] == '\0')
  957.             return(badp);
  958.     }
  959.     if(*tsp != seof)
  960.         return(badp);
  961.     cp = ++tsp;
  962.  
  963.     for(c = 0; !(c & 0200); c++)
  964.         if(ep[c] == 0)
  965.             ep[c] = c;
  966.  
  967.     return(ep + 0200);
  968. }
  969.  
  970.