Annotation of researchv8dc/cmd/qed/pattern.c, revision 1.1.1.1

1.1       root        1: /*% cc -c -O %
                      2:  */
                      3: #include "vars.h"
                      4: #define ESIZE  128     /* ESIZE-1 must fit in a signed byte */
                      5: char   expbuf[ESIZE+4];
                      6: int    expgood /*0*/;          /* flag indicating if compiled exp is good */
                      7: #define        CCHR    2
                      8: #define        CDOT    4
                      9: #define        CCL     6
                     10: #define        NCCL    8
                     11: #define CFUNNY 10
                     12: #define        CALT    12
                     13: #define        CBACK   14
                     14: 
                     15: #define        STAR    01
                     16: #define STARABLE CBACK
                     17: 
                     18: #define        CKET    16
                     19: #define        CDOL    17
                     20: #define        CEOF    18
                     21: #define        CBRA    19
                     22: #define CBOI   20
                     23: #define CEOI   21
                     24: #define CSPACE 22
                     25: int    circfl;
                     26: char   pmagic[] = "/.$^*+\\()<|>{}[!_123456789";
                     27: compile(eof)
                     28: char eof;
                     29: {
                     30:        register c;
                     31:        register char *ep, *penultep;
                     32:        char *lastep, *bracketp, bracket[NBRA];
                     33:        int getsvc();
                     34:        int getchar();
                     35:        struct{
                     36:                char    *althd;         /* start of code for < ... > */
                     37:                char    *altlast;       /* start of code for last < or | */
                     38:                char    *bpstart;       /* bracketp at start of < and | */
                     39:                char    *bpend;         /* bracketp at end of > or | */
                     40:                int     nbstart;        /* nbra at start of < and | */
                     41:                int     nbend;          /* nbra at end of > or | */
                     42:                int     firstalt;       /* is this the first alternative? */
                     43:        } *asp, altstk[NBRA];
                     44: 
                     45:        if(eof == '\n')
                     46:                error('x');
                     47:        pmagic[0] = eof;
                     48:        if ((c=nextchar()) == eof || c=='\n') {
                     49:                if (!expgood)
                     50:                        goto cerror;
                     51:                if(c!='\n')
                     52:                        getchar();      /* eat the eof character */
                     53:                return;
                     54:        }
                     55:        expgood = FALSE;
                     56:        ep = expbuf;
                     57:        lastep = 0;
                     58:        bracketp = bracket;
                     59:        nbra = 0;
                     60:        asp = &altstk[-1];
                     61:        startstring();  /* for the saved pattern register */
                     62:        circfl = 0;
                     63:        if (c=='^') {
                     64:                getsvc();       /* save the caret */
                     65:                circfl++;
                     66:        }
                     67:        for (;;) {
                     68:                c = getquote(pmagic, getsvc);
                     69:                if (c==eof || c=='\n') {
                     70:                        if (bracketp!=bracket || asp>=altstk)
                     71:                                goto cerror;
                     72:                        *ep++ = CEOF;
                     73:                        expgood = TRUE;
                     74:                        dropstring();   /* lose the eof character */
                     75:                        setstring(SAVPAT);
                     76:                        if(c=='\n')
                     77:                                ungetchar(c);
                     78:                        return;
                     79:                }
                     80:                if (ep >= &expbuf[ESIZE-5])
                     81:                        goto cerror;
                     82:                penultep = lastep;
                     83:                lastep = ep;
                     84: 
                     85:                if(c != (eof|0200)) switch (c) {
                     86:                case '('|0200:
                     87:                        if (nbra >= NBRA)
                     88:                                goto cerror;
                     89:                        *bracketp++ = nbra;
                     90:                        *ep++ = CBRA;
                     91:                        *ep++ = nbra++;
                     92:                        continue;
                     93:                case ')'|0200:
                     94:                        if (bracketp <= bracket)
                     95:                                goto cerror;
                     96:                        *ep++ = CKET;
                     97:                        *ep++ = *--bracketp;
                     98:                        continue;
                     99:                case '{'|0200:
                    100:                        *ep++ = CBOI;
                    101:                        continue;
                    102:                case '}'|0200:
                    103:                        *ep++ = CEOI;
                    104:                        continue;
                    105:                case '_'|0200:
                    106:                        *ep++ = CSPACE;
                    107:                        continue;
                    108:                case '!'|0200:
                    109:                        *ep++ = CFUNNY;
                    110:                        continue;
                    111:                case '<':
                    112:                        if (++asp >= &altstk[NBRA])
                    113:                                goto cerror;
                    114:                        *ep++ = CALT;
                    115:                        asp->althd = ep;
                    116:                        ep++;
                    117:                        asp->bpstart = bracketp;
                    118:                        asp->nbstart = nbra;
                    119:                        asp->firstalt = TRUE;
                    120:                        asp->altlast = ep++;
                    121:                        lastep = 0;
                    122:                        continue;
                    123:                case '|':
                    124:                        if (asp<altstk)
                    125:                                break;
                    126:                        if (asp->firstalt) {
                    127:                                asp->bpend = bracketp;
                    128:                                asp->nbend = nbra;
                    129:                        }
                    130:                        if (bracketp!=asp->bpend || nbra!=asp->nbend)
                    131:                                goto cerror;
                    132:                        *ep++ = CEOF;
                    133:                        asp->altlast[0] = ep-asp->altlast;
                    134:                        asp->firstalt = FALSE;
                    135:                        bracketp = asp->bpstart;
                    136:                        nbra = asp->nbstart;
                    137:                        asp->altlast = ep++;
                    138:                        lastep = 0;
                    139:                        continue;
                    140:                case '>':
                    141:                        if (asp<altstk)
                    142:                                break;
                    143:                        if (!asp->firstalt &&
                    144:                            (bracketp!=asp->bpend || nbra!=asp->nbend))
                    145:                                goto cerror;
                    146:                        *ep++ = CEOF;
                    147:                        asp->altlast[0] = ep-asp->altlast;
                    148:                        lastep = asp->althd;
                    149:                        *lastep = ep-lastep;
                    150:                        lastep--;
                    151:                        if (bracketp!=asp->bpstart || nbra!=asp->nbstart)
                    152:                                lastep = 0;
                    153:                        asp--;
                    154:                        continue;
                    155:                case '*':
                    156:                case '+':
                    157:                        if (penultep==0){
                    158:                                *ep++ = CCHR;
                    159:                                *ep++ = c;
                    160:                        } else {
                    161:                                if(*penultep>STARABLE)
                    162:                                        goto cerror;
                    163:                                if(c == '+'){
                    164:                                        if((ep-penultep)+ep >= &expbuf[ESIZE-1])
                    165:                                                goto cerror;
                    166:                                        do
                    167:                                                *ep++ = *penultep++;
                    168:                                        while (penultep!=lastep);
                    169:                                }
                    170:                                *penultep |= STAR;
                    171:                                lastep = 0;
                    172:                        }
                    173:                        continue;
                    174:                case '.':
                    175:                        *ep++ = CDOT;
                    176:                        continue;
                    177: 
                    178:                case '[':
                    179:                        penultep = ep;
                    180:                        *ep++ = CCL;
                    181:                        *ep++ = 0;
                    182:                        if ((c=getsvc()) == '^') {
                    183:                                c = getsvc();
                    184:                                ep[-2] = NCCL;
                    185:                        }
                    186:                        do {
                    187:                                if (c == EOF || c == '\n')
                    188:                                        goto cerror;
                    189:                                *ep++ = c;
                    190:                                if ((lastc=getsvc()) == '-') {
                    191:                                        c=getsvc();
                    192:                                        if (c == EOF || c == '\n' || c<=ep[-1])
                    193:                                                goto cerror;
                    194:                                        ep[-1] |= 0200;
                    195:                                        *ep++ = c;
                    196:                                        lastc = getsvc();       /* prime lastc */
                    197:                                } else if (dflag&&'a'<=(c|' ')&&(c|' ')<='z')
                    198:                                        *ep++ = c^' ';
                    199:                                if (ep >= &expbuf[ESIZE-1])
                    200:                                        goto cerror;
                    201:                        } while ((c=lastc) != ']');
                    202:                        penultep[1] = ep-penultep-1;
                    203:                        continue;
                    204: 
                    205: 
                    206:                case '$':
                    207:                        if (nextchar() == eof || peekc=='\n') {
                    208:                                *ep++ = CDOL;
                    209:                                continue;
                    210:                        }
                    211:                        /* fall through */
                    212:                default:
                    213:                        break;
                    214:                }
                    215:                /* if fell through switch, match literal character */
                    216:                /* Goddamned sign extension! */
                    217:                if ((c&0200) && (c&0177)>='1' && (c&0177)<='9') {
                    218:                        *ep++ = CBACK;
                    219:                        *ep++ = c-('1'|0200);
                    220:                        continue;
                    221:                }
                    222:                c &= ~0200;
                    223:                if(dflag && c|' '>='a' && c|' '<='z'){
                    224:                        *ep++ = CCL;
                    225:                        *ep++ = 3;
                    226:                        *ep++ = c;
                    227:                        *ep++ = c^' ';
                    228:                }
                    229:                else{
                    230:                        *ep++ = CCHR;
                    231:                        *ep++ = c;
                    232:                }
                    233:        }
                    234:    cerror:
                    235:        error('p');
                    236: }
                    237: getsvc(){
                    238:        register c;
                    239:        addstring(c=getchar());
                    240:        return(c);
                    241: }
                    242: int
                    243: execute(addr)
                    244:        int *addr;
                    245: {
                    246:        register char *p1, *p2;
                    247: 
                    248:        if (addr==0) {
                    249:                if((p1=loc2) == 0)      /* G command */
                    250:                        p1 = linebuf;
                    251:                else if (circfl)        /* not first search in substitute */
                    252:                        return(FALSE);
                    253:        } else {
                    254:                if (addr==zero)
                    255:                        return(FALSE);
                    256:                p1 = getline(*addr, linebuf);
                    257:        }
                    258:        p2 = expbuf;
                    259:        if (circfl) {
                    260:                loc1 = p1;
                    261:                return(advance(p1, p2));
                    262:        }
                    263:        do {
                    264:                if (*p2 != CCHR  ||  p2[1] == *p1) {
                    265:                        if (advance(p1, p2)) {
                    266:                                loc1 = p1;
                    267:                                return(TRUE);
                    268:                        }
                    269:                }
                    270:        } while (*p1++);
                    271:        return(FALSE);
                    272: }
                    273: 
                    274: int
                    275: advance(lp, ep)
                    276:        register char *lp, *ep;
                    277: {
                    278:        register char *curlp;
                    279:        char *althd, *altend;
                    280: 
                    281:        for (;;) {
                    282:                curlp = lp;
                    283:                switch (*ep++) {
                    284: 
                    285:                case CCHR:
                    286:                        if (*ep++ == *lp++)
                    287:                                continue;
                    288:                        return(FALSE);
                    289: 
                    290:                case CCHR|STAR:
                    291:                        do ; while (*lp++ == *ep);
                    292:                        ep++;
                    293:                        break;
                    294: 
                    295:                case CDOT:
                    296:                        if (*lp++)
                    297:                                continue;
                    298:                        return(FALSE);
                    299: 
                    300:                case CDOT|STAR:
                    301:                        do ; while (*lp++);
                    302:                        break;
                    303: 
                    304:                case CCL:
                    305:                case NCCL:
                    306:                        if (cclass(ep, *lp++, ep[-1]==CCL)) {
                    307:                                ep += *ep;
                    308:                                continue;
                    309:                        }
                    310:                        return(FALSE);
                    311: 
                    312:                case CCL|STAR:
                    313:                case NCCL|STAR:
                    314:                        do ; while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
                    315:                        ep += *ep;
                    316:                        break;
                    317: 
                    318:                case CFUNNY:
                    319:                        if (*lp>=' ' && *lp!='\177' || *lp=='\t' || *lp=='\0')
                    320:                                return(FALSE);
                    321:                        lp++;
                    322:                        continue;
                    323: 
                    324:                case CFUNNY|STAR:
                    325:                        while (*lp<' ' && *lp && *lp!='\t'  ||  *lp=='\177')
                    326:                                lp++;
                    327:                        lp++;
                    328:                        break;
                    329: 
                    330:                case CBACK:
                    331:                        if (braelist[*ep]==0)
                    332:                                error('p');
                    333:                        if (backref(*ep++, lp)) {
                    334:                                lp += braelist[ep[-1]] - braslist[ep[-1]];
                    335:                                continue;
                    336:                        }
                    337:                        return(FALSE);
                    338:        
                    339:                case CBACK|STAR:
                    340:                        if (braelist[*ep] == 0)
                    341:                                error('p');
                    342:                        curlp = lp;
                    343:                        while (backref(*ep, lp))
                    344:                                lp += braelist[*ep] - braslist[*ep];
                    345:                        while (lp >= curlp) {
                    346:                                if (advance(lp, ep+1))
                    347:                                        return(TRUE);
                    348:                                lp -= braelist[*ep] - braslist[*ep];
                    349:                        }
                    350:                        ep++;
                    351:                        continue;
                    352: 
                    353:                case CBRA:
                    354:                        braslist[*ep++] = lp;
                    355:                        continue;
                    356: 
                    357:                case CKET:
                    358:                        braelist[*ep++] = lp;
                    359:                        continue;
                    360: 
                    361:                case CDOL:
                    362:                        if (*lp==0)
                    363:                                continue;
                    364:                        return(FALSE);
                    365: 
                    366:                case CEOF:
                    367:                        loc2 = lp;
                    368:                        return(TRUE);
                    369: 
                    370:                case CBOI:
                    371:                        if (alfmatch(*lp,0)
                    372:                            && (lp==linebuf || !alfmatch(lp[-1],1)))
                    373:                                continue;
                    374:                        return(FALSE);
                    375: 
                    376:                case CEOI:
                    377:                        if (!alfmatch(*lp,1)
                    378:                            && lp!=linebuf && alfmatch(lp[-1],1))
                    379:                                continue;
                    380:                        return(FALSE);
                    381: 
                    382:                case CSPACE:
                    383:                        if (*lp==' ' || *lp=='\t') {
                    384:                                while (*lp == ' ' || *lp=='\t')
                    385:                                        lp++;
                    386:                                continue;
                    387:                                }
                    388:                        return(FALSE);
                    389: 
                    390:                case CALT:
                    391:                        althd = ep-1;
                    392:                        altend = ep + *ep;
                    393:                        for(ep++; ; ep+= *ep) {
                    394:                                if(ep == altend)
                    395:                                        return(FALSE);
                    396:                                if(advance(lp,ep+1) && advance(loc2,altend))
                    397:                                        return(TRUE);
                    398:                        }
                    399: 
                    400:                case CALT|STAR:
                    401:                        althd = ep-1;
                    402:                        altend = ep + *ep;
                    403:                        for(ep++; ep!=altend; ep+= *ep){
                    404:                                if(advance(lp, ep+1)){
                    405:                                        if(loc2 == lp)
                    406:                                                break;
                    407:                                        if(advance(loc2, althd))
                    408:                                                return(TRUE);
                    409:                                }
                    410:                        }
                    411:                        /* return (advance(lp,altend)) */
                    412:                        continue;
                    413: 
                    414:                default:
                    415:                        error('!');
                    416:                }
                    417:                /* star logic: executed by falling out of switch */
                    418:                do {
                    419:                        lp--;
                    420:                        if (advance(lp, ep))
                    421:                                return(TRUE);
                    422:                } while (lp > curlp);
                    423:                return(FALSE);
                    424:        }
                    425: }
                    426: 
                    427: backref(i, lp)
                    428: register i;
                    429: register char *lp;
                    430: {
                    431:        register char *bp;
                    432: 
                    433:        bp = braslist[i];
                    434:        while (*bp++ == *lp++)
                    435:                if (bp >= braelist[i])
                    436:                        return(TRUE);
                    437:        return(FALSE);
                    438: }
                    439: int alfmatch(c,tail)
                    440: register char c;
                    441: {
                    442:        return (('a' <= c && c <= 'z')  ||
                    443:                ('A' <= c && c <= 'Z')  ||
                    444:                (c == '_') ||
                    445:                (tail && '0' <= c && c<= '9'));
                    446: }
                    447: 
                    448: 
                    449: cclass(set, c, f)
                    450:        register char *set;
                    451:        register c;
                    452: {
                    453:        register n;
                    454:        if (c == 0)
                    455:                return(0);
                    456:        n = *set++;
                    457:        while (--n) {
                    458:                if (*set&0200) {
                    459:                        if ((*set++ & 0177) <= c) {
                    460:                                if (c <= *set++)
                    461:                                        return(f);
                    462:                        } else
                    463:                                set++;
                    464:                        --n;
                    465:                } else if (*set++ == c)
                    466:                        return(f);
                    467:        }
                    468:        return(!f);
                    469: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.